Version in base suite: 22.01+dfsg-8+deb12u1 Base version: 7zip_22.01+dfsg-8+deb12u1 Target version: 7zip_22.01+really25.01+dfsg-0+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/7/7zip/7zip_22.01+dfsg-8+deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/7/7zip/7zip_22.01+really25.01+dfsg-0+deb12u1.dsc /srv/release.debian.org/tmp/danBDQ1hk5/7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Icons/zst.ico |binary 7zip-22.01+really25.01+dfsg/Asm/x86/7zAsm.asm | 68 7zip-22.01+really25.01+dfsg/Asm/x86/7zCrcOpt.asm | 352 7zip-22.01+really25.01+dfsg/Asm/x86/LzFindOpt.asm | 31 7zip-22.01+really25.01+dfsg/Asm/x86/LzmaDecOpt.asm | 40 7zip-22.01+really25.01+dfsg/Asm/x86/Sha1Opt.asm | 4 7zip-22.01+really25.01+dfsg/Asm/x86/Sha256Opt.asm | 4 7zip-22.01+really25.01+dfsg/Asm/x86/Sort.asm | 860 ++ 7zip-22.01+really25.01+dfsg/Asm/x86/XzCrc64Opt.asm | 620 + 7zip-22.01+really25.01+dfsg/C/7z.h | 12 7zip-22.01+really25.01+dfsg/C/7zAlloc.c | 69 7zip-22.01+really25.01+dfsg/C/7zAlloc.h | 6 7zip-22.01+really25.01+dfsg/C/7zArcIn.c | 409 - 7zip-22.01+really25.01+dfsg/C/7zBuf.h | 6 7zip-22.01+really25.01+dfsg/C/7zCrc.c | 528 - 7zip-22.01+really25.01+dfsg/C/7zCrc.h | 15 7zip-22.01+really25.01+dfsg/C/7zCrcOpt.c | 244 7zip-22.01+really25.01+dfsg/C/7zDec.c | 201 7zip-22.01+really25.01+dfsg/C/7zFile.c | 33 7zip-22.01+really25.01+dfsg/C/7zFile.h | 9 7zip-22.01+really25.01+dfsg/C/7zStream.c | 67 7zip-22.01+really25.01+dfsg/C/7zTypes.h | 262 7zip-22.01+really25.01+dfsg/C/7zVersion.h | 10 7zip-22.01+really25.01+dfsg/C/7zWindows.h | 101 7zip-22.01+really25.01+dfsg/C/7zip_gcc_c.mak | 77 7zip-22.01+really25.01+dfsg/C/Aes.c | 162 7zip-22.01+really25.01+dfsg/C/Aes.h | 38 7zip-22.01+really25.01+dfsg/C/AesOpt.c | 704 + 7zip-22.01+really25.01+dfsg/C/Alloc.c | 330 7zip-22.01+really25.01+dfsg/C/Alloc.h | 32 7zip-22.01+really25.01+dfsg/C/Asm_c.mak | 12 7zip-22.01+really25.01+dfsg/C/Bcj2.c | 319 7zip-22.01+really25.01+dfsg/C/Bcj2.h | 270 7zip-22.01+really25.01+dfsg/C/Bcj2Enc.c | 557 - 7zip-22.01+really25.01+dfsg/C/Blake2.h | 119 7zip-22.01+really25.01+dfsg/C/Blake2s.c | 2726 ++++++ 7zip-22.01+really25.01+dfsg/C/Bra.c | 765 + 7zip-22.01+really25.01+dfsg/C/Bra.h | 125 7zip-22.01+really25.01+dfsg/C/Bra86.c | 221 7zip-22.01+really25.01+dfsg/C/BraIA64.c | 57 7zip-22.01+really25.01+dfsg/C/BwtSort.c | 471 - 7zip-22.01+really25.01+dfsg/C/BwtSort.h | 11 7zip-22.01+really25.01+dfsg/C/Compiler.h | 247 7zip-22.01+really25.01+dfsg/C/CpuArch.c | 952 +- 7zip-22.01+really25.01+dfsg/C/CpuArch.h | 393 7zip-22.01+really25.01+dfsg/C/Delta.h | 6 7zip-22.01+really25.01+dfsg/C/DllSecur.c | 117 7zip-22.01+really25.01+dfsg/C/DllSecur.h | 6 7zip-22.01+really25.01+dfsg/C/HuffEnc.c | 392 7zip-22.01+really25.01+dfsg/C/HuffEnc.h | 12 7zip-22.01+really25.01+dfsg/C/LzFind.c | 648 - 7zip-22.01+really25.01+dfsg/C/LzFind.h | 56 7zip-22.01+really25.01+dfsg/C/LzFindMt.c | 130 7zip-22.01+really25.01+dfsg/C/LzFindMt.h | 19 7zip-22.01+really25.01+dfsg/C/LzFindOpt.c | 14 7zip-22.01+really25.01+dfsg/C/LzHash.h | 8 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.c | 16 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.h | 15 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.c | 155 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.h | 20 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.c | 176 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.h | 21 7zip-22.01+really25.01+dfsg/C/Lzma86.h | 6 7zip-22.01+really25.01+dfsg/C/Lzma86Dec.c | 7 7zip-22.01+really25.01+dfsg/C/Lzma86Enc.c | 7 7zip-22.01+really25.01+dfsg/C/LzmaDec.c | 190 7zip-22.01+really25.01+dfsg/C/LzmaDec.h | 17 7zip-22.01+really25.01+dfsg/C/LzmaEnc.c | 416 - 7zip-22.01+really25.01+dfsg/C/LzmaEnc.h | 25 7zip-22.01+really25.01+dfsg/C/LzmaLib.c | 8 7zip-22.01+really25.01+dfsg/C/LzmaLib.h | 12 7zip-22.01+really25.01+dfsg/C/Md5.c | 206 7zip-22.01+really25.01+dfsg/C/Md5.h | 34 7zip-22.01+really25.01+dfsg/C/MtCoder.c | 161 7zip-22.01+really25.01+dfsg/C/MtCoder.h | 53 7zip-22.01+really25.01+dfsg/C/MtDec.c | 117 7zip-22.01+really25.01+dfsg/C/MtDec.h | 34 7zip-22.01+really25.01+dfsg/C/Ppmd.h | 12 7zip-22.01+really25.01+dfsg/C/Ppmd7.c | 217 7zip-22.01+really25.01+dfsg/C/Ppmd7.h | 10 7zip-22.01+really25.01+dfsg/C/Ppmd7Dec.c | 79 7zip-22.01+really25.01+dfsg/C/Ppmd7Enc.c | 102 7zip-22.01+really25.01+dfsg/C/Ppmd7aDec.c | 76 7zip-22.01+really25.01+dfsg/C/Ppmd8.c | 279 7zip-22.01+really25.01+dfsg/C/Ppmd8.h | 10 7zip-22.01+really25.01+dfsg/C/Ppmd8Dec.c | 78 7zip-22.01+really25.01+dfsg/C/Ppmd8Enc.c | 101 7zip-22.01+really25.01+dfsg/C/Precomp.h | 127 7zip-22.01+really25.01+dfsg/C/RotateDefs.h | 28 7zip-22.01+really25.01+dfsg/C/Sha1.c | 316 7zip-22.01+really25.01+dfsg/C/Sha1.h | 28 7zip-22.01+really25.01+dfsg/C/Sha1Opt.c | 369 7zip-22.01+really25.01+dfsg/C/Sha256.c | 328 7zip-22.01+really25.01+dfsg/C/Sha256.h | 26 7zip-22.01+really25.01+dfsg/C/Sha256Opt.c | 354 7zip-22.01+really25.01+dfsg/C/Sha3.c | 359 7zip-22.01+really25.01+dfsg/C/Sha3.h | 36 7zip-22.01+really25.01+dfsg/C/Sha512.c | 711 + 7zip-22.01+really25.01+dfsg/C/Sha512.h | 86 7zip-22.01+really25.01+dfsg/C/Sha512Opt.c | 395 7zip-22.01+really25.01+dfsg/C/Sort.c | 355 7zip-22.01+really25.01+dfsg/C/Sort.h | 11 7zip-22.01+really25.01+dfsg/C/SwapBytes.c | 835 ++ 7zip-22.01+really25.01+dfsg/C/SwapBytes.h | 17 7zip-22.01+really25.01+dfsg/C/Threads.c | 362 7zip-22.01+really25.01+dfsg/C/Threads.h | 78 7zip-22.01+really25.01+dfsg/C/Util/7z/7z.dsp | 12 7zip-22.01+really25.01+dfsg/C/Util/7z/7zMain.c | 118 7zip-22.01+really25.01+dfsg/C/Util/7z/Precomp.h | 17 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile | 10 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile.gcc | 4 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.c | 137 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.dsp | 8 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/Precomp.h | 16 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/makefile | 23 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/resource.rc | 5 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.c | 185 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.dsp | 8 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/Precomp.h | 16 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/makefile | 4 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/resource.rc | 5 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.c | 145 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.dsp | 20 7zip-22.01+really25.01+dfsg/C/Util/Lzma/Precomp.h | 13 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLib.dsp | 28 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLibExports.c | 13 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.c | 4 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.h | 13 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/makefile | 29 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/Precomp.h | 17 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/SfxSetup.c | 61 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile | 11 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile_con | 4 7zip-22.01+really25.01+dfsg/C/Xxh64.c | 327 7zip-22.01+really25.01+dfsg/C/Xxh64.h | 50 7zip-22.01+really25.01+dfsg/C/Xz.c | 6 7zip-22.01+really25.01+dfsg/C/Xz.h | 71 7zip-22.01+really25.01+dfsg/C/XzCrc64.c | 138 7zip-22.01+really25.01+dfsg/C/XzCrc64.h | 16 7zip-22.01+really25.01+dfsg/C/XzCrc64Opt.c | 266 7zip-22.01+really25.01+dfsg/C/XzDec.c | 393 7zip-22.01+really25.01+dfsg/C/XzEnc.c | 316 7zip-22.01+really25.01+dfsg/C/XzEnc.h | 24 7zip-22.01+really25.01+dfsg/C/XzIn.c | 320 7zip-22.01+really25.01+dfsg/C/ZstdDec.c | 4067 ++++++++++ 7zip-22.01+really25.01+dfsg/C/ZstdDec.h | 173 7zip-22.01+really25.01+dfsg/C/var_clang_arm64.mak | 1 7zip-22.01+really25.01+dfsg/C/warn_clang.mak | 38 7zip-22.01+really25.01+dfsg/C/warn_clang_mac.mak | 38 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip.mak | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip_gcc.mak | 161 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7z.dsp | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zCompressionMode.h | 31 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.cpp | 176 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.h | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.cpp | 312 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.h | 43 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zExtract.cpp | 124 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.cpp | 116 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.h | 63 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.cpp | 159 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.h | 101 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandlerOut.cpp | 266 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.cpp | 308 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.h | 47 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zItem.h | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.cpp | 399 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.h | 91 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.cpp | 132 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.cpp | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.h | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.cpp | 1177 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.h | 44 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/makefile | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApfsHandler.cpp | 1145 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApmHandler.cpp | 309 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArHandler.cpp | 216 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive.def | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive2.def | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArchiveExports.cpp | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArjHandler.cpp | 300 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/AvbHandler.cpp | 596 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Base64Handler.cpp | 97 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Bz2Handler.cpp | 188 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.cpp | 132 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.h | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.cpp | 356 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHeader.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.cpp | 89 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabItem.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.cpp | 286 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.cpp | 123 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ComHandler.cpp | 206 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.cpp | 106 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.h | 108 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.cpp | 48 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.cpp | 36 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.h | 43 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.cpp | 29 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.h | 43 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.cpp | 35 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.cpp | 52 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.h | 49 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.h | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ParseProperties.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CpioHandler.cpp | 943 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CramfsHandler.cpp | 117 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DeflateProps.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports2.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DmgHandler.cpp | 1969 +++- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ElfHandler.cpp | 535 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ExtHandler.cpp | 511 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FatHandler.cpp | 950 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FlvHandler.cpp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GptHandler.cpp | 239 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GzHandler.cpp | 271 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.cpp | 140 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.h | 108 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.cpp | 687 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IArchive.h | 411 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IhexHandler.cpp | 210 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.cpp | 105 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.h | 17 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHeader.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.cpp | 94 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.h | 55 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoItem.h | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LpHandler.cpp | 125 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LvmHandler.cpp | 1107 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzhHandler.cpp | 224 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzmaHandler.cpp | 184 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MachoHandler.cpp | 234 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MbrHandler.cpp | 324 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MslzHandler.cpp | 82 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MubHandler.cpp | 93 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.cpp | 38 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.cpp | 139 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.cpp | 368 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.h | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/NtfsHandler.cpp | 481 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PeHandler.cpp | 737 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PpmdHandler.cpp | 78 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/QcowHandler.cpp | 472 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.cpp | 1654 ++-- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.h | 200 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.cpp | 144 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.h | 31 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHeader.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarItem.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarVol.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/RpmHandler.cpp | 121 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SparseHandler.cpp | 80 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SplitHandler.cpp | 89 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SquashfsHandler.cpp | 436 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SwfHandler.cpp | 230 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.cpp | 230 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.h | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 42 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.cpp | 114 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarItem.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.cpp | 50 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.cpp | 130 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.cpp | 107 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.cpp | 154 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.h | 29 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/UefiHandler.cpp | 298 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VdiHandler.cpp | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdHandler.cpp | 158 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdxHandler.cpp | 169 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VmdkHandler.cpp | 149 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.cpp | 153 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.h | 52 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandlerOut.cpp | 507 - 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.cpp | 289 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.h | 34 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XarHandler.cpp | 1173 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.cpp | 336 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZHandler.cpp | 93 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.cpp | 194 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.h | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipCompressionMode.h | 28 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.cpp | 402 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.h | 52 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp | 91 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHeader.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.cpp | 379 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.h | 34 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.cpp | 57 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.cpp | 1009 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.h | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZstdHandler.cpp | 1147 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Asm.mak | 9 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/Alone.dsp | 184 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/afxres.h | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile | 23 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile.gcc | 73 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile.gcc | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/Alone.dsp | 139 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile.gcc | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/FM.dsp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/StdAfx.h | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/makefile | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/makefile | 9 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/makefile | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/makefile | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc.mak | 19 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Format7z.dsp | 206 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile.gcc | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/resource.rc | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/makefile | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp | 67 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp | 86 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile.gcc | 24 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SFXCon.dsp | 104 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SfxCon.cpp | 44 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile.gcc | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/resource.rc | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp | 28 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp | 79 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp | 77 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/StdAfx.h | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/makefile | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SFXWin.dsp | 73 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SfxWin.cpp | 57 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/StdAfx.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/makefile | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/resource.rc | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.cpp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.cpp | 115 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.h | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.cpp | 248 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.h | 138 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.cpp | 367 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.h | 152 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.cpp | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.h | 28 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.cpp | 304 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.h | 59 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.cpp | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.h | 116 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LockedStream.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodId.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.cpp | 107 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.cpp | 855 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.h | 160 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.cpp | 24 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.h | 81 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.h | 29 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.cpp | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.h | 19 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.h | 24 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/PropId.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterArc.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterCodec.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.cpp | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.cpp | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.h | 84 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.cpp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/UniqBlocks.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.cpp | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Const.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.cpp | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.cpp | 206 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.h | 108 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.cpp | 755 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.h | 198 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Register.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.cpp | 909 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.h | 125 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Register.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.cpp | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.h | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjRegister.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.cpp | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.h | 87 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlEncoder.h | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmDecoder.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmEncoder.h | 65 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.cpp | 93 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.h | 60 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchRegister.cpp | 49 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ByteSwap.cpp | 105 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Codec.def | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CodecExports.cpp | 69 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.cpp | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.h | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Deflate64Register.cpp | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateConst.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.cpp | 175 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.h | 83 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.cpp | 169 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateRegister.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeltaFilter.cpp | 54 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DllExports2Compress.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/HuffmanDecoder.h | 593 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.cpp | 86 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.h | 38 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeHuffmanDecoder.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.cpp | 107 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.h | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.cpp | 116 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.h | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.cpp | 58 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.h | 99 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.cpp | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.h | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Register.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.cpp | 54 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.h | 102 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.cpp | 59 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.h | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.cpp | 131 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.h | 78 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzx.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.cpp | 1586 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.h | 256 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Mtf8.h | 49 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.cpp | 47 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.h | 66 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.h | 24 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.cpp | 67 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.h | 51 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.cpp | 372 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.h | 153 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.h | 26 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.cpp | 388 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.h | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.cpp | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.h | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.cpp | 30 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.h | 29 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.cpp | 72 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.cpp | 119 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.h | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.h | 26 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.cpp | 437 + 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.h | 98 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc.mak | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc64.mak | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.cpp | 48 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.h | 41 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAesRegister.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.cpp | 288 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.h | 113 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAesReg.cpp | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.cpp | 38 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.h | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.cpp | 129 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.h | 69 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.h | 23 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Sha1Cls.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.cpp | 31 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.h | 37 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.cpp | 86 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.h | 36 7zip-22.01+really25.01+dfsg/CPP/7zip/GuiCommon.rc | 41 7zip-22.01+really25.01+dfsg/CPP/7zip/Guid.txt | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/ICoder.h | 431 - 7zip-22.01+really25.01+dfsg/CPP/7zip/IDecl.h | 62 7zip-22.01+really25.01+dfsg/CPP/7zip/IPassword.h | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/IProgress.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/IStream.h | 187 7zip-22.01+really25.01+dfsg/CPP/7zip/LzmaDec.mak | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/MyVersionInfo.rc | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/PropID.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/Sort.mak | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.cpp | 248 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.h | 220 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentOut.cpp | 197 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.cpp | 113 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolder.cpp | 17 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp | 129 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 131 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/IFolderArchive.h | 139 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.cpp | 189 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.dsp | 98 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile.gcc | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 255 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.h | 36 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 1684 ++-- 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.h | 420 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.cpp | 233 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 272 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.h | 199 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.cpp | 1429 ++- 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.h | 23 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.cpp | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall2.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DefaultName.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DirItem.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.cpp | 191 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExitCode.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.cpp | 82 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractMode.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.cpp | 667 + 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.h | 122 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/IFileExtractCallback.h | 92 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.cpp | 324 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.h | 136 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.cpp | 468 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.h | 45 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.cpp | 146 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Property.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.cpp | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SortUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.cpp | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.cpp | 675 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.h | 98 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateAction.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.cpp | 320 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.h | 175 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.h | 9 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.cpp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.cpp | 61 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.cpp | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.dsp | 48 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.mak | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.manifest | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp | 167 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.h | 109 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.h | 17 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.cpp | 207 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Main.cpp | 289 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/MainAr.cpp | 58 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.cpp | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.h | 25 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 149 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.h | 64 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile | 5 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile.gcc | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.cpp | 884 +- 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.h | 126 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenuFlags.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/Explorer.dsp | 61 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyExplorerCommand.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp | 43 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/StdAfx.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/makefile | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource.h | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource2.rc | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.cpp | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.h | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.cpp | 266 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.dsp | 52 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarPlugin.h | 51 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.cpp | 59 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.h | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Messages.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.cpp | 115 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginDelete.cpp | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginRead.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginWrite.cpp | 54 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.cpp | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.cpp | 136 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.h | 62 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/makefile | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/7zFM.exe.manifest | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.cpp | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp | 319 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.h | 58 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.cpp | 82 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.h | 150 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AppState.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.cpp | 489 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.h | 19 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog2.cpp | 1834 ++++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog2.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog2.rc | 32 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog2Res.h | 9 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ComboDialog.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ComboDialog.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/CopyDialog.cpp | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/CopyDialog.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/DialogSize.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EditDialog.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EditDialog.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EditPage.cpp | 30 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EditPage.h | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EditPage.rc | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp | 41 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/EnumFormatEtc.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ExtractCallback.cpp | 577 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ExtractCallback.h | 412 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FM.cpp | 244 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FM.dsp | 64 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FM.mak | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FSDrives.cpp | 188 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FSDrives.h | 23 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FSFolder.cpp | 282 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FSFolder.h | 110 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FSFolderCopy.cpp | 343 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp | 71 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FilePlugins.cpp | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FilePlugins.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FoldersPage.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FoldersPage.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FoldersPage.rc | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FoldersPage2.rc | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/FormatUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/HelpUtils.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/HelpUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/IFolder.h | 301 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangPage.cpp | 273 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangPage.h | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangPage.rc | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangPageRes.h | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangUtils.cpp | 102 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LangUtils.h | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LinkDialog.cpp | 69 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/LinkDialog.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ListViewDialog.cpp | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ListViewDialog.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MemDialog.cpp | 218 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MemDialog.h | 48 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MemDialog.rc | 49 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MemDialogRes.h | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MenuPage.cpp | 30 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MenuPage.h | 22 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MenuPage.rc | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MenuPage2.rc | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MessagesDialog.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MessagesDialog.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MyCom2.h | 52 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MyLoadMenu.cpp | 412 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MyLoadMenu.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/MyWindowsNew.h | 53 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/NetFolder.cpp | 79 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/NetFolder.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OpenCallback.cpp | 83 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OpenCallback.h | 69 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OptionsDialog.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OverwriteDialog.cpp | 246 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OverwriteDialog.h | 62 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OverwriteDialog.rc | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/OverwriteDialogRes.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/Panel.cpp | 237 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/Panel.h | 503 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelCopy.cpp | 146 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelCrc.cpp | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelDrag.cpp | 2820 +++++- 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelFolderChange.cpp | 445 - 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 357 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelItems.cpp | 343 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelKey.cpp | 34 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelListNotify.cpp | 172 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelMenu.cpp | 297 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelOperations.cpp | 81 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelSelect.cpp | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelSort.cpp | 28 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PanelSplitFile.cpp | 72 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PasswordDialog.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PasswordDialog.h | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PasswordDialog.rc | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PluginInterface.h | 45 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PluginLoader.h | 15 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ProgramLocation.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ProgressDialog.cpp | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ProgressDialog.h | 33 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 245 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ProgressDialog2.h | 102 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PropertyName.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PropertyName.rc | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/PropertyNameRes.h | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryAssociations.cpp | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryAssociations.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryPlugins.cpp | 168 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryPlugins.h | 27 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryUtils.cpp | 13 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RegistryUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RootFolder.cpp | 88 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/RootFolder.h | 19 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SettingsPage.cpp | 135 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SettingsPage.h | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SettingsPage.rc | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SettingsPage2.rc | 36 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SettingsPageRes.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SplitDialog.cpp | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SplitDialog.h | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SplitUtils.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SplitUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/StdAfx.h | 72 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/StringUtils.cpp | 26 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/StringUtils.h | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SysIconUtils.cpp | 278 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SysIconUtils.h | 41 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SystemPage.cpp | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SystemPage.h | 16 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/SystemPage.rc | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/TextPairs.cpp | 20 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/TextPairs.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/UpdateCallback100.cpp | 59 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/UpdateCallback100.h | 33 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/VerCtrl.cpp | 18 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ViewSettings.cpp | 76 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/ViewSettings.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/makefile | 7 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/resource.h | 19 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/resource.rc | 84 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/resourceGui.h | 10 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/resourceGui.rc | 11 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/7zG.exe.manifest | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/BenchmarkDialog.cpp | 239 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/BenchmarkDialog.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/BenchmarkDialog.rc | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/CompressDialog.cpp | 1085 ++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/CompressDialog.h | 78 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/CompressDialog.rc | 14 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/CompressDialogRes.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/CompressOptionsDialog.rc | 69 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/ExtractDialog.cpp | 62 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/ExtractDialog.h | 30 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/ExtractGUI.cpp | 45 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/ExtractGUI.h | 6 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/GUI.cpp | 84 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/GUI.dsp | 60 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/HashGUI.cpp | 58 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/HashGUI.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/StdAfx.h | 21 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 25 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateCallbackGUI.h | 23 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp | 75 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h | 36 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateGUI.cpp | 38 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/UpdateGUI.h | 4 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/makefile | 12 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/GUI/resource.rc | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/cmpl_gcc_arm.mak | 3 7zip-22.01+really25.01+dfsg/CPP/7zip/var_clang_arm64.mak | 8 7zip-22.01+really25.01+dfsg/CPP/7zip/var_clang_x64.mak | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/var_clang_x86.mak | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/var_gcc_arm.mak | 34 7zip-22.01+really25.01+dfsg/CPP/7zip/var_gcc_x64.mak | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/var_gcc_x86.mak | 1 7zip-22.01+really25.01+dfsg/CPP/7zip/var_mac_arm64.mak | 2 7zip-22.01+really25.01+dfsg/CPP/7zip/warn_clang.mak | 40 7zip-22.01+really25.01+dfsg/CPP/7zip/warn_clang_mac.mak | 46 7zip-22.01+really25.01+dfsg/CPP/7zip/warn_gcc.mak | 56 7zip-22.01+really25.01+dfsg/CPP/Build.mak | 116 7zip-22.01+really25.01+dfsg/CPP/Common/AutoPtr.h | 39 7zip-22.01+really25.01+dfsg/CPP/Common/C_FileIO.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/CksumReg.cpp | 23 7zip-22.01+really25.01+dfsg/CPP/Common/ComTry.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/CommandLineParser.cpp | 40 7zip-22.01+really25.01+dfsg/CPP/Common/CommandLineParser.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/Common.h | 57 7zip-22.01+really25.01+dfsg/CPP/Common/Common0.h | 330 7zip-22.01+really25.01+dfsg/CPP/Common/CrcReg.cpp | 60 7zip-22.01+really25.01+dfsg/CPP/Common/Defs.h | 6 7zip-22.01+really25.01+dfsg/CPP/Common/DynLimBuf.cpp | 2 7zip-22.01+really25.01+dfsg/CPP/Common/DynLimBuf.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/DynamicBuffer.h | 20 7zip-22.01+really25.01+dfsg/CPP/Common/IntToString.cpp | 245 7zip-22.01+really25.01+dfsg/CPP/Common/IntToString.h | 34 7zip-22.01+really25.01+dfsg/CPP/Common/Lang.cpp | 70 7zip-22.01+really25.01+dfsg/CPP/Common/Lang.h | 17 7zip-22.01+really25.01+dfsg/CPP/Common/ListFileUtils.cpp | 18 7zip-22.01+really25.01+dfsg/CPP/Common/ListFileUtils.h | 8 7zip-22.01+really25.01+dfsg/CPP/Common/Md5Reg.cpp | 44 7zip-22.01+really25.01+dfsg/CPP/Common/MyBuffer.h | 68 7zip-22.01+really25.01+dfsg/CPP/Common/MyBuffer2.h | 68 7zip-22.01+really25.01+dfsg/CPP/Common/MyCom.h | 556 + 7zip-22.01+really25.01+dfsg/CPP/Common/MyException.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/MyGuidDef.h | 24 7zip-22.01+really25.01+dfsg/CPP/Common/MyInitGuid.h | 26 7zip-22.01+really25.01+dfsg/CPP/Common/MyLinux.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/MyMap.cpp | 12 7zip-22.01+really25.01+dfsg/CPP/Common/MyMap.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/MyString.cpp | 237 7zip-22.01+really25.01+dfsg/CPP/Common/MyString.h | 122 7zip-22.01+really25.01+dfsg/CPP/Common/MyTypes.h | 24 7zip-22.01+really25.01+dfsg/CPP/Common/MyUnknown.h | 13 7zip-22.01+really25.01+dfsg/CPP/Common/MyVector.h | 55 7zip-22.01+really25.01+dfsg/CPP/Common/MyWindows.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/Common/MyWindows.h | 133 7zip-22.01+really25.01+dfsg/CPP/Common/MyXml.cpp | 143 7zip-22.01+really25.01+dfsg/CPP/Common/MyXml.h | 8 7zip-22.01+really25.01+dfsg/CPP/Common/NewHandler.cpp | 226 7zip-22.01+really25.01+dfsg/CPP/Common/NewHandler.h | 43 7zip-22.01+really25.01+dfsg/CPP/Common/Random.cpp | 4 7zip-22.01+really25.01+dfsg/CPP/Common/Random.h | 6 7zip-22.01+really25.01+dfsg/CPP/Common/Sha1Reg.cpp | 29 7zip-22.01+really25.01+dfsg/CPP/Common/Sha256Reg.cpp | 29 7zip-22.01+really25.01+dfsg/CPP/Common/Sha3Reg.cpp | 76 7zip-22.01+really25.01+dfsg/CPP/Common/Sha512Prepare.cpp | 7 7zip-22.01+really25.01+dfsg/CPP/Common/Sha512Reg.cpp | 83 7zip-22.01+really25.01+dfsg/CPP/Common/StdAfx.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/StdInStream.cpp | 17 7zip-22.01+really25.01+dfsg/CPP/Common/StdInStream.h | 12 7zip-22.01+really25.01+dfsg/CPP/Common/StdOutStream.cpp | 128 7zip-22.01+really25.01+dfsg/CPP/Common/StdOutStream.h | 31 7zip-22.01+really25.01+dfsg/CPP/Common/StringConvert.cpp | 55 7zip-22.01+really25.01+dfsg/CPP/Common/StringConvert.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/StringToInt.cpp | 229 7zip-22.01+really25.01+dfsg/CPP/Common/StringToInt.h | 20 7zip-22.01+really25.01+dfsg/CPP/Common/TextConfig.cpp | 21 7zip-22.01+really25.01+dfsg/CPP/Common/TextConfig.h | 4 7zip-22.01+really25.01+dfsg/CPP/Common/UTFConvert.cpp | 202 7zip-22.01+really25.01+dfsg/CPP/Common/UTFConvert.h | 64 7zip-22.01+really25.01+dfsg/CPP/Common/Wildcard.cpp | 27 7zip-22.01+really25.01+dfsg/CPP/Common/Wildcard.h | 6 7zip-22.01+really25.01+dfsg/CPP/Common/Xxh64Reg.cpp | 97 7zip-22.01+really25.01+dfsg/CPP/Common/XzCrc64Reg.cpp | 25 7zip-22.01+really25.01+dfsg/CPP/Windows/COM.h | 32 7zip-22.01+really25.01+dfsg/CPP/Windows/Clipboard.h | 6 7zip-22.01+really25.01+dfsg/CPP/Windows/CommonDialog.cpp | 297 7zip-22.01+really25.01+dfsg/CPP/Windows/CommonDialog.h | 44 7zip-22.01+really25.01+dfsg/CPP/Windows/Console.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ComboBox.cpp | 8 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ComboBox.h | 22 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/CommandBar.h | 12 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Dialog.cpp | 52 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Dialog.h | 135 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Edit.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ImageList.h | 6 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ListView.cpp | 47 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ListView.h | 51 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ProgressBar.h | 24 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/PropertyPage.cpp | 90 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/PropertyPage.h | 20 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ReBar.h | 6 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Static.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/StatusBar.h | 10 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/ToolBar.h | 6 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Trackbar.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Window2.cpp | 14 7zip-22.01+really25.01+dfsg/CPP/Windows/Control/Window2.h | 16 7zip-22.01+really25.01+dfsg/CPP/Windows/DLL.cpp | 57 7zip-22.01+really25.01+dfsg/CPP/Windows/DLL.h | 49 7zip-22.01+really25.01+dfsg/CPP/Windows/Defs.h | 5 7zip-22.01+really25.01+dfsg/CPP/Windows/ErrorMsg.cpp | 8 7zip-22.01+really25.01+dfsg/CPP/Windows/ErrorMsg.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/FileDir.cpp | 464 - 7zip-22.01+really25.01+dfsg/CPP/Windows/FileDir.h | 47 7zip-22.01+really25.01+dfsg/CPP/Windows/FileFind.cpp | 220 7zip-22.01+really25.01+dfsg/CPP/Windows/FileFind.h | 33 7zip-22.01+really25.01+dfsg/CPP/Windows/FileIO.cpp | 159 7zip-22.01+really25.01+dfsg/CPP/Windows/FileIO.h | 162 7zip-22.01+really25.01+dfsg/CPP/Windows/FileLink.cpp | 326 7zip-22.01+really25.01+dfsg/CPP/Windows/FileMapping.h | 6 7zip-22.01+really25.01+dfsg/CPP/Windows/FileName.cpp | 252 7zip-22.01+really25.01+dfsg/CPP/Windows/FileName.h | 49 7zip-22.01+really25.01+dfsg/CPP/Windows/FileSystem.cpp | 72 7zip-22.01+really25.01+dfsg/CPP/Windows/FileSystem.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Handle.h | 8 7zip-22.01+really25.01+dfsg/CPP/Windows/MemoryGlobal.h | 12 7zip-22.01+really25.01+dfsg/CPP/Windows/MemoryLock.cpp | 31 7zip-22.01+really25.01+dfsg/CPP/Windows/MemoryLock.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Menu.cpp | 159 7zip-22.01+really25.01+dfsg/CPP/Windows/Menu.h | 52 7zip-22.01+really25.01+dfsg/CPP/Windows/NationalTime.cpp | 8 7zip-22.01+really25.01+dfsg/CPP/Windows/NationalTime.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Net.cpp | 56 7zip-22.01+really25.01+dfsg/CPP/Windows/Net.h | 5 7zip-22.01+really25.01+dfsg/CPP/Windows/NtCheck.h | 14 7zip-22.01+really25.01+dfsg/CPP/Windows/ProcessMessages.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/ProcessUtils.cpp | 24 7zip-22.01+really25.01+dfsg/CPP/Windows/ProcessUtils.h | 54 7zip-22.01+really25.01+dfsg/CPP/Windows/PropVariant.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/Windows/PropVariant.h | 10 7zip-22.01+really25.01+dfsg/CPP/Windows/PropVariantConv.cpp | 112 7zip-22.01+really25.01+dfsg/CPP/Windows/PropVariantConv.h | 13 7zip-22.01+really25.01+dfsg/CPP/Windows/PropVariantUtils.h | 12 7zip-22.01+really25.01+dfsg/CPP/Windows/Registry.cpp | 300 7zip-22.01+really25.01+dfsg/CPP/Windows/Registry.h | 52 7zip-22.01+really25.01+dfsg/CPP/Windows/ResourceString.h | 5 7zip-22.01+really25.01+dfsg/CPP/Windows/SecurityUtils.cpp | 38 7zip-22.01+really25.01+dfsg/CPP/Windows/SecurityUtils.h | 14 7zip-22.01+really25.01+dfsg/CPP/Windows/Shell.cpp | 592 + 7zip-22.01+really25.01+dfsg/CPP/Windows/Shell.h | 61 7zip-22.01+really25.01+dfsg/CPP/Windows/StdAfx.h | 7 7zip-22.01+really25.01+dfsg/CPP/Windows/Synchronization.cpp | 24 7zip-22.01+really25.01+dfsg/CPP/Windows/Synchronization.h | 55 7zip-22.01+really25.01+dfsg/CPP/Windows/System.cpp | 291 7zip-22.01+really25.01+dfsg/CPP/Windows/System.h | 82 7zip-22.01+really25.01+dfsg/CPP/Windows/SystemInfo.cpp | 700 + 7zip-22.01+really25.01+dfsg/CPP/Windows/SystemInfo.h | 7 7zip-22.01+really25.01+dfsg/CPP/Windows/Thread.h | 14 7zip-22.01+really25.01+dfsg/CPP/Windows/TimeUtils.cpp | 95 7zip-22.01+really25.01+dfsg/CPP/Windows/TimeUtils.h | 4 7zip-22.01+really25.01+dfsg/CPP/Windows/Window.cpp | 10 7zip-22.01+really25.01+dfsg/CPP/Windows/Window.h | 113 7zip-22.01+really25.01+dfsg/DOC/7zip.hhp | 1 7zip-22.01+really25.01+dfsg/DOC/7zip.wxs | 2 7zip-22.01+really25.01+dfsg/DOC/License.txt | 145 7zip-22.01+really25.01+dfsg/DOC/Methods.txt | 8 7zip-22.01+really25.01+dfsg/DOC/lzma.txt | 43 7zip-22.01+really25.01+dfsg/DOC/readme.txt | 87 7zip-22.01+really25.01+dfsg/DOC/src-history.txt | 139 7zip-22.01+really25.01+dfsg/debian/changelog | 29 7zip-22.01+really25.01+dfsg/debian/gbp.conf | 3 7zip-22.01+really25.01+dfsg/debian/patches/0001-Accept-Debian-build-flags.patch | 50 7zip-22.01+really25.01+dfsg/debian/patches/0002-Use-GCC-10-warning-options.patch | 22 7zip-22.01+really25.01+dfsg/debian/patches/0002-Use-getcwd-3-POSIX-extension-to-avoid-PATH_MAX-macro.patch | 39 7zip-22.01+really25.01+dfsg/debian/patches/0003-Disable-hardware-acceleration-support-on-armel.patch | 159 7zip-22.01+really25.01+dfsg/debian/patches/0003-Disable-local-echo-display-when-in-input-passwords-C.patch | 88 7zip-22.01+really25.01+dfsg/debian/patches/0004-Guard-ARM-v8-feature-from-old-architecture.patch | 25 7zip-22.01+really25.01+dfsg/debian/patches/0005-Add-note-for-unexpected-recursive-operations-behavio.patch | 25 7zip-22.01+really25.01+dfsg/debian/patches/0005-Use-getcwd-3-POSIX-extension-to-avoid-PATH_MAX-macro.patch | 39 7zip-22.01+really25.01+dfsg/debian/patches/0006-Disable-local-echo-display-when-in-input-passwords-C.patch | 83 7zip-22.01+really25.01+dfsg/debian/patches/0007-Manually-de-reference-pointers.patch | 119 7zip-22.01+really25.01+dfsg/debian/patches/0008-Remove-unwanted-hack-for-object-files.patch | 20 7zip-22.01+really25.01+dfsg/debian/patches/0009-Fix-CVE-2023-52168-and-CVE-2023-52169.patch | 146 7zip-22.01+really25.01+dfsg/debian/patches/series | 10 7zip-22.01+really25.01+dfsg/debian/salsa-ci.yml | 3 1049 files changed, 82031 insertions(+), 37480 deletions(-) Unrecognised file line in .dsc: -----BEGIN PGP SIGNATURE----- dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpwjlclt2z/7zip_22.01+dfsg-8+deb12u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpwjlclt2z/7zip_22.01+really25.01+dfsg-0+deb12u1.dsc: no acceptable signature found diff -Nru 7zip-22.01+dfsg/Asm/x86/7zAsm.asm 7zip-22.01+really25.01+dfsg/Asm/x86/7zAsm.asm --- 7zip-22.01+dfsg/Asm/x86/7zAsm.asm 2022-05-16 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/7zAsm.asm 2023-12-08 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ ; 7zAsm.asm -- ASM macros -; 2022-05-16 : Igor Pavlov : Public domain +; 2023-12-08 : Igor Pavlov : Public domain ; UASM can require these changes @@ -43,7 +43,7 @@ endif endif -OPTION PROLOGUE:NONE +OPTION PROLOGUE:NONE OPTION EPILOGUE:NONE MY_ASM_START macro @@ -121,10 +121,29 @@ x2_H equ DH x3_H equ BH +; r0_L equ AL +; r1_L equ CL +; r2_L equ DL +; r3_L equ BL + +; r0_H equ AH +; r1_H equ CH +; r2_H equ DH +; r3_H equ BH + + ifdef x64 x5_L equ BPL x6_L equ SIL x7_L equ DIL + x8_L equ r8b + x9_L equ r9b + x10_L equ r10b + x11_L equ r11b + x12_L equ r12b + x13_L equ r13b + x14_L equ r14b + x15_L equ r15b r0 equ RAX r1 equ RCX @@ -153,6 +172,22 @@ r7 equ x7 endif + x0_R equ r0 + x1_R equ r1 + x2_R equ r2 + x3_R equ r3 + x4_R equ r4 + x5_R equ r5 + x6_R equ r6 + x7_R equ r7 + x8_R equ r8 + x9_R equ r9 + x10_R equ r10 + x11_R equ r11 + x12_R equ r12 + x13_R equ r13 + x14_R equ r14 + x15_R equ r15 ifdef x64 ifdef ABI_LINUX @@ -200,6 +235,14 @@ REG_ABI_PARAM_1_x equ REG_PARAM_1_x REG_ABI_PARAM_1 equ REG_PARAM_1 +MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + MY_PUSH_4_REGS +endm + +MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + MY_POP_4_REGS +endm + else ; x64 @@ -261,12 +304,25 @@ endif ; IS_LINUX -MY_PUSH_PRESERVED_ABI_REGS macro +MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro if (IS_LINUX gt 0) MY_PUSH_2_REGS else MY_PUSH_4_REGS endif +endm + +MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + if (IS_LINUX gt 0) + MY_POP_2_REGS + else + MY_POP_4_REGS + endif +endm + + +MY_PUSH_PRESERVED_ABI_REGS macro + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 push r12 push r13 push r14 @@ -279,11 +335,7 @@ pop r14 pop r13 pop r12 - if (IS_LINUX gt 0) - MY_POP_2_REGS - else - MY_POP_4_REGS - endif + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 endm endif ; x64 diff -Nru 7zip-22.01+dfsg/Asm/x86/7zCrcOpt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/7zCrcOpt.asm --- 7zip-22.01+dfsg/Asm/x86/7zCrcOpt.asm 2021-02-07 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/7zCrcOpt.asm 2023-12-08 17:00:00.000000000 +0000 @@ -1,180 +1,258 @@ ; 7zCrcOpt.asm -- CRC32 calculation : optimized version -; 2021-02-07 : Igor Pavlov : Public domain +; 2023-12-08 : Igor Pavlov : Public domain include 7zAsm.asm MY_ASM_START -rD equ r2 -rN equ r7 -rT equ r5 +NUM_WORDS equ 3 +UNROLL_CNT equ 2 -ifdef x64 - num_VAR equ r8 - table_VAR equ r9 -else - if (IS_CDECL gt 0) - crc_OFFS equ (REG_SIZE * 5) - data_OFFS equ (REG_SIZE + crc_OFFS) - size_OFFS equ (REG_SIZE + data_OFFS) - else - size_OFFS equ (REG_SIZE * 5) - endif - table_OFFS equ (REG_SIZE + size_OFFS) - num_VAR equ [r4 + size_OFFS] - table_VAR equ [r4 + table_OFFS] +if (NUM_WORDS lt 1) or (NUM_WORDS gt 64) +.err +endif +if (UNROLL_CNT lt 1) +.err +endif + +rD equ r2 +rD_x equ x2 +rN equ r7 +rT equ r5 + +ifndef x64 + if (IS_CDECL gt 0) + crc_OFFS equ (REG_SIZE * 5) + data_OFFS equ (REG_SIZE + crc_OFFS) + size_OFFS equ (REG_SIZE + data_OFFS) + else + size_OFFS equ (REG_SIZE * 5) + endif + table_OFFS equ (REG_SIZE + size_OFFS) endif -SRCDAT equ rD + rN * 1 + 4 * +; rN + rD is same speed as rD, but we reduce one instruction in loop +SRCDAT_1 equ rN + rD * 1 + 1 * +SRCDAT_4 equ rN + rD * 1 + 4 * CRC macro op:req, dest:req, src:req, t:req - op dest, DWORD PTR [rT + src * 4 + 0400h * t] + op dest, dword ptr [rT + @CatStr(src, _R) * 4 + 0400h * (t)] endm CRC_XOR macro dest:req, src:req, t:req - CRC xor, dest, src, t + CRC xor, dest, src, t endm CRC_MOV macro dest:req, src:req, t:req - CRC mov, dest, src, t + CRC mov, dest, src, t +endm + +MOVZXLO macro dest:req, src:req + movzx dest, @CatStr(src, _L) +endm + +MOVZXHI macro dest:req, src:req + movzx dest, @CatStr(src, _H) endm +; movzx x0, x0_L - is slow in some cpus (ivb), if same register for src and dest +; movzx x3, x0_L sometimes is 0 cycles latency (not always) +; movzx x3, x0_L sometimes is 0.5 cycles latency +; movzx x3, x0_H is 2 cycles latency in some cpus + CRC1b macro - movzx x6, BYTE PTR [rD] - inc rD - movzx x3, x0_L - xor x6, x3 - shr x0, 8 - CRC xor, x0, r6, 0 - dec rN + movzx x6, byte ptr [rD] + MOVZXLO x3, x0 + inc rD + shr x0, 8 + xor x6, x3 + CRC_XOR x0, x6, 0 + dec rN +endm + +LOAD_1 macro dest:req, t:req, iter:req, index:req + movzx dest, byte ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)] +endm + +LOAD_2 macro dest:req, t:req, iter:req, index:req + movzx dest, word ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)] +endm + +CRC_QUAD macro nn, t:req, iter:req +ifdef x64 + ; paired memory loads give 1-3% speed gain, but it uses more registers + LOAD_2 x3, t, iter, 0 + LOAD_2 x9, t, iter, 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 3 + MOVZXLO x6, x9 + shr x9, 8 + CRC_XOR nn, x3, t * 4 + 2 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x9, t * 4 + 0 +elseif 0 + LOAD_2 x3, t, iter, 0 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 3 + CRC_XOR nn, x3, t * 4 + 2 + LOAD_2 x3, t, iter, 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x3, t * 4 + 0 +elseif 0 + LOAD_1 x3, t, iter, 0 + LOAD_1 x6, t, iter, 1 + CRC_XOR nn, x3, t * 4 + 3 + CRC_XOR nn, x6, t * 4 + 2 + LOAD_1 x3, t, iter, 2 + LOAD_1 x6, t, iter, 3 + CRC_XOR nn, x3, t * 4 + 1 + CRC_XOR nn, x6, t * 4 + 0 +else + ; 32-bit load is better if there is only one read port (core2) + ; but that code can be slower if there are 2 read ports (snb) + mov x3, dword ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + 0)] + MOVZXLO x6, x3 + CRC_XOR nn, x6, t * 4 + 3 + MOVZXHI x6, x3 + shr x3, 16 + CRC_XOR nn, x6, t * 4 + 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x3, t * 4 + 0 +endif +endm + + +LAST equ (4 * (NUM_WORDS - 1)) + +CRC_ITER macro qq, nn, iter + mov nn, [SRCDAT_4 (NUM_WORDS * (1 + iter))] + + i = 0 + rept NUM_WORDS - 1 + CRC_QUAD nn, i, iter + i = i + 1 + endm + + MOVZXLO x6, qq + mov x3, qq + shr x3, 24 + CRC_XOR nn, x6, LAST + 3 + CRC_XOR nn, x3, LAST + 0 + ror qq, 16 + MOVZXLO x6, qq + shr qq, 24 + CRC_XOR nn, x6, LAST + 1 +if ((UNROLL_CNT and 1) eq 1) and (iter eq (UNROLL_CNT - 1)) + CRC_MOV qq, qq, LAST + 2 + xor qq, nn +else + CRC_XOR nn, qq, LAST + 2 +endif endm -MY_PROLOG macro crc_end:req +; + 4 for prefetching next 4-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 * UNROLL_CNT + 4) +ALIGN_MASK equ 3 + + +; MY_PROC @CatStr(CrcUpdateT, 12), 4 +MY_PROC @CatStr(CrcUpdateT, %(NUM_WORDS * 4)), 4 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 ifdef x64 + mov x0, REG_ABI_PARAM_0_x ; x0 = x1(win) / x7(linux) + mov rT, REG_ABI_PARAM_3 ; r5 = r9(win) / x1(linux) + mov rN, REG_ABI_PARAM_2 ; r7 = r8(win) / r2(linux) + ; mov rD, REG_ABI_PARAM_1 ; r2 = r2(win) if (IS_LINUX gt 0) - MY_PUSH_2_REGS - mov x0, REG_ABI_PARAM_0_x ; x0 = x7 - mov rT, REG_ABI_PARAM_3 ; r5 = r1 - mov rN, REG_ABI_PARAM_2 ; r7 = r2 mov rD, REG_ABI_PARAM_1 ; r2 = r6 - else - MY_PUSH_4_REGS - mov x0, REG_ABI_PARAM_0_x ; x0 = x1 - mov rT, REG_ABI_PARAM_3 ; r5 = r9 - mov rN, REG_ABI_PARAM_2 ; r7 = r8 - ; mov rD, REG_ABI_PARAM_1 ; r2 = r2 endif else - MY_PUSH_4_REGS if (IS_CDECL gt 0) mov x0, [r4 + crc_OFFS] mov rD, [r4 + data_OFFS] else mov x0, REG_ABI_PARAM_0_x endif - mov rN, num_VAR - mov rT, table_VAR + mov rN, [r4 + size_OFFS] + mov rT, [r4 + table_OFFS] endif - test rN, rN - jz crc_end - @@: - test rD, 7 - jz @F - CRC1b - jnz @B - @@: - cmp rN, 16 - jb crc_end - add rN, rD - mov num_VAR, rN - sub rN, 8 - and rN, NOT 7 - sub rD, rN - xor x0, [SRCDAT 0] -endm - -MY_EPILOG macro crc_end:req - xor x0, [SRCDAT 0] - mov rD, rN - mov rN, num_VAR - sub rN, rD - crc_end: - test rN, rN - jz @F - CRC1b - jmp crc_end - @@: - if (IS_X64 gt 0) and (IS_LINUX gt 0) - MY_POP_2_REGS - else - MY_POP_4_REGS - endif + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end +@@: + test rD_x, ALIGN_MASK ; test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, dword ptr [rD] + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + sub rD, rN + +align 16 +@@: +unr_index = 0 +while unr_index lt UNROLL_CNT + if (unr_index and 1) eq 0 + CRC_ITER x0, x1, unr_index + else + CRC_ITER x1, x0, unr_index + endif + unr_index = unr_index + 1 endm -MY_PROC CrcUpdateT8, 4 - MY_PROLOG crc_end_8 - mov x1, [SRCDAT 1] - align 16 - main_loop_8: - mov x6, [SRCDAT 2] - movzx x3, x1_L - CRC_XOR x6, r3, 3 - movzx x3, x1_H - CRC_XOR x6, r3, 2 - shr x1, 16 - movzx x3, x1_L - movzx x1, x1_H - CRC_XOR x6, r3, 1 - movzx x3, x0_L - CRC_XOR x6, r1, 0 - - mov x1, [SRCDAT 3] - CRC_XOR x6, r3, 7 - movzx x3, x0_H - shr x0, 16 - CRC_XOR x6, r3, 6 - movzx x3, x0_L - CRC_XOR x6, r3, 5 - movzx x3, x0_H - CRC_MOV x0, r3, 4 - xor x0, x6 - add rD, 8 - jnz main_loop_8 + add rD, NUM_WORDS * 4 * UNROLL_CNT + jnc @B - MY_EPILOG crc_end_8 -MY_ENDP - -MY_PROC CrcUpdateT4, 4 - MY_PROLOG crc_end_4 - align 16 - main_loop_4: - movzx x1, x0_L - movzx x3, x0_H - shr x0, 16 - movzx x6, x0_H - and x0, 0FFh - CRC_MOV x1, r1, 3 - xor x1, [SRCDAT 1] - CRC_XOR x1, r3, 2 - CRC_XOR x1, r6, 0 - CRC_XOR x1, r0, 1 - - movzx x0, x1_L - movzx x3, x1_H - shr x1, 16 - movzx x6, x1_H - and x1, 0FFh - CRC_MOV x0, r0, 3 - xor x0, [SRCDAT 2] - CRC_XOR x0, r3, 2 - CRC_XOR x0, r6, 0 - CRC_XOR x0, r1, 1 - add rD, 8 - jnz main_loop_4 +if 0 + ; byte verson + add rD, rN + xor x0, dword ptr [rD] + add rN, NUM_BYTES_LIMIT - 1 +else + ; 4-byte version + add rN, 4 * NUM_WORDS * UNROLL_CNT + sub rD, 4 * NUM_WORDS * UNROLL_CNT +@@: + MOVZXLO x3, x0 + MOVZXHI x1, x0 + shr x0, 16 + MOVZXLO x6, x0 + shr x0, 8 + CRC_MOV x0, x0, 0 + CRC_XOR x0, x3, 3 + CRC_XOR x0, x1, 2 + CRC_XOR x0, x6, 1 + + add rD, 4 +if (NUM_WORDS * UNROLL_CNT) ne 1 + jc @F + xor x0, [SRCDAT_4 0] + jmp @B +@@: +endif + add rD, rN + add rN, 4 - 1 + +endif + + sub rN, rD +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B - MY_EPILOG crc_end_4 +func_end: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 MY_ENDP end diff -Nru 7zip-22.01+dfsg/Asm/x86/LzFindOpt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/LzFindOpt.asm --- 7zip-22.01+dfsg/Asm/x86/LzFindOpt.asm 2021-07-21 19:31:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/LzFindOpt.asm 2024-06-18 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ ; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function -; 2021-07-21: Igor Pavlov : Public domain +; 2024-06-18: Igor Pavlov : Public domain ; ifndef x64 @@ -11,10 +11,31 @@ MY_ASM_START -_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE' +ifndef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1 +else + Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1 +endif +endif +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE' MY_ALIGN macro num:req align num + ; align 16 +endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside our function. + align 16 +endm +endif + + +MY_ALIGN_16 macro + MY_ALIGN 16 endm MY_ALIGN_32 macro @@ -136,7 +157,11 @@ endm +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT ; MY_ALIGN_64 +else + MY_ALIGN_16 +endif MY_PROC GetMatchesSpecN_2, 13 MY_PUSH_PRESERVED_ABI_REGS mov r0, RSP @@ -508,6 +533,8 @@ MY_POP_PRESERVED_ABI_REGS MY_ENDP +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT _TEXT$LZFINDOPT ENDS +endif end diff -Nru 7zip-22.01+dfsg/Asm/x86/LzmaDecOpt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/LzmaDecOpt.asm --- 7zip-22.01+dfsg/Asm/x86/LzmaDecOpt.asm 2021-02-23 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/LzmaDecOpt.asm 2024-06-18 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ ; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function -; 2021-02-23: Igor Pavlov : Public domain +; 2024-06-18: Igor Pavlov : Public domain ; ; 3 - is the code compatibility version of LzmaDec_DecodeReal_*() ; function for check at link time. @@ -17,11 +17,41 @@ MY_ASM_START -_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE' +; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is defined, we use additional SEGMENT with 64-byte alignment. +; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is not defined, we use default SEGMENT (where default 16-byte alignment of segment is expected). +; The performance is almost identical in our tests. +; But the performance can depend from position of lzmadec code inside instruction cache +; or micro-op cache line (depending from low address bits in 32-byte/64-byte cache lines). +; And 64-byte alignment provides a more consistent speed regardless +; of the code's position in the executable. +; But also it's possible that code without Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT can be +; slightly faster than 64-bytes aligned code in some cases, if offset of lzmadec +; code in 64-byte block after compilation provides better speed by some reason. +; Note that Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT adds an extra section to the ELF file. +; If you don't want to get that extra section, do not define Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT. + +ifndef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1 +else + Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1 +endif +endif +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE' MY_ALIGN macro num:req align num + ; align 16 endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside out function. + align 16 +endm +endif + MY_ALIGN_16 macro MY_ALIGN 16 @@ -610,7 +640,11 @@ PARAM_limit equ REG_ABI_PARAM_1 PARAM_bufLimit equ REG_ABI_PARAM_2 +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT ; MY_ALIGN_64 +else + MY_ALIGN_16 +endif MY_PROC LzmaDec_DecodeReal_3, 3 MY_PUSH_PRESERVED_ABI_REGS @@ -1298,6 +1332,8 @@ MY_POP_PRESERVED_ABI_REGS MY_ENDP +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT _TEXT$LZMADECOPT ENDS +endif end diff -Nru 7zip-22.01+dfsg/Asm/x86/Sha1Opt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/Sha1Opt.asm --- 7zip-22.01+dfsg/Asm/x86/Sha1Opt.asm 2021-03-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/Sha1Opt.asm 2024-06-16 08:00:00.000000000 +0000 @@ -1,5 +1,5 @@ ; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions -; 2021-03-10 : Igor Pavlov : Public domain +; 2024-06-16 : Igor Pavlov : Public domain include 7zAsm.asm @@ -20,7 +20,7 @@ -CONST SEGMENT +CONST SEGMENT READONLY align 16 Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0 diff -Nru 7zip-22.01+dfsg/Asm/x86/Sha256Opt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/Sha256Opt.asm --- 7zip-22.01+dfsg/Asm/x86/Sha256Opt.asm 2022-04-17 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/Sha256Opt.asm 2024-06-16 08:00:00.000000000 +0000 @@ -1,5 +1,5 @@ ; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions -; 2022-04-17 : Igor Pavlov : Public domain +; 2024-06-16 : Igor Pavlov : Public domain include 7zAsm.asm @@ -20,7 +20,7 @@ EXTRN K_CONST:xmmword @ -CONST SEGMENT +CONST SEGMENT READONLY align 16 Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 diff -Nru 7zip-22.01+dfsg/Asm/x86/Sort.asm 7zip-22.01+really25.01+dfsg/Asm/x86/Sort.asm --- 7zip-22.01+dfsg/Asm/x86/Sort.asm 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/Sort.asm 2025-01-08 08:00:00.000000000 +0000 @@ -0,0 +1,860 @@ +; SortTest.asm -- ASM version of HeapSort() function +; Igor Pavlov : Public domain + +include ../../../../Asm/x86/7zAsm.asm + +MY_ASM_START + +ifndef Z7_SORT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + ; Z7_SORT_ASM_USE_SEGMENT equ 1 +else + ; Z7_SORT_ASM_USE_SEGMENT equ 1 +endif +endif + +ifdef Z7_SORT_ASM_USE_SEGMENT +_TEXT$Z7_SORT SEGMENT ALIGN(64) 'CODE' +MY_ALIGN macro num:req + align num +endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside our function. + align 16 +endm +endif + + +MY_ALIGN_16 macro + MY_ALIGN 16 +endm + +MY_ALIGN_32 macro + MY_ALIGN 32 +endm + +MY_ALIGN_64 macro + MY_ALIGN 64 +endm + +ifdef x64 + +NUM_PREFETCH_LEVELS equ 3 ; to prefetch 1x 64-bytes line (is good for most cases) +; NUM_PREFETCH_LEVELS equ 4 ; to prefetch 2x 64-bytes lines (better for big arrays) + +acc equ x0 +k equ r0 +k_x equ x0 + +p equ r1 + +s equ r2 +s_x equ x2 + +a0 equ x3 +t0 equ a0 + +a3 equ x5 +qq equ a3 + +a1 equ x6 +t1 equ a1 +t1_r equ r6 + +a2 equ x7 +t2 equ a2 + +i equ r8 +e0 equ x8 + +e1 equ x9 + +num_last equ r10 +num_last_x equ x10 + +next4_lim equ r11 +pref_lim equ r12 + + + +SORT_2_WITH_TEMP_REG macro b0, b1, temp_reg + mov temp_reg, b0 + cmp b0, b1 + cmovae b0, b1 ; min + cmovae b1, temp_reg ; max +endm + +SORT macro b0, b1 + SORT_2_WITH_TEMP_REG b0, b1, acc +endm + +LOAD macro dest:req, index:req + mov dest, [p + 4 * index] +endm + +STORE macro reg:req, index:req + mov [p + 4 * index], reg +endm + + +if (NUM_PREFETCH_LEVELS gt 3) + num_prefetches equ (1 SHL (NUM_PREFETCH_LEVELS - 3)) +else + num_prefetches equ 1 +endif + +PREFETCH_OP macro offs + cur_offset = 7 * 4 ; it's average offset in 64-bytes cache line. + ; cur_offset = 0 ; we can use zero offset, if we are sure that array is aligned for 64-bytes. + rept num_prefetches + if 1 + prefetcht0 byte ptr [p + offs + cur_offset] + else + mov pref_x, dword ptr [p + offs + cur_offset] + endif + cur_offset = cur_offset + 64 + endm +endm + +PREFETCH_MY macro +if 1 + if 1 + shl k, NUM_PREFETCH_LEVELS + 3 + else + ; we delay prefetch instruction to improve main loads + shl k, NUM_PREFETCH_LEVELS + shl k, 3 + ; shl k, 0 + endif + PREFETCH_OP k +elseif 1 + shl k, 3 + PREFETCH_OP k * (1 SHL NUM_PREFETCH_LEVELS) ; change it +endif +endm + + +STEP_1 macro exit_label, prefetch_macro +use_cmov_1 equ 1 ; set 1 for cmov, but it's slower in some cases + ; set 0 for LOAD after adc s, 0 + cmp t0, t1 + if use_cmov_1 + cmovb t0, t1 + ; STORE t0, k + endif + adc s, 0 + if use_cmov_1 eq 0 + LOAD t0, s + endif + cmp qq, t0 + jae exit_label + if 1 ; use_cmov_1 eq 0 + STORE t0, k + endif + prefetch_macro + mov t0, [p + s * 8] + mov t1, [p + s * 8 + 4] + mov k, s + add s, s ; slower for some cpus + ; lea s, dword ptr [s + s] ; slower for some cpus + ; shl s, 1 ; faster for some cpus + ; lea s, dword ptr [s * 2] ; faster for some cpus + rept 0 ; 1000 for debug : 0 for normal + ; number of calls in generate_stage : ~0.6 of number of items + shl k, 0 + endm +endm + + +STEP_2 macro exit_label, prefetch_macro +use_cmov_2 equ 0 ; set 1 for cmov, but it's slower in some cases + ; set 0 for LOAD after adc s, 0 + cmp t0, t1 + if use_cmov_2 + mov t2, t0 + cmovb t2, t1 + ; STORE t2, k + endif + mov t0, [p + s * 8] + mov t1, [p + s * 8 + 4] + cmovb t0, [p + s * 8 + 8] + cmovb t1, [p + s * 8 + 12] + adc s, 0 + if use_cmov_2 eq 0 + LOAD t2, s + endif + cmp qq, t2 + jae exit_label + if 1 ; use_cmov_2 eq 0 + STORE t2, k + endif + prefetch_macro + mov k, s + ; add s, s + ; lea s, [s + s] + shl s, 1 + ; lea s, [s * 2] +endm + + +MOVE_SMALLEST_UP macro STEP, use_prefetch, num_unrolls + LOCAL exit_1, exit_2, leaves, opt_loop, last_nodes + + ; s == k * 2 + ; t0 == (p)[s] + ; t1 == (p)[s + 1] + cmp k, next4_lim + jae leaves + + rept num_unrolls + STEP exit_2 + cmp k, next4_lim + jae leaves + endm + + if use_prefetch + prefetch_macro equ PREFETCH_MY + pref_lim_2 equ pref_lim + ; lea pref_lim, dword ptr [num_last + 1] + ; shr pref_lim, NUM_PREFETCH_LEVELS + 1 + cmp k, pref_lim_2 + jae last_nodes + else + prefetch_macro equ + pref_lim_2 equ next4_lim + endif + +MY_ALIGN_16 +opt_loop: + STEP exit_2, prefetch_macro + cmp k, pref_lim_2 + jb opt_loop + +last_nodes: + ; k >= pref_lim_2 + ; 2 cases are possible: + ; case-1: num_after_prefetch_levels == 0 && next4_lim = pref_lim_2 + ; case-2: num_after_prefetch_levels == NUM_PREFETCH_LEVELS - 1 && + ; next4_lim = pref_lim_2 / (NUM_PREFETCH_LEVELS - 1) + if use_prefetch + yyy = NUM_PREFETCH_LEVELS - 1 + while yyy + yyy = yyy - 1 + STEP exit_2 + if yyy + cmp k, next4_lim + jae leaves + endif + endm + endif + +leaves: + ; k >= next4_lim == (num_last + 1) / 4 must be provided by previous code. + ; we have 2 nodes in (s) level : always + ; we can have some nodes in (s * 2) level : low probability case + ; we have no nodes in (s * 4) level + ; s == k * 2 + ; t0 == (p)[s] + ; t1 == (p)[s + 1] + cmp t0, t1 + cmovb t0, t1 + adc s, 0 + STORE t0, k + + ; t0 == (p)[s] + ; s / 2 == k : (s) is index of max item from (p)[k * 2], (p)[k * 2 + 1] + ; we have 3 possible cases here: + ; s * 2 > num_last : (s) node has no childs + ; s * 2 == num_last : (s) node has 1 leaf child that is last item of array + ; s * 2 < num_last : (s) node has 2 leaf childs. We provide (s * 4 > num_last) + ; we check for (s * 2 > num_last) before "cmp qq, t0" check, because + ; we will replace conditional jump with cmov instruction later. + lea t1_r, dword ptr [s + s] + cmp t1_r, num_last + ja exit_1 ; if (s * 2 > num_last), we have no childs : it's high probability branch + + ; it's low probability branch + ; s * 2 <= num_last + cmp qq, t0 + jae exit_2 + + ; qq < t0, so we go to next level + ; we check 1 or 2 childs in next level + mov t0, [p + s * 8] + mov k, s + mov s, t1_r + cmp t1_r, num_last + je @F ; (s == num_last) means that we have single child in tree + + ; (s < num_last) : so we must read both childs and select max of them. + mov t1, [p + k * 8 + 4] + cmp t0, t1 + cmovb t0, t1 + adc s, 0 +@@: + STORE t0, k +exit_1: + ; t0 == (p)[s], s / 2 == k : (s) is index of max item from (p)[k * 2], (p)[k * 2 + 1] + cmp qq, t0 + cmovb k, s +exit_2: + STORE qq, k +endm + + + + +ifdef Z7_SORT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif + +MY_PROC HeapSort, 2 + +if (IS_LINUX gt 0) + mov p, REG_ABI_PARAM_0 ; r1 <- r7 : linux +endif + mov num_last, REG_ABI_PARAM_1 ; r10 <- r6 : linux + ; r10 <- r2 : win64 + cmp num_last, 2 + jb end_1 + + ; MY_PUSH_PRESERVED_ABI_REGS + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + push r12 + + cmp num_last, 4 + ja sort_5 + + LOAD a0, 0 + LOAD a1, 1 + SORT a0, a1 + cmp num_last, 3 + jb end_2 + + LOAD a2, 2 + je sort_3 + + LOAD a3, 3 + SORT a2, a3 + SORT a1, a3 + STORE a3, 3 +sort_3: + SORT a0, a2 + SORT a1, a2 + STORE a2, 2 + jmp end_2 + +sort_5: + ; (num_last > 4) is required here + ; if (num_last >= 6) : we will use optimized loop for leaf nodes loop_down_1 + mov next4_lim, num_last + shr next4_lim, 2 + + dec num_last + mov k, num_last + shr k, 1 + mov i, num_last + shr i, 2 + test num_last, 1 + jnz size_even + + ; ODD number of items. So we compare parent with single child + LOAD t1, num_last + LOAD t0, k + SORT_2_WITH_TEMP_REG t1, t0, t2 + STORE t1, num_last + STORE t0, k + dec k + +size_even: + cmp k, i + jbe loop_down ; jump for num_last == 4 case + +if 0 ; 1 for debug + mov r15, k + mov r14d, 1 ; 100 +loop_benchmark: +endif + ; optimized loop for leaf nodes: + mov t0, [p + k * 8] + mov t1, [p + k * 8 + 4] + +MY_ALIGN_16 +loop_down_1: + ; we compare parent with max of childs: + ; lea s, dword ptr [2 * k] + mov s, k + cmp t0, t1 + cmovb t0, t1 + adc s, s + LOAD t2, k + STORE t0, k + cmp t2, t0 + cmovae s, k + dec k + ; we preload next items before STORE operation for calculated address + mov t0, [p + k * 8] + mov t1, [p + k * 8 + 4] + STORE t2, s + cmp k, i + jne loop_down_1 + +if 0 ; 1 for debug + mov k, r15 + dec r14d + jnz loop_benchmark + ; jmp end_debug +endif + +MY_ALIGN_16 +loop_down: + mov t0, [p + i * 8] + mov t1, [p + i * 8 + 4] + LOAD qq, i + mov k, i + lea s, dword ptr [i + i] + ; jmp end_debug + DOWN_use_prefetch equ 0 + DOWN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_1, DOWN_use_prefetch, DOWN_num_unrolls + sub i, 1 + jnb loop_down + + ; jmp end_debug + LOAD e0, 0 + LOAD e1, 1 + + LEVEL_3_LIMIT equ 8 ; 8 is default, but 7 also can work + + cmp num_last, LEVEL_3_LIMIT + 1 + jb main_loop_sort_5 + +MY_ALIGN_16 +main_loop_sort: + ; num_last > LEVEL_3_LIMIT + ; p[size--] = p[0]; + LOAD qq, num_last + STORE e0, num_last + mov e0, e1 + + mov next4_lim, num_last + shr next4_lim, 2 + mov pref_lim, num_last + shr pref_lim, NUM_PREFETCH_LEVELS + 1 + + dec num_last +if 0 ; 1 for debug + ; that optional optimization can improve the performance, if there are identical items in array + ; 3 times improvement : if all items in array are identical + ; 20% improvement : if items are different for 1 bit only + ; 1-10% improvement : if items are different for (2+) bits + ; no gain : if items are different + cmp qq, e1 + jae next_iter_main +endif + LOAD e1, 2 + LOAD t0, 3 + mov k_x, 2 + cmp e1, t0 + cmovb e1, t0 + mov t0, [p + 4 * (4 + 0)] + mov t1, [p + 4 * (4 + 1)] + cmovb t0, [p + 4 * (4 + 2)] + cmovb t1, [p + 4 * (4 + 3)] + adc k_x, 0 + ; (qq <= e1), because the tree is correctly sorted + ; also here we could check (qq >= e1) or (qq == e1) for faster exit + lea s, dword ptr [k + k] + MAIN_use_prefetch equ 1 + MAIN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_2, MAIN_use_prefetch, MAIN_num_unrolls + +next_iter_main: + cmp num_last, LEVEL_3_LIMIT + jne main_loop_sort + + ; num_last == LEVEL_3_LIMIT +main_loop_sort_5: + ; 4 <= num_last <= LEVEL_3_LIMIT + ; p[size--] = p[0]; + LOAD qq, num_last + STORE e0, num_last + mov e0, e1 + dec num_last_x + + LOAD e1, 2 + LOAD t0, 3 + mov k_x, 2 + cmp e1, t0 + cmovb e1, t0 + adc k_x, 0 + + lea s_x, dword ptr [k * 2] + cmp s_x, num_last_x + ja exit_2 + + mov t0, [p + k * 8] + je exit_1 + + ; s < num_last + mov t1, [p + k * 8 + 4] + cmp t0, t1 + cmovb t0, t1 + adc s_x, 0 +exit_1: + STORE t0, k + cmp qq, t0 + cmovb k_x, s_x +exit_2: + STORE qq, k + cmp num_last_x, 3 + jne main_loop_sort_5 + + ; num_last == 3 (real_size == 4) + LOAD a0, 2 + LOAD a1, 3 + STORE e1, 2 + STORE e0, 3 + SORT a0, a1 +end_2: + STORE a0, 0 + STORE a1, 1 +; end_debug: + ; MY_POP_PRESERVED_ABI_REGS + pop r12 + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +end_1: +MY_ENDP + + + +else +; ------------ x86 32-bit ------------ + +ifdef x64 +IS_CDECL = 0 +endif + +acc equ x0 +k equ r0 +k_x equ acc + +p equ r1 + +num_last equ r2 +num_last_x equ x2 + +a0 equ x3 +t0 equ a0 + +a3 equ x5 +i equ r5 +e0 equ a3 + +a1 equ x6 +qq equ a1 + +a2 equ x7 +s equ r7 +s_x equ a2 + + +SORT macro b0, b1 + cmp b1, b0 + jae @F + if 1 + xchg b0, b1 + else + mov acc, b0 + mov b0, b1 ; min + mov b1, acc ; max + endif +@@: +endm + +LOAD macro dest:req, index:req + mov dest, [p + 4 * index] +endm + +STORE macro reg:req, index:req + mov [p + 4 * index], reg +endm + + +STEP_1 macro exit_label + mov t0, [p + k * 8] + cmp t0, [p + k * 8 + 4] + adc s, 0 + LOAD t0, s + STORE t0, k ; we lookahed stooring for most expected branch + cmp qq, t0 + jae exit_label + ; STORE t0, k ; use if + mov k, s + add s, s + ; lea s, dword ptr [s + s] + ; shl s, 1 + ; lea s, dword ptr [s * 2] +endm + +STEP_BRANCH macro exit_label + mov t0, [p + k * 8] + cmp t0, [p + k * 8 + 4] + jae @F + inc s + mov t0, [p + k * 8 + 4] +@@: + cmp qq, t0 + jae exit_label + STORE t0, k + mov k, s + add s, s +endm + + + +MOVE_SMALLEST_UP macro STEP, num_unrolls, exit_2 + LOCAL leaves, opt_loop, single + + ; s == k * 2 + rept num_unrolls + cmp s, num_last + jae leaves + STEP_1 exit_2 + endm + cmp s, num_last + jb opt_loop + +leaves: + ; (s >= num_last) + jne exit_2 +single: + ; (s == num_last) + mov t0, [p + k * 8] + cmp qq, t0 + jae exit_2 + STORE t0, k + mov k, s + jmp exit_2 + +MY_ALIGN_16 +opt_loop: + STEP exit_2 + cmp s, num_last + jb opt_loop + je single +exit_2: + STORE qq, k +endm + + + + +ifdef Z7_SORT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif + +MY_PROC HeapSort, 2 + ifdef x64 + if (IS_LINUX gt 0) + mov num_last, REG_ABI_PARAM_1 ; r2 <- r6 : linux + mov p, REG_ABI_PARAM_0 ; r1 <- r7 : linux + endif + elseif (IS_CDECL gt 0) + mov num_last, [r4 + REG_SIZE * 2] + mov p, [r4 + REG_SIZE * 1] + endif + cmp num_last, 2 + jb end_1 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + + cmp num_last, 4 + ja sort_5 + + LOAD a0, 0 + LOAD a1, 1 + SORT a0, a1 + cmp num_last, 3 + jb end_2 + + LOAD a2, 2 + je sort_3 + + LOAD a3, 3 + SORT a2, a3 + SORT a1, a3 + STORE a3, 3 +sort_3: + SORT a0, a2 + SORT a1, a2 + STORE a2, 2 + jmp end_2 + +sort_5: + ; num_last > 4 + lea i, dword ptr [num_last - 2] + dec num_last + test i, 1 + jz loop_down + + ; single child + mov t0, [p + num_last * 4] + mov qq, [p + num_last * 2] + dec i + cmp qq, t0 + jae loop_down + + mov [p + num_last * 2], t0 + mov [p + num_last * 4], qq + +MY_ALIGN_16 +loop_down: + mov t0, [p + i * 4] + cmp t0, [p + i * 4 + 4] + mov k, i + mov qq, [p + i * 2] + adc k, 0 + LOAD t0, k + cmp qq, t0 + jae down_next + mov [p + i * 2], t0 + lea s, dword ptr [k + k] + + DOWN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_1, DOWN_num_unrolls, down_exit_label +down_next: + sub i, 2 + jnb loop_down + ; jmp end_debug + + LOAD e0, 0 + +MY_ALIGN_16 +main_loop_sort: + ; num_last > 3 + mov t0, [p + 2 * 4] + cmp t0, [p + 3 * 4] + LOAD qq, num_last + STORE e0, num_last + LOAD e0, 1 + mov s_x, 2 + mov k_x, 1 + adc s, 0 + LOAD t0, s + dec num_last + cmp qq, t0 + jae main_exit_label + STORE t0, 1 + mov k, s + add s, s + if 1 + ; for branch data prefetch mode : + ; it's faster for large arrays : larger than (1 << 13) items. + MAIN_num_unrolls equ 10 + STEP_LOOP equ STEP_BRANCH + else + MAIN_num_unrolls equ 0 + STEP_LOOP equ STEP_1 + endif + + MOVE_SMALLEST_UP STEP_LOOP, MAIN_num_unrolls, main_exit_label + + ; jmp end_debug + cmp num_last, 3 + jne main_loop_sort + + ; num_last == 3 (real_size == 4) + LOAD a0, 2 + LOAD a1, 3 + LOAD a2, 1 + STORE e0, 3 ; e0 is alias for a3 + STORE a2, 2 + SORT a0, a1 +end_2: + STORE a0, 0 + STORE a1, 1 +; end_debug: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +end_1: +MY_ENDP + +endif + +ifdef Z7_SORT_ASM_USE_SEGMENT +_TEXT$Z7_SORT ENDS +endif + +if 0 +LEA_IS_D8 (R64) [R2 * 4 + 16] + Lat : TP + 2 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 hsw-rocket + 1 : 2 : p01 snb-ivb + 1 : 1 : p1 conroe-wsm + 1 : 4 : zen3,zen4 + 2 : 4 : zen1,zen2 + +LEA_B_IS (R64) [R2 + R3 * 4] + Lat : TP + 1 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 hsw-rocket + 1 : 2 : p01 snb-ivb + 1 : 1 : p1 nhm-wsm + 1 : 1 : p0 conroe-wsm + 1 : 4 : zen3,zen4 + 2 :2,4 : zen1,zen2 + +LEA_B_IS_D8 (R64) [R2 + R3 * 4 + 16] + Lat : TP + 2 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 ice-rocket + 3 : 1 : p1/p15 hsw-rocket + 3 : 1 : p01 snb-ivb + 1 : 1 : p1 nhm-wsm + 1 : 1 : p0 conroe-wsm + 2,1 : 2 : zen3,zen4 + 2 : 2 : zen1,zen2 + +CMOVB (R64, R64) + Lat : TP + 1,2 : 2 : adl-e + 1 : 2 p06 adl-p + 1 : 2 : p06 bwd-rocket + 1,2 : 2 : p0156+p06 hsw + 1,2 :1.5 : p015+p05 snb-ivb + 1,2 : 1 : p015+p05 nhm + 1 : 1 : 2*p015 conroe + 1 : 2 : zen3,zen4 + 1 : 4 : zen1,zen2 + +ADC (R64, 0) + Lat : TP + 1,2 : 2 : adl-e + 1 : 2 p06 adl-p + 1 : 2 : p06 bwd-rocket + 1 :1.5 : p0156+p06 hsw + 1 :1.5 : p015+p05 snb-ivb + 2 : 1 : 2*p015 conroe-wstm + 1 : 2 : zen1,zen2,zen3,zen4 + +PREFETCHNTA : fetch data into non-temporal cache close to the processor, minimizing cache pollution. + L1 : Pentium3 + L2 : NetBurst + L1, not L2: Core duo, Core 2, Atom processors + L1, not L2, may fetch into L3 with fast replacement: Nehalem, Westmere, Sandy Bridge, ... + NEHALEM: Fills L1/L3, L1 LRU is not updated + L3 with fast replacement: Xeon Processors based on Nehalem, Westmere, Sandy Bridge, ... +PREFETCHT0 : fetch data into all cache levels. +PREFETCHT1 : fetch data into L2 and L3 +endif + +end diff -Nru 7zip-22.01+dfsg/Asm/x86/XzCrc64Opt.asm 7zip-22.01+really25.01+dfsg/Asm/x86/XzCrc64Opt.asm --- 7zip-22.01+dfsg/Asm/x86/XzCrc64Opt.asm 2021-02-06 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/Asm/x86/XzCrc64Opt.asm 2023-12-08 17:00:00.000000000 +0000 @@ -1,113 +1,231 @@ ; XzCrc64Opt.asm -- CRC64 calculation : optimized version -; 2021-02-06 : Igor Pavlov : Public domain +; 2023-12-08 : Igor Pavlov : Public domain include 7zAsm.asm MY_ASM_START +NUM_WORDS equ 3 + +if (NUM_WORDS lt 1) or (NUM_WORDS gt 64) +.err +endif + +NUM_SKIP_BYTES equ ((NUM_WORDS - 2) * 4) + + +MOVZXLO macro dest:req, src:req + movzx dest, @CatStr(src, _L) +endm + +MOVZXHI macro dest:req, src:req + movzx dest, @CatStr(src, _H) +endm + + ifdef x64 -rD equ r9 +rD equ r11 rN equ r10 -rT equ r5 -num_VAR equ r8 - -SRCDAT4 equ dword ptr [rD + rN * 1] +rT equ r9 + +CRC_OP macro op:req, dest:req, src:req, t:req + op dest, QWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t)] +endm CRC_XOR macro dest:req, src:req, t:req - xor dest, QWORD PTR [rT + src * 8 + 0800h * t] + CRC_OP xor, dest, src, t +endm + +CRC_MOV macro dest:req, src:req, t:req + CRC_OP mov, dest, src, t endm CRC1b macro - movzx x6, BYTE PTR [rD] - inc rD - movzx x3, x0_L - xor x6, x3 - shr r0, 8 - CRC_XOR r0, r6, 0 - dec rN + movzx x6, BYTE PTR [rD] + inc rD + MOVZXLO x3, x0 + xor x6, x3 + shr r0, 8 + CRC_XOR r0, x6, 0 + dec rN endm -MY_PROLOG macro crc_end:req - ifdef ABI_LINUX - MY_PUSH_2_REGS - else - MY_PUSH_4_REGS - endif - mov r0, REG_ABI_PARAM_0 - mov rN, REG_ABI_PARAM_2 - mov rT, REG_ABI_PARAM_3 - mov rD, REG_ABI_PARAM_1 - test rN, rN - jz crc_end - @@: - test rD, 3 - jz @F - CRC1b - jnz @B - @@: - cmp rN, 8 - jb crc_end - add rN, rD - mov num_VAR, rN - sub rN, 4 - and rN, NOT 3 - sub rD, rN - mov x1, SRCDAT4 - xor r0, r1 - add rN, 4 -endm - -MY_EPILOG macro crc_end:req - sub rN, 4 - mov x1, SRCDAT4 - xor r0, r1 - mov rD, rN - mov rN, num_VAR - sub rN, rD - crc_end: - test rN, rN - jz @F - CRC1b - jmp crc_end - @@: - ifdef ABI_LINUX - MY_POP_2_REGS - else - MY_POP_4_REGS - endif + +; ALIGN_MASK is 3 or 7 bytes alignment: +ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4) + +if NUM_WORDS eq 1 + +src_rN_offset equ 4 +; + 4 for prefetching next 4-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 4) +SRCDAT4 equ DWORD PTR [rN + rD * 1] + +XOR_NEXT macro + mov x1, [rD] + xor r0, r1 endm -MY_PROC XzCrc64UpdateT4, 4 - MY_PROLOG crc_end_4 - align 16 - main_loop_4: - mov x1, SRCDAT4 - movzx x2, x0_L - movzx x3, x0_H - shr r0, 16 - movzx x6, x0_L - movzx x7, x0_H - shr r0, 16 - CRC_XOR r1, r2, 3 - CRC_XOR r0, r3, 2 - CRC_XOR r1, r6, 1 - CRC_XOR r0, r7, 0 - xor r0, r1 +else ; NUM_WORDS > 1 + +src_rN_offset equ 8 +; + 8 for prefetching next 8-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 8) + +XOR_NEXT macro + xor r0, QWORD PTR [rD] ; 64-bit read, can be unaligned +endm - add rD, 4 - jnz main_loop_4 +; 32-bit or 64-bit +LOAD_SRC_MULT4 macro dest:req, word_index:req + mov dest, [rN + rD * 1 + 4 * (word_index) - src_rN_offset]; +endm - MY_EPILOG crc_end_4 +endif + + + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 4 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + + mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7 + mov rD, REG_ABI_PARAM_1 ; r11 <- r2 / r6 + mov rN, REG_ABI_PARAM_2 ; r10 <- r8 / r2 +if (IS_LINUX gt 0) + mov rT, REG_ABI_PARAM_3 ; r9 <- r9 / r1 +endif + + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + XOR_NEXT + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + sub rD, rN + add rN, src_rN_offset + +align 16 +@@: + +if NUM_WORDS eq 1 + + mov x1, x0 + shr x1, 8 + MOVZXLO x3, x1 + MOVZXLO x2, x0 + shr x1, 8 + shr r0, 32 + xor x0, SRCDAT4 + CRC_XOR r0, x2, 3 + CRC_XOR r0, x3, 2 + MOVZXLO x2, x1 + shr x1, 8 + CRC_XOR r0, x2, 1 + CRC_XOR r0, x1, 0 + +else ; NUM_WORDS > 1 + +if NUM_WORDS ne 2 + k = 2 + while k lt NUM_WORDS + + LOAD_SRC_MULT4 x1, k + crc_op1 textequ + + if k eq 2 + if (NUM_WORDS and 1) + LOAD_SRC_MULT4 x7, NUM_WORDS ; aligned 32-bit + LOAD_SRC_MULT4 x6, NUM_WORDS + 1 ; aligned 32-bit + shl r6, 32 + else + LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit + crc_op1 textequ + endif + endif + table = 4 * (NUM_WORDS - 1 - k) + MOVZXLO x3, x1 + CRC_OP crc_op1, r7, x3, 3 + table + MOVZXHI x3, x1 + shr x1, 16 + CRC_XOR r6, x3, 2 + table + MOVZXLO x3, x1 + shr x1, 8 + CRC_XOR r7, x3, 1 + table + CRC_XOR r6, x1, 0 + table + k = k + 1 + endm + crc_op2 textequ + +else ; NUM_WORDS == 2 + LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit + crc_op2 textequ +endif ; NUM_WORDS == 2 + + MOVZXHI x3, x0 + MOVZXLO x2, x0 + mov r1, r0 + shr r1, 32 + shr x0, 16 + CRC_XOR r6, x2, NUM_SKIP_BYTES + 7 + CRC_OP crc_op2, r7, x3, NUM_SKIP_BYTES + 6 + MOVZXLO x2, x0 + MOVZXHI x5, x1 + MOVZXLO x3, x1 + shr x0, 8 + shr x1, 16 + CRC_XOR r7, x2, NUM_SKIP_BYTES + 5 + CRC_XOR r6, x3, NUM_SKIP_BYTES + 3 + CRC_XOR r7, x0, NUM_SKIP_BYTES + 4 + CRC_XOR r6, x5, NUM_SKIP_BYTES + 2 + MOVZXLO x2, x1 + shr x1, 8 + CRC_XOR r7, x2, NUM_SKIP_BYTES + 1 + CRC_MOV r0, x1, NUM_SKIP_BYTES + 0 + xor r0, r6 + xor r0, r7 + +endif ; NUM_WORDS > 1 + add rD, NUM_WORDS * 4 + jnc @B + + sub rN, src_rN_offset + add rD, rN + XOR_NEXT + add rN, NUM_BYTES_LIMIT - 1 + sub rN, rD + +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B +func_end: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 MY_ENDP + + else +; ================================================================== ; x86 (32-bit) -rD equ r1 -rN equ r7 +rD equ r7 +rN equ r1 rT equ r5 +xA equ x6 +xA_R equ r6 + +ifdef x64 + num_VAR equ r8 +else + crc_OFFS equ (REG_SIZE * 5) if (IS_CDECL gt 0) or (IS_LINUX gt 0) @@ -133,107 +251,273 @@ table_VAR equ [r4 + table_OFFS] num_VAR equ table_VAR endif +endif ; x64 -SRCDAT4 equ dword ptr [rD + rN * 1] +SRCDAT4 equ DWORD PTR [rN + rD * 1] + +CRC_1 macro op:req, dest:req, src:req, t:req, word_index:req + op dest, DWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t) + (word_index) * 4] +endm CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req - op0 dest0, DWORD PTR [rT + src * 8 + 0800h * t] - op1 dest1, DWORD PTR [rT + src * 8 + 0800h * t + 4] + CRC_1 op0, dest0, src, t, 0 + CRC_1 op1, dest1, src, t, 1 endm CRC_XOR macro dest0:req, dest1:req, src:req, t:req - CRC xor, xor, dest0, dest1, src, t + CRC xor, xor, dest0, dest1, src, t endm CRC1b macro - movzx x6, BYTE PTR [rD] - inc rD - movzx x3, x0_L - xor x6, x3 - shrd r0, r2, 8 - shr r2, 8 - CRC_XOR r0, r2, r6, 0 - dec rN -endm - -MY_PROLOG macro crc_end:req - MY_PUSH_4_REGS - - if (IS_CDECL gt 0) or (IS_LINUX gt 0) - proc_numParams = proc_numParams + 2 ; for ABI_LINUX - mov rN, [r4 + size_OFFS] - mov rD, [r4 + data_OFFS] + movzx xA, BYTE PTR [rD] + inc rD + MOVZXLO x3, x0 + xor xA, x3 + shrd x0, x2, 8 + shr x2, 8 + CRC_XOR x0, x2, xA, 0 + dec rN +endm + + +MY_PROLOG_BASE macro + MY_PUSH_4_REGS +ifdef x64 + mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7 + mov rT, REG_ABI_PARAM_3 ; r5 <- r9 / r1 + mov rN, REG_ABI_PARAM_2 ; r1 <- r8 / r2 + mov rD, REG_ABI_PARAM_1 ; r7 <- r2 / r6 + mov r2, r0 + shr r2, 32 + mov x0, x0 +else + if (IS_CDECL gt 0) or (IS_LINUX gt 0) + proc_numParams = proc_numParams + 2 ; for ABI_LINUX + mov rN, [r4 + size_OFFS] + mov rD, [r4 + data_OFFS] + else + mov rD, REG_ABI_PARAM_0 ; r7 <- r1 : (data) + mov rN, REG_ABI_PARAM_1 ; r1 <- r2 : (size) + endif + mov x0, [r4 + crc_OFFS] + mov x2, [r4 + crc_OFFS + 4] + mov rT, table_VAR +endif +endm + + +MY_EPILOG_BASE macro crc_end:req, func_end:req +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B +func_end: +ifdef x64 + shl r2, 32 + xor r0, r2 +endif + MY_POP_4_REGS +endm + + +; ALIGN_MASK is 3 or 7 bytes alignment: +ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4) + +if (NUM_WORDS eq 1) + +NUM_BYTES_LIMIT_T4 equ (NUM_WORDS * 4 + 4) + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5 + MY_PROLOG_BASE + + cmp rN, NUM_BYTES_LIMIT_T4 + ALIGN_MASK + jb crc_end_4 +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, [rD] + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT_T4 - 1)] + sub rD, rN + add rN, 4 + + MOVZXLO xA, x0 +align 16 +@@: + mov x3, SRCDAT4 + xor x3, x2 + shr x0, 8 + CRC xor, mov, x3, x2, xA, 3 + MOVZXLO xA, x0 + shr x0, 8 + ; MOVZXHI xA, x0 + ; shr x0, 16 + CRC_XOR x3, x2, xA, 2 + + MOVZXLO xA, x0 + shr x0, 8 + CRC_XOR x3, x2, xA, 1 + CRC_XOR x3, x2, x0, 0 + MOVZXLO xA, x3 + mov x0, x3 + + add rD, 4 + jnc @B + + sub rN, 4 + add rD, rN + xor x0, [rD] + add rN, NUM_BYTES_LIMIT_T4 - 1 + sub rN, rD + MY_EPILOG_BASE crc_end_4, func_end_4 +MY_ENDP + +else ; NUM_WORDS > 1 + +SHR_X macro x, imm + shr x, imm +endm + + +ITER_1 macro v0, v1, a, off + MOVZXLO xA, a + SHR_X a, 8 + CRC_XOR v0, v1, xA, off +endm + + +ITER_4 macro v0, v1, a, off +if 0 eq 0 + ITER_1 v0, v1, a, off + 3 + ITER_1 v0, v1, a, off + 2 + ITER_1 v0, v1, a, off + 1 + CRC_XOR v0, v1, a, off +elseif 0 eq 0 + MOVZXLO xA, a + CRC_XOR v0, v1, xA, off + 3 + mov xA, a + ror a, 16 ; 32-bit ror + shr xA, 24 + CRC_XOR v0, v1, xA, off + MOVZXLO xA, a + SHR_X a, 24 + CRC_XOR v0, v1, xA, off + 1 + CRC_XOR v0, v1, a, off + 2 +else + ; MOVZXHI provides smaller code, but MOVZX_HI_BYTE is not fast instruction + MOVZXLO xA, a + CRC_XOR v0, v1, xA, off + 3 + MOVZXHI xA, a + SHR_X a, 16 + CRC_XOR v0, v1, xA, off + 2 + MOVZXLO xA, a + SHR_X a, 8 + CRC_XOR v0, v1, xA, off + 1 + CRC_XOR v0, v1, a, off +endif +endm + + + +ITER_1_PAIR macro v0, v1, a0, a1, off + ITER_1 v0, v1, a0, off + 4 + ITER_1 v0, v1, a1, off +endm + +src_rD_offset equ 8 +STEP_SIZE equ (NUM_WORDS * 4) + +ITER_12_NEXT macro op, index, v0, v1 + op v0, DWORD PTR [rD + (index + 1) * STEP_SIZE - src_rD_offset] + op v1, DWORD PTR [rD + (index + 1) * STEP_SIZE + 4 - src_rD_offset] +endm + +ITER_12 macro index, a0, a1, v0, v1 + + if NUM_SKIP_BYTES eq 0 + ITER_12_NEXT mov, index, v0, v1 else - mov rN, r2 + k = 0 + while k lt NUM_SKIP_BYTES + movzx xA, BYTE PTR [rD + (index) * STEP_SIZE + k + 8 - src_rD_offset] + if k eq 0 + CRC mov, mov, v0, v1, xA, NUM_SKIP_BYTES - 1 - k + else + CRC_XOR v0, v1, xA, NUM_SKIP_BYTES - 1 - k + endif + k = k + 1 + endm + ITER_12_NEXT xor, index, v0, v1 endif - mov x0, [r4 + crc_OFFS] - mov x2, [r4 + crc_OFFS + 4] - mov rT, table_VAR - test rN, rN - jz crc_end - @@: - test rD, 3 - jz @F - CRC1b - jnz @B - @@: - cmp rN, 8 - jb crc_end - add rN, rD - - mov num_VAR, rN - - sub rN, 4 - and rN, NOT 3 - sub rD, rN - xor r0, SRCDAT4 - add rN, 4 -endm - -MY_EPILOG macro crc_end:req - sub rN, 4 - xor r0, SRCDAT4 - - mov rD, rN - mov rN, num_VAR - sub rN, rD - crc_end: - test rN, rN - jz @F - CRC1b - jmp crc_end - @@: - MY_POP_4_REGS -endm - -MY_PROC XzCrc64UpdateT4, 5 - MY_PROLOG crc_end_4 - movzx x6, x0_L - align 16 - main_loop_4: - mov r3, SRCDAT4 - xor r3, r2 - - CRC xor, mov, r3, r2, r6, 3 - movzx x6, x0_H - shr r0, 16 - CRC_XOR r3, r2, r6, 2 - - movzx x6, x0_L - movzx x0, x0_H - CRC_XOR r3, r2, r6, 1 - CRC_XOR r3, r2, r0, 0 - movzx x6, x3_L - mov r0, r3 +if 0 eq 0 + ITER_4 v0, v1, a0, NUM_SKIP_BYTES + 4 + ITER_4 v0, v1, a1, NUM_SKIP_BYTES +else ; interleave version is faster/slower for different processors + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 3 + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 2 + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 1 + CRC_XOR v0, v1, a0, NUM_SKIP_BYTES + 4 + CRC_XOR v0, v1, a1, NUM_SKIP_BYTES +endif +endm - add rD, 4 - jnz main_loop_4 +; we use (UNROLL_CNT > 1) to reduce read ports pressure (num_VAR reads) +UNROLL_CNT equ (2 * 1) +NUM_BYTES_LIMIT equ (STEP_SIZE * UNROLL_CNT + 8) + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5 + MY_PROLOG_BASE + + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end_12 +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, [rD] + xor x2, [rD + 4] + add rD, src_rD_offset + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + mov num_VAR, rN + +align 16 +@@: + i = 0 + rept UNROLL_CNT + if (i and 1) eq 0 + ITER_12 i, x0, x2, x1, x3 + else + ITER_12 i, x1, x3, x0, x2 + endif + i = i + 1 + endm + + if (UNROLL_CNT and 1) + mov x0, x1 + mov x2, x3 + endif + add rD, STEP_SIZE * UNROLL_CNT + cmp rD, num_VAR + jb @B + + mov rN, num_VAR + add rN, NUM_BYTES_LIMIT - 1 + sub rN, rD + sub rD, src_rD_offset + xor x0, [rD] + xor x2, [rD + 4] - MY_EPILOG crc_end_4 + MY_EPILOG_BASE crc_end_12, func_end_12 MY_ENDP +endif ; (NUM_WORDS > 1) endif ; ! x64 - end diff -Nru 7zip-22.01+dfsg/C/7z.h 7zip-22.01+really25.01+dfsg/C/7z.h --- 7zip-22.01+dfsg/C/7z.h 2019-07-02 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7z.h 2023-04-02 11:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7z.h -- 7z interface -2018-07-02 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_H -#define __7Z_H +#ifndef ZIP7_INC_7Z_H +#define ZIP7_INC_7Z_H #include "7zTypes.h" @@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *stream, UInt64 startPos, + ILookInStreamPtr stream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAllocPtr allocMain); @@ -174,7 +174,7 @@ SRes SzArEx_Extract( const CSzArEx *db, - ILookInStream *inStream, + ILookInStreamPtr inStream, UInt32 fileIndex, /* index of file */ UInt32 *blockIndex, /* index of solid block */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ @@ -196,7 +196,7 @@ SZ_ERROR_FAIL */ -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/7zAlloc.c 7zip-22.01+really25.01+dfsg/C/7zAlloc.c --- 7zip-22.01+dfsg/C/7zAlloc.c 2017-04-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zAlloc.c 2023-03-04 09:00:00.000000000 +0000 @@ -1,5 +1,5 @@ -/* 7zAlloc.c -- Allocation functions -2017-04-03 : Igor Pavlov : Public domain */ +/* 7zAlloc.c -- Allocation functions for 7z processing +2023-03-04 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,74 +7,83 @@ #include "7zAlloc.h" -/* #define _SZ_ALLOC_DEBUG */ -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +/* #define SZ_ALLOC_DEBUG */ +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ -#ifdef _SZ_ALLOC_DEBUG +#ifdef SZ_ALLOC_DEBUG +/* #ifdef _WIN32 -#include +#include "7zWindows.h" #endif +*/ #include -int g_allocCount = 0; -int g_allocCountTemp = 0; +static int g_allocCount = 0; +static int g_allocCountTemp = 0; +static void Print_Alloc(const char *s, size_t size, int *counter) +{ + const unsigned size2 = (unsigned)size; + fprintf(stderr, "\n%s count = %10d : %10u bytes; ", s, *counter, size2); + (*counter)++; +} +static void Print_Free(const char *s, int *counter) +{ + (*counter)--; + fprintf(stderr, "\n%s count = %10d", s, *counter); +} #endif void *SzAlloc(ISzAllocPtr p, size_t size) { - UNUSED_VAR(p); + UNUSED_VAR(p) if (size == 0) return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount); - g_allocCount++; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc", size, &g_allocCount); #endif return malloc(size); } void SzFree(ISzAllocPtr p, void *address) { - UNUSED_VAR(p); - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCount--; - fprintf(stderr, "\nFree; count = %10d", g_allocCount); - } + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free ", &g_allocCount); #endif free(address); } void *SzAllocTemp(ISzAllocPtr p, size_t size) { - UNUSED_VAR(p); + UNUSED_VAR(p) if (size == 0) return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp); - g_allocCountTemp++; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc_temp", size, &g_allocCountTemp); + /* #ifdef _WIN32 return HeapAlloc(GetProcessHeap(), 0, size); #endif + */ #endif return malloc(size); } void SzFreeTemp(ISzAllocPtr p, void *address) { - UNUSED_VAR(p); - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCountTemp--; - fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); - } + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free_temp ", &g_allocCountTemp); + /* #ifdef _WIN32 HeapFree(GetProcessHeap(), 0, address); return; #endif + */ #endif free(address); } diff -Nru 7zip-22.01+dfsg/C/7zAlloc.h 7zip-22.01+really25.01+dfsg/C/7zAlloc.h --- 7zip-22.01+dfsg/C/7zAlloc.h 2017-04-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zAlloc.h 2023-03-04 09:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7zAlloc.h -- Allocation functions -2017-04-03 : Igor Pavlov : Public domain */ +2023-03-04 : Igor Pavlov : Public domain */ -#ifndef __7Z_ALLOC_H -#define __7Z_ALLOC_H +#ifndef ZIP7_INC_7Z_ALLOC_H +#define ZIP7_INC_7Z_ALLOC_H #include "7zTypes.h" diff -Nru 7zip-22.01+dfsg/C/7zArcIn.c 7zip-22.01+really25.01+dfsg/C/7zArcIn.c --- 7zip-22.01+dfsg/C/7zArcIn.c 2021-02-09 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zArcIn.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* 7zArcIn.c -- 7z Input functions -2021-02-09 : Igor Pavlov : Public domain */ +2023-09-07 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -10,10 +10,11 @@ #include "7zCrc.h" #include "CpuArch.h" -#define MY_ALLOC(T, p, size, alloc) { \ - if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } +#define MY_ALLOC(T, p, size, alloc) \ + { if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } -#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } +#define MY_ALLOC_ZE(T, p, size, alloc) \ + { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } #define MY_ALLOC_AND_CPY(to, size, from, alloc) \ { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); } @@ -58,7 +59,7 @@ const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; -#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } +#define SzBitUi32s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) { @@ -69,8 +70,8 @@ } else { - MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc); - MY_ALLOC(UInt32, p->Vals, num, alloc); + MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc) + MY_ALLOC(UInt32, p->Vals, num, alloc) } return SZ_OK; } @@ -81,7 +82,7 @@ ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; } -#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } +#define SzBitUi64s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) { @@ -96,7 +97,7 @@ p->NumFolders = 0; p->PackPositions = NULL; - SzBitUi32s_Init(&p->FolderCRCs); + SzBitUi32s_INIT(&p->FolderCRCs) p->FoCodersOffsets = NULL; p->FoStartPackStreamIndex = NULL; @@ -142,11 +143,11 @@ p->FileNameOffsets = NULL; p->FileNames = NULL; - SzBitUi32s_Init(&p->CRCs); - SzBitUi32s_Init(&p->Attribs); - // SzBitUi32s_Init(&p->Parents); - SzBitUi64s_Init(&p->MTime); - SzBitUi64s_Init(&p->CTime); + SzBitUi32s_INIT(&p->CRCs) + SzBitUi32s_INIT(&p->Attribs) + // SzBitUi32s_INIT(&p->Parents) + SzBitUi64s_INIT(&p->MTime) + SzBitUi64s_INIT(&p->CTime) } void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) @@ -180,11 +181,20 @@ return 1; } -#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; } +#define SzData_CLEAR(p) { (p)->Data = NULL; (p)->Size = 0; } + +#define SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) \ + (_sd_)->Size--; dest = *(_sd_)->Data++; + +#define SZ_READ_BYTE_SD(_sd_, dest) \ + if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; \ + SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) -#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++; #define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) -#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++; + +#define SZ_READ_BYTE_2(dest) \ + if (sd.Size == 0) return SZ_ERROR_ARCHIVE; \ + sd.Size--; dest = *sd.Data++; #define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } #define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } @@ -192,25 +202,25 @@ #define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \ dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4); -static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) +static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) { Byte firstByte, mask; unsigned i; UInt32 v; - SZ_READ_BYTE(firstByte); + SZ_READ_BYTE(firstByte) if ((firstByte & 0x80) == 0) { *value = firstByte; return SZ_OK; } - SZ_READ_BYTE(v); + SZ_READ_BYTE(v) if ((firstByte & 0x40) == 0) { *value = (((UInt32)firstByte & 0x3F) << 8) | v; return SZ_OK; } - SZ_READ_BYTE(mask); + SZ_READ_BYTE(mask) *value = v | ((UInt32)mask << 8); mask = 0x20; for (i = 2; i < 8; i++) @@ -218,11 +228,11 @@ Byte b; if ((firstByte & mask) == 0) { - UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); + const UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); *value |= (highPart << (8 * i)); return SZ_OK; } - SZ_READ_BYTE(b); + SZ_READ_BYTE(b) *value |= ((UInt64)b << (8 * i)); mask >>= 1; } @@ -230,7 +240,7 @@ } -static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) +static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) { Byte firstByte; UInt64 value64; @@ -244,7 +254,7 @@ sd->Size--; return SZ_OK; } - RINOK(ReadNumber(sd, &value64)); + RINOK(ReadNumber(sd, &value64)) if (value64 >= (UInt32)0x80000000 - 1) return SZ_ERROR_UNSUPPORTED; if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4))) @@ -258,10 +268,10 @@ static SRes SkipData(CSzData *sd) { UInt64 size; - RINOK(ReadNumber(sd, &size)); + RINOK(ReadNumber(sd, &size)) if (size > sd->Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) return SZ_OK; } @@ -270,28 +280,28 @@ for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == id) return SZ_OK; if (type == k7zIdEnd) return SZ_ERROR_ARCHIVE; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } } static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v) { - UInt32 numBytes = (numItems + 7) >> 3; + const UInt32 numBytes = (numItems + 7) >> 3; if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; *v = sd->Data; - SKIP_DATA(sd, numBytes); + SKIP_DATA(sd, numBytes) return SZ_OK; } static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) { - Byte b = 0; + unsigned b = 0; unsigned m = 0; UInt32 sum = 0; for (; numItems != 0; numItems--) @@ -302,53 +312,53 @@ m = 8; } m--; - sum += ((b >> m) & 1); + sum += (UInt32)((b >> m) & 1); } return sum; } -static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) +static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) { Byte allAreDefined; Byte *v2; - UInt32 numBytes = (numItems + 7) >> 3; + const UInt32 numBytes = (numItems + 7) >> 3; *v = NULL; - SZ_READ_BYTE(allAreDefined); + SZ_READ_BYTE(allAreDefined) if (numBytes == 0) return SZ_OK; if (allAreDefined == 0) { if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; - MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc); - SKIP_DATA(sd, numBytes); + MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc) + SKIP_DATA(sd, numBytes) return SZ_OK; } - MY_ALLOC(Byte, *v, numBytes, alloc); + MY_ALLOC(Byte, *v, numBytes, alloc) v2 = *v; memset(v2, 0xFF, (size_t)numBytes); { - unsigned numBits = (unsigned)numItems & 7; + const unsigned numBits = (unsigned)numItems & 7; if (numBits != 0) v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); } return SZ_OK; } -static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { UInt32 i; CSzData sd; UInt32 *vals; const Byte *defs; - MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc); + MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc) sd = *sd2; defs = crcs->Defs; vals = crcs->Vals; for (i = 0; i < numItems; i++) if (SzBitArray_Check(defs, i)) { - SZ_READ_32(vals[i]); + SZ_READ_32(vals[i]) } else vals[i] = 0; @@ -359,7 +369,7 @@ static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { SzBitUi32s_Free(crcs, alloc); - RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); + RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)) return ReadUi32s(sd, numItems, crcs, alloc); } @@ -367,36 +377,36 @@ { Byte allAreDefined; UInt32 numDefined = numItems; - SZ_READ_BYTE(allAreDefined); + SZ_READ_BYTE(allAreDefined) if (!allAreDefined) { - size_t numBytes = (numItems + 7) >> 3; + const size_t numBytes = (numItems + 7) >> 3; if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; numDefined = CountDefinedBits(sd->Data, numItems); - SKIP_DATA(sd, numBytes); + SKIP_DATA(sd, numBytes) } if (numDefined > (sd->Size >> 2)) return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, (size_t)numDefined * 4); + SKIP_DATA(sd, (size_t)numDefined * 4) return SZ_OK; } static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) { - RINOK(SzReadNumber32(sd, &p->NumPackStreams)); + RINOK(SzReadNumber32(sd, &p->NumPackStreams)) - RINOK(WaitId(sd, k7zIdSize)); - MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc); + RINOK(WaitId(sd, k7zIdSize)) + MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc) { UInt64 sum = 0; UInt32 i; - UInt32 numPackStreams = p->NumPackStreams; + const UInt32 numPackStreams = p->NumPackStreams; for (i = 0; i < numPackStreams; i++) { UInt64 packSize; p->PackPositions[i] = sum; - RINOK(ReadNumber(sd, &packSize)); + RINOK(ReadNumber(sd, &packSize)) sum += packSize; if (sum < packSize) return SZ_ERROR_ARCHIVE; @@ -407,16 +417,16 @@ for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) return SZ_OK; if (type == k7zIdCRC) { /* CRC of packed streams is unused now */ - RINOK(SkipBitUi32s(sd, p->NumPackStreams)); + RINOK(SkipBitUi32s(sd, p->NumPackStreams)) continue; } - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } } @@ -442,7 +452,7 @@ f->NumPackStreams = 0; f->UnpackStream = 0; - RINOK(SzReadNumber32(sd, &numCoders)); + RINOK(SzReadNumber32(sd, &numCoders)) if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) return SZ_ERROR_UNSUPPORTED; @@ -453,7 +463,7 @@ unsigned idSize, j; UInt64 id; - SZ_READ_BYTE(mainByte); + SZ_READ_BYTE(mainByte) if ((mainByte & 0xC0) != 0) return SZ_ERROR_UNSUPPORTED; @@ -481,12 +491,12 @@ { UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numStreams > k_NumCodersStreams_in_Folder_MAX) return SZ_ERROR_UNSUPPORTED; coder->NumStreams = (Byte)numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numStreams != 1) return SZ_ERROR_UNSUPPORTED; } @@ -499,7 +509,7 @@ if ((mainByte & 0x20) != 0) { UInt32 propsSize = 0; - RINOK(SzReadNumber32(sd, &propsSize)); + RINOK(SzReadNumber32(sd, &propsSize)) if (propsSize > sd->Size) return SZ_ERROR_ARCHIVE; if (propsSize >= 0x80) @@ -549,12 +559,12 @@ { CSzBond *bp = f->Bonds + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); + RINOK(SzReadNumber32(sd, &bp->InIndex)) if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex]) return SZ_ERROR_ARCHIVE; streamUsed[bp->InIndex] = True; - RINOK(SzReadNumber32(sd, &bp->OutIndex)); + RINOK(SzReadNumber32(sd, &bp->OutIndex)) if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex]) return SZ_ERROR_ARCHIVE; coderUsed[bp->OutIndex] = True; @@ -584,7 +594,7 @@ for (i = 0; i < numPackStreams; i++) { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; @@ -598,7 +608,7 @@ } -static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) +static Z7_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) { CSzData sd; sd = *sd2; @@ -606,7 +616,7 @@ { Byte firstByte, mask; unsigned i; - SZ_READ_BYTE_2(firstByte); + SZ_READ_BYTE_2(firstByte) if ((firstByte & 0x80) == 0) continue; if ((firstByte & 0x40) == 0) @@ -622,7 +632,7 @@ mask >>= 1; if (i > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, i); + SKIP_DATA2(sd, i) } *sd2 = sd; return SZ_OK; @@ -645,30 +655,30 @@ const Byte *startBufPtr; Byte external; - RINOK(WaitId(sd2, k7zIdFolder)); + RINOK(WaitId(sd2, k7zIdFolder)) - RINOK(SzReadNumber32(sd2, &numFolders)); + RINOK(SzReadNumber32(sd2, &numFolders)) if (numFolders > numFoldersMax) return SZ_ERROR_UNSUPPORTED; p->NumFolders = numFolders; - SZ_READ_BYTE_SD(sd2, external); + SZ_READ_BYTE_SD(sd2, external) if (external == 0) sd = *sd2; else { UInt32 index; - RINOK(SzReadNumber32(sd2, &index)); + RINOK(SzReadNumber32(sd2, &index)) if (index >= numTempBufs) return SZ_ERROR_ARCHIVE; sd.Data = tempBufs[index].data; sd.Size = tempBufs[index].size; } - MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc); - MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc); - MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc); - MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc); + MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc) + MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc) startBufPtr = sd.Data; @@ -681,7 +691,7 @@ p->FoCodersOffsets[fo] = (size_t)(sd.Data - startBufPtr); - RINOK(SzReadNumber32(&sd, &numCoders)); + RINOK(SzReadNumber32(&sd, &numCoders)) if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) return SZ_ERROR_UNSUPPORTED; @@ -691,7 +701,7 @@ unsigned idSize; UInt32 coderInStreams; - SZ_READ_BYTE_2(mainByte); + SZ_READ_BYTE_2(mainByte) if ((mainByte & 0xC0) != 0) return SZ_ERROR_UNSUPPORTED; idSize = (mainByte & 0xF); @@ -699,15 +709,15 @@ return SZ_ERROR_UNSUPPORTED; if (idSize > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, idSize); + SKIP_DATA2(sd, idSize) coderInStreams = 1; if ((mainByte & 0x10) != 0) { UInt32 coderOutStreams; - RINOK(SzReadNumber32(&sd, &coderInStreams)); - RINOK(SzReadNumber32(&sd, &coderOutStreams)); + RINOK(SzReadNumber32(&sd, &coderInStreams)) + RINOK(SzReadNumber32(&sd, &coderOutStreams)) if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1) return SZ_ERROR_UNSUPPORTED; } @@ -717,10 +727,10 @@ if ((mainByte & 0x20) != 0) { UInt32 propsSize; - RINOK(SzReadNumber32(&sd, &propsSize)); + RINOK(SzReadNumber32(&sd, &propsSize)) if (propsSize > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, propsSize); + SKIP_DATA2(sd, propsSize) } } @@ -734,7 +744,7 @@ Byte coderUsed[k_Scan_NumCoders_MAX]; UInt32 i; - UInt32 numBonds = numCoders - 1; + const UInt32 numBonds = numCoders - 1; if (numInStreams < numBonds) return SZ_ERROR_ARCHIVE; @@ -750,12 +760,12 @@ { UInt32 index; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numCoders || coderUsed[index]) return SZ_ERROR_ARCHIVE; coderUsed[index] = True; @@ -767,7 +777,7 @@ for (i = 0; i < numPackStreams; i++) { UInt32 index; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; @@ -802,7 +812,7 @@ const size_t dataSize = (size_t)(sd.Data - startBufPtr); p->FoStartPackStreamIndex[fo] = packStreamIndex; p->FoCodersOffsets[fo] = dataSize; - MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc); + MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc) } if (external != 0) @@ -812,21 +822,21 @@ sd = *sd2; } - RINOK(WaitId(&sd, k7zIdCodersUnpackSize)); + RINOK(WaitId(&sd, k7zIdCodersUnpackSize)) - MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc); + MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc) { UInt32 i; for (i = 0; i < numCodersOutStreams; i++) { - RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)); + RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)) } } for (;;) { UInt64 type; - RINOK(ReadID(&sd, &type)); + RINOK(ReadID(&sd, &type)) if (type == k7zIdEnd) { *sd2 = sd; @@ -834,10 +844,10 @@ } if (type == k7zIdCRC) { - RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)); + RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)) continue; } - RINOK(SkipData(&sd)); + RINOK(SkipData(&sd)) } } @@ -862,13 +872,13 @@ { UInt64 type = 0; UInt32 numSubDigests = 0; - UInt32 numFolders = p->NumFolders; + const UInt32 numFolders = p->NumFolders; UInt32 numUnpackStreams = numFolders; UInt32 numUnpackSizesInData = 0; for (;;) { - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdNumUnpackStream) { UInt32 i; @@ -878,7 +888,7 @@ for (i = 0; i < numFolders; i++) { UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numUnpackStreams > numUnpackStreams + numStreams) return SZ_ERROR_UNSUPPORTED; numUnpackStreams += numStreams; @@ -892,7 +902,7 @@ } if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } if (!ssi->sdNumSubStreams.Data) @@ -908,9 +918,9 @@ if (type == k7zIdSize) { ssi->sdSizes.Data = sd->Data; - RINOK(SkipNumbers(sd, numUnpackSizesInData)); + RINOK(SkipNumbers(sd, numUnpackSizesInData)) ssi->sdSizes.Size = (size_t)(sd->Data - ssi->sdSizes.Data); - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } for (;;) @@ -920,14 +930,14 @@ if (type == k7zIdCRC) { ssi->sdCRCs.Data = sd->Data; - RINOK(SkipBitUi32s(sd, numSubDigests)); + RINOK(SkipBitUi32s(sd, numSubDigests)) ssi->sdCRCs.Size = (size_t)(sd->Data - ssi->sdCRCs.Data); } else { - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } } @@ -940,31 +950,31 @@ { UInt64 type; - SzData_Clear(&ssi->sdSizes); - SzData_Clear(&ssi->sdCRCs); - SzData_Clear(&ssi->sdNumSubStreams); + SzData_CLEAR(&ssi->sdSizes) + SzData_CLEAR(&ssi->sdCRCs) + SzData_CLEAR(&ssi->sdNumSubStreams) *dataOffset = 0; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdPackInfo) { - RINOK(ReadNumber(sd, dataOffset)); + RINOK(ReadNumber(sd, dataOffset)) if (*dataOffset > p->RangeLimit) return SZ_ERROR_ARCHIVE; - RINOK(ReadPackInfo(p, sd, alloc)); + RINOK(ReadPackInfo(p, sd, alloc)) if (p->PackPositions[p->NumPackStreams] > p->RangeLimit - *dataOffset) return SZ_ERROR_ARCHIVE; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdUnpackInfo) { - RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)); - RINOK(ReadID(sd, &type)); + RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)) + RINOK(ReadID(sd, &type)) } if (type == k7zIdSubStreamsInfo) { - RINOK(ReadSubStreamsInfo(p, sd, ssi)); - RINOK(ReadID(sd, &type)); + RINOK(ReadSubStreamsInfo(p, sd, ssi)) + RINOK(ReadID(sd, &type)) } else { @@ -976,7 +986,7 @@ } static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, + ILookInStreamPtr inStream, CSzData *sd, CBuf *tempBufs, UInt32 numFoldersMax, @@ -988,7 +998,7 @@ UInt32 fo; CSubStreamInfo ssi; - RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)); + RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)) dataStartPos += baseOffset; if (p->NumFolders == 0) @@ -1000,7 +1010,7 @@ for (fo = 0; fo < p->NumFolders; fo++) { CBuf *tempBuf = tempBufs + fo; - UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); + const UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); if ((size_t)unpackSize != unpackSize) return SZ_ERROR_MEM; if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) @@ -1010,8 +1020,8 @@ for (fo = 0; fo < p->NumFolders; fo++) { const CBuf *tempBuf = tempBufs + fo; - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)); + RINOK(LookInStream_SeekTo(inStream, dataStartPos)) + RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)) } return SZ_OK; @@ -1046,7 +1056,7 @@ return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; } -static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, +static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, CSzData *sd2, const CBuf *tempBufs, UInt32 numTempBufs, ISzAllocPtr alloc) @@ -1057,22 +1067,22 @@ Byte *defs; Byte external; - RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)); + RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)) - SZ_READ_BYTE_SD(sd2, external); + SZ_READ_BYTE_SD(sd2, external) if (external == 0) sd = *sd2; else { UInt32 index; - RINOK(SzReadNumber32(sd2, &index)); + RINOK(SzReadNumber32(sd2, &index)) if (index >= numTempBufs) return SZ_ERROR_ARCHIVE; sd.Data = tempBufs[index].data; sd.Size = tempBufs[index].size; } - MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc); + MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc) vals = p->Vals; defs = p->Defs; for (i = 0; i < num; i++) @@ -1082,7 +1092,7 @@ return SZ_ERROR_ARCHIVE; vals[i].Low = GetUi32(sd.Data); vals[i].High = GetUi32(sd.Data + 4); - SKIP_DATA2(sd, 8); + SKIP_DATA2(sd, 8) } else vals[i].High = vals[i].Low = 0; @@ -1100,7 +1110,7 @@ static SRes SzReadHeader2( CSzArEx *p, /* allocMain */ CSzData *sd, - ILookInStream *inStream, + ILookInStreamPtr inStream, CBuf *tempBufs, UInt32 *numTempBufs, ISzAllocPtr allocMain, ISzAllocPtr allocTemp @@ -1111,26 +1121,26 @@ { UInt64 type; - SzData_Clear(&ssi.sdSizes); - SzData_Clear(&ssi.sdCRCs); - SzData_Clear(&ssi.sdNumSubStreams); + SzData_CLEAR(&ssi.sdSizes) + SzData_CLEAR(&ssi.sdCRCs) + SzData_CLEAR(&ssi.sdNumSubStreams) ssi.NumSubDigests = 0; ssi.NumTotalSubStreams = 0; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdArchiveProperties) { for (;;) { UInt64 type2; - RINOK(ReadID(sd, &type2)); + RINOK(ReadID(sd, &type2)) if (type2 == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdAdditionalStreamsInfo) @@ -1148,15 +1158,15 @@ if (res != SZ_OK) return res; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, - &p->dataPos, &ssi, allocMain)); + &p->dataPos, &ssi, allocMain)) p->dataPos += p->startPosAfterHeader; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdEnd) @@ -1174,23 +1184,23 @@ const Byte *emptyStreams = NULL; const Byte *emptyFiles = NULL; - RINOK(SzReadNumber32(sd, &numFiles)); + RINOK(SzReadNumber32(sd, &numFiles)) p->NumFiles = numFiles; for (;;) { UInt64 type; UInt64 size; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) break; - RINOK(ReadNumber(sd, &size)); + RINOK(ReadNumber(sd, &size)) if (size > sd->Size) return SZ_ERROR_ARCHIVE; if (type >= ((UInt32)1 << 8)) { - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) } else switch ((unsigned)type) { @@ -1200,7 +1210,7 @@ const Byte *namesData; Byte external; - SZ_READ_BYTE(external); + SZ_READ_BYTE(external) if (external == 0) { namesSize = (size_t)size - 1; @@ -1209,7 +1219,7 @@ else { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; namesData = (tempBufs)[index].data; @@ -1218,25 +1228,25 @@ if ((namesSize & 1) != 0) return SZ_ERROR_ARCHIVE; - MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); - MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain); + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain) + MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain) RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) if (external == 0) { - SKIP_DATA(sd, namesSize); + SKIP_DATA(sd, namesSize) } break; } case k7zIdEmptyStream: { - RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); + RINOK(RememberBitVector(sd, numFiles, &emptyStreams)) numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); emptyFiles = NULL; break; } case k7zIdEmptyFile: { - RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)); + RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)) break; } case k7zIdWinAttrib: @@ -1245,22 +1255,22 @@ CSzData sdSwitch; CSzData *sdPtr; SzBitUi32s_Free(&p->Attribs, allocMain); - RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)); + RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)) - SZ_READ_BYTE(external); + SZ_READ_BYTE(external) if (external == 0) sdPtr = sd; else { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; sdSwitch.Data = (tempBufs)[index].data; sdSwitch.Size = (tempBufs)[index].size; sdPtr = &sdSwitch; } - RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)); + RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)) break; } /* @@ -1273,11 +1283,11 @@ break; } */ - case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; - case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; + case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; + case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; default: { - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) } } } @@ -1288,10 +1298,10 @@ for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } { @@ -1303,40 +1313,37 @@ UInt64 unpackPos = 0; const Byte *digestsDefs = NULL; const Byte *digestsVals = NULL; - UInt32 digestsValsIndex = 0; - UInt32 digestIndex; - Byte allDigestsDefined = 0; + UInt32 digestIndex = 0; Byte isDirMask = 0; Byte crcMask = 0; Byte mask = 0x80; - MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain); - MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain); - MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain); - MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain); + MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain) + MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain) + MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain) + MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain) - RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)); + RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)) if (ssi.sdCRCs.Size != 0) { - SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined); + Byte allDigestsDefined = 0; + SZ_READ_BYTE_SD_NOCHECK(&ssi.sdCRCs, allDigestsDefined) if (allDigestsDefined) digestsVals = ssi.sdCRCs.Data; else { - size_t numBytes = (ssi.NumSubDigests + 7) >> 3; + const size_t numBytes = (ssi.NumSubDigests + 7) >> 3; digestsDefs = ssi.sdCRCs.Data; digestsVals = digestsDefs + numBytes; } } - digestIndex = 0; - for (i = 0; i < numFiles; i++, mask >>= 1) { if (mask == 0) { - UInt32 byteIndex = (i - 1) >> 3; + const UInt32 byteIndex = (i - 1) >> 3; p->IsDirs[byteIndex] = isDirMask; p->CRCs.Defs[byteIndex] = crcMask; isDirMask = 0; @@ -1374,18 +1381,17 @@ numSubStreams = 1; if (ssi.sdNumSubStreams.Data) { - RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) } remSubStreams = numSubStreams; if (numSubStreams != 0) break; { - UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); unpackPos += folderUnpackSize; if (unpackPos < folderUnpackSize) return SZ_ERROR_ARCHIVE; } - folderIndex++; } } @@ -1397,47 +1403,44 @@ if (--remSubStreams == 0) { - UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); - UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; if (folderUnpackSize < unpackPos - startFolderUnpackPos) return SZ_ERROR_ARCHIVE; unpackPos = startFolderUnpackPos + folderUnpackSize; if (unpackPos < folderUnpackSize) return SZ_ERROR_ARCHIVE; - if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i)) + if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex)) { p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; crcMask |= mask; } - else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) - { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; - crcMask |= mask; - } - folderIndex++; } else { UInt64 v; - RINOK(ReadNumber(&ssi.sdSizes, &v)); + RINOK(ReadNumber(&ssi.sdSizes, &v)) unpackPos += v; if (unpackPos < v) return SZ_ERROR_ARCHIVE; - if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) + } + if ((crcMask & mask) == 0 && digestsVals) + { + if (!digestsDefs || SzBitArray_Check(digestsDefs, digestIndex)) { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; + p->CRCs.Vals[i] = GetUi32(digestsVals); + digestsVals += 4; crcMask |= mask; } + digestIndex++; } } if (mask != 0x80) { - UInt32 byteIndex = (i - 1) >> 3; + const UInt32 byteIndex = (i - 1) >> 3; p->IsDirs[byteIndex] = isDirMask; p->CRCs.Defs[byteIndex] = crcMask; } @@ -1454,7 +1457,7 @@ break; if (!ssi.sdNumSubStreams.Data) return SZ_ERROR_ARCHIVE; - RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) if (numSubStreams != 0) return SZ_ERROR_ARCHIVE; /* @@ -1479,7 +1482,7 @@ static SRes SzReadHeader( CSzArEx *p, CSzData *sd, - ILookInStream *inStream, + ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { @@ -1498,7 +1501,7 @@ for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) Buf_Free(tempBufs + i, allocTemp); - RINOK(res); + RINOK(res) if (sd->Size != 0) return SZ_ERROR_FAIL; @@ -1508,7 +1511,7 @@ static SRes SzArEx_Open2( CSzArEx *p, - ILookInStream *inStream, + ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { @@ -1521,9 +1524,9 @@ SRes res; startArcPos = 0; - RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)) - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)) if (!TestSignatureCandidate(header)) return SZ_ERROR_NO_ARCHIVE; @@ -1552,14 +1555,14 @@ { Int64 pos = 0; - RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)); + RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)) if ((UInt64)pos < (UInt64)startArcPos + nextHeaderOffset || (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset || (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) return SZ_ERROR_INPUT_EOF; } - RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset)); + RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset)) if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) return SZ_ERROR_MEM; @@ -1634,10 +1637,10 @@ } -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + const SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) SzArEx_Free(p, allocMain); return res; @@ -1646,7 +1649,7 @@ SRes SzArEx_Extract( const CSzArEx *p, - ILookInStream *inStream, + ILookInStreamPtr inStream, UInt32 fileIndex, UInt32 *blockIndex, Byte **tempBuf, @@ -1656,7 +1659,7 @@ ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { - UInt32 folderIndex = p->FileToFolder[fileIndex]; + const UInt32 folderIndex = p->FileToFolder[fileIndex]; SRes res = SZ_OK; *offset = 0; @@ -1673,13 +1676,13 @@ if (*tempBuf == NULL || *blockIndex != folderIndex) { - UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); /* UInt64 unpackSizeSpec = p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] - p->UnpackPositions[p->FolderToFile[folderIndex]]; */ - size_t unpackSize = (size_t)unpackSizeSpec; + const size_t unpackSize = (size_t)unpackSizeSpec; if (unpackSize != unpackSizeSpec) return SZ_ERROR_MEM; @@ -1707,7 +1710,7 @@ if (res == SZ_OK) { - UInt64 unpackPos = p->UnpackPositions[fileIndex]; + const UInt64 unpackPos = p->UnpackPositions[fileIndex]; *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos); if (*offset + *outSizeProcessed > *outBufferSize) @@ -1723,8 +1726,8 @@ size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) { - size_t offs = p->FileNameOffsets[fileIndex]; - size_t len = p->FileNameOffsets[fileIndex + 1] - offs; + const size_t offs = p->FileNameOffsets[fileIndex]; + const size_t len = p->FileNameOffsets[fileIndex + 1] - offs; if (dest != 0) { size_t i; diff -Nru 7zip-22.01+dfsg/C/7zBuf.h 7zip-22.01+really25.01+dfsg/C/7zBuf.h --- 7zip-22.01+dfsg/C/7zBuf.h 2017-04-03 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zBuf.h 2023-03-04 11:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7zBuf.h -- Byte Buffer -2017-04-03 : Igor Pavlov : Public domain */ +2023-03-04 : Igor Pavlov : Public domain */ -#ifndef __7Z_BUF_H -#define __7Z_BUF_H +#ifndef ZIP7_INC_7Z_BUF_H +#define ZIP7_INC_7Z_BUF_H #include "7zTypes.h" diff -Nru 7zip-22.01+dfsg/C/7zCrc.c 7zip-22.01+really25.01+dfsg/C/7zCrc.c --- 7zip-22.01+dfsg/C/7zCrc.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zCrc.c 2024-03-01 06:00:00.000000000 +0000 @@ -1,182 +1,218 @@ -/* 7zCrc.c -- CRC32 init -2021-04-01 : Igor Pavlov : Public domain */ +/* 7zCrc.c -- CRC32 calculation and init +2024-03-01 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "7zCrc.h" #include "CpuArch.h" -#define kCrcPoly 0xEDB88320 +// for debug: +// #define __ARM_FEATURE_CRC32 1 -#ifdef MY_CPU_LE - #define CRC_NUM_TABLES 8 -#else - #define CRC_NUM_TABLES 9 - - #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - - UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +#ifdef __ARM_FEATURE_CRC32 +// #pragma message("__ARM_FEATURE_CRC32") +#define Z7_CRC_HW_FORCE #endif -#ifndef MY_CPU_BE - UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +// #define Z7_CRC_DEBUG_BE +#ifdef Z7_CRC_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE #endif -typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); - -extern -CRC_FUNC g_CrcUpdateT4; -CRC_FUNC g_CrcUpdateT4; -extern -CRC_FUNC g_CrcUpdateT8; -CRC_FUNC g_CrcUpdateT8; -extern -CRC_FUNC g_CrcUpdateT0_32; -CRC_FUNC g_CrcUpdateT0_32; -extern -CRC_FUNC g_CrcUpdateT0_64; -CRC_FUNC g_CrcUpdateT0_64; -extern -CRC_FUNC g_CrcUpdate; -CRC_FUNC g_CrcUpdate; - -UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; +#ifdef Z7_CRC_HW_FORCE + #define Z7_CRC_NUM_TABLES_USE 1 +#else +#ifdef Z7_CRC_NUM_TABLES + #define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES +#else + #define Z7_CRC_NUM_TABLES_USE 12 +#endif +#endif -UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) -{ - return g_CrcUpdate(v, data, size, g_CrcTable); -} +#if Z7_CRC_NUM_TABLES_USE < 1 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) -{ - return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; -} +#if defined(MY_CPU_LE) || (Z7_CRC_NUM_TABLES_USE == 1) + #define Z7_CRC_NUM_TABLES_TOTAL Z7_CRC_NUM_TABLES_USE +#else + #define Z7_CRC_NUM_TABLES_TOTAL (Z7_CRC_NUM_TABLES_USE + 1) +#endif -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#ifndef Z7_CRC_HW_FORCE -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) +#if Z7_CRC_NUM_TABLES_USE == 1 \ + || (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#define Z7_CRC_UPDATE_T1_FUNC_NAME CrcUpdateGT1 +static UInt32 Z7_FASTCALL Z7_CRC_UPDATE_T1_FUNC_NAME(UInt32 v, const void *data, size_t size) { + const UInt32 *table = g_CrcTable; const Byte *p = (const Byte *)data; - const Byte *pEnd = p + size; - for (; p != pEnd; p++) + const Byte *lim = p + size; + for (; p != lim; p++) v = CRC_UPDATE_BYTE_2(v, *p); return v; } +#endif +#if Z7_CRC_NUM_TABLES_USE != 1 +#ifndef MY_CPU_BE + #define FUNC_NAME_LE_2(s) CrcUpdateT ## s + #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s) + #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC_NUM_TABLES_USE) + UInt32 Z7_FASTCALL FUNC_NAME_LE (UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif +#ifndef MY_CPU_LE + #define FUNC_NAME_BE_2(s) CrcUpdateT1_BeT ## s + #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s) + #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC_NUM_TABLES_USE) + UInt32 Z7_FASTCALL FUNC_NAME_BE (UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif +#endif + +#endif // Z7_CRC_HW_FORCE + /* ---------- hardware CRC ---------- */ #ifdef MY_CPU_LE #if defined(MY_CPU_ARM_OR_ARM64) - // #pragma message("ARM*") - #if defined(_MSC_VER) - #if defined(MY_CPU_ARM64) - #if (_MSC_VER >= 1910) - #define USE_ARM64_CRC - #endif - #endif - #elif (defined(__clang__) && (__clang_major__ >= 3)) \ - || (defined(__GNUC__) && (__GNUC__ > 4)) + #if (defined(__clang__) && (__clang_major__ >= 3)) \ + || defined(__GNUC__) && (__GNUC__ >= 6) && defined(MY_CPU_ARM64) \ + || defined(__GNUC__) && (__GNUC__ >= 8) #if !defined(__ARM_FEATURE_CRC32) +// #pragma message("!defined(__ARM_FEATURE_CRC32)") +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER #define __ARM_FEATURE_CRC32 1 - #if (!defined(__clang__) || (__clang_major__ > 3)) // fix these numbers +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRC32_WAS_SET + #if defined(__clang__) + #if defined(MY_CPU_ARM64) + #define ATTRIB_CRC __attribute__((__target__("crc"))) + #else + #define ATTRIB_CRC __attribute__((__target__("armv8-a,crc"))) + #endif + #else + #if defined(MY_CPU_ARM64) +#if !defined(Z7_GCC_VERSION) || (Z7_GCC_VERSION >= 60000) + #define ATTRIB_CRC __attribute__((__target__("+crc"))) +#endif + #else +#if !defined(Z7_GCC_VERSION) || (__GNUC__ >= 8) +#if defined(__ARM_FP) && __GNUC__ >= 8 +// for -mfloat-abi=hard: similar to + #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc+simd"))) +#else #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc"))) +#endif +#endif #endif + #endif #endif #if defined(__ARM_FEATURE_CRC32) - #define USE_ARM64_CRC + // #pragma message("") +/* +arm_acle.h (GGC): + before Nov 17, 2017: +#ifdef __ARM_FEATURE_CRC32 + + Nov 17, 2017: gcc10.0 (gcc 9.2.0) checked" +#if __ARM_ARCH >= 8 +#pragma GCC target ("arch=armv8-a+crc") + + Aug 22, 2019: GCC 8.4?, 9.2.1, 10.1: +#ifdef __ARM_FEATURE_CRC32 +#ifdef __ARM_FP +#pragma GCC target ("arch=armv8-a+crc+simd") +#else +#pragma GCC target ("arch=armv8-a+crc") +#endif +*/ +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 +#if defined(Z7_GCC_VERSION) && (__GNUC__ == 8) && (Z7_GCC_VERSION < 80400) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 9) && (Z7_GCC_VERSION < 90201) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 10) && (Z7_GCC_VERSION < 100100) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") +#undef __ARM_ARCH +#define __ARM_ARCH 8 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif + #define Z7_CRC_HW_USE #include #endif + #elif defined(_MSC_VER) + #if defined(MY_CPU_ARM64) + #if (_MSC_VER >= 1910) + #ifdef __clang__ + // #define Z7_CRC_HW_USE + // #include + #else + #define Z7_CRC_HW_USE + #include + #endif + #endif + #endif #endif -#else - -// no hardware CRC - -// #define USE_CRC_EMU +#else // non-ARM* -#ifdef USE_CRC_EMU - -#pragma message("ARM64 CRC emulation") - -MY_FORCE_INLINE -UInt32 __crc32b(UInt32 v, UInt32 data) -{ - const UInt32 *table = g_CrcTable; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); - return v; -} - -MY_FORCE_INLINE -UInt32 __crc32w(UInt32 v, UInt32 data) -{ - const UInt32 *table = g_CrcTable; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - return v; -} +// #define Z7_CRC_HW_USE // for debug : we can test HW-branch of code +#ifdef Z7_CRC_HW_USE +#include "7zCrcEmu.h" +#endif -MY_FORCE_INLINE -UInt32 __crc32d(UInt32 v, UInt64 data) -{ - const UInt32 *table = g_CrcTable; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - v = CRC_UPDATE_BYTE_2(v, (Byte)data); data >>= 8; - return v; -} +#endif // non-ARM* -#endif // USE_CRC_EMU -#endif // defined(MY_CPU_ARM64) && defined(MY_CPU_LE) +#if defined(Z7_CRC_HW_USE) +// #pragma message("USE ARM HW CRC") -#if defined(USE_ARM64_CRC) || defined(USE_CRC_EMU) +#ifdef MY_CPU_64BIT + #define CRC_HW_WORD_TYPE UInt64 + #define CRC_HW_WORD_FUNC __crc32d +#else + #define CRC_HW_WORD_TYPE UInt32 + #define CRC_HW_WORD_FUNC __crc32w +#endif -#define T0_32_UNROLL_BYTES (4 * 4) -#define T0_64_UNROLL_BYTES (4 * 8) +#define CRC_HW_UNROLL_BYTES (sizeof(CRC_HW_WORD_TYPE) * 4) -#ifndef ATTRIB_CRC -#define ATTRIB_CRC +#ifdef ATTRIB_CRC + ATTRIB_CRC #endif -// #pragma message("USE ARM HW CRC") - -ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table); -ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table) +Z7_NO_INLINE +#ifdef Z7_CRC_HW_FORCE + UInt32 Z7_FASTCALL CrcUpdate +#else + static UInt32 Z7_FASTCALL CrcUpdate_HW +#endif + (UInt32 v, const void *data, size_t size) { const Byte *p = (const Byte *)data; - UNUSED_VAR(table); - - for (; size != 0 && ((unsigned)(ptrdiff_t)p & (T0_32_UNROLL_BYTES - 1)) != 0; size--) + for (; size != 0 && ((unsigned)(ptrdiff_t)p & (CRC_HW_UNROLL_BYTES - 1)) != 0; size--) v = __crc32b(v, *p++); - - if (size >= T0_32_UNROLL_BYTES) + if (size >= CRC_HW_UNROLL_BYTES) { const Byte *lim = p + size; - size &= (T0_32_UNROLL_BYTES - 1); + size &= CRC_HW_UNROLL_BYTES - 1; lim -= size; do { - v = __crc32w(v, *(const UInt32 *)(const void *)(p)); - v = __crc32w(v, *(const UInt32 *)(const void *)(p + 4)); p += 2 * 4; - v = __crc32w(v, *(const UInt32 *)(const void *)(p)); - v = __crc32w(v, *(const UInt32 *)(const void *)(p + 4)); p += 2 * 4; + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p)); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE))); + p += 2 * sizeof(CRC_HW_WORD_TYPE); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p)); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE))); + p += 2 * sizeof(CRC_HW_WORD_TYPE); } while (p != lim); } @@ -187,136 +223,198 @@ return v; } -ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table); -ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table) +#ifdef Z7_ARM_FEATURE_CRC32_WAS_SET +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#undef __ARM_FEATURE_CRC32 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#undef Z7_ARM_FEATURE_CRC32_WAS_SET +#endif + +#endif // defined(Z7_CRC_HW_USE) +#endif // MY_CPU_LE + + + +#ifndef Z7_CRC_HW_FORCE + +#if defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) +/* +typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_WITH_TABLE_FUNC) + (UInt32 v, const void *data, size_t size, const UInt32 *table); +Z7_CRC_UPDATE_WITH_TABLE_FUNC g_CrcUpdate; +*/ +static unsigned g_Crc_Algo; +#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) +static unsigned g_Crc_Be; +#endif +#endif // defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) + + + +Z7_NO_INLINE +#ifdef Z7_CRC_HW_USE + static UInt32 Z7_FASTCALL CrcUpdate_Base +#else + UInt32 Z7_FASTCALL CrcUpdate +#endif + (UInt32 crc, const void *data, size_t size) { - const Byte *p = (const Byte *)data; - UNUSED_VAR(table); +#if Z7_CRC_NUM_TABLES_USE == 1 + return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size); +#else // Z7_CRC_NUM_TABLES_USE != 1 +#ifdef Z7_CRC_UPDATE_T1_FUNC_NAME + if (g_Crc_Algo == 1) + return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size); +#endif - for (; size != 0 && ((unsigned)(ptrdiff_t)p & (T0_64_UNROLL_BYTES - 1)) != 0; size--) - v = __crc32b(v, *p++); +#ifdef MY_CPU_LE + return FUNC_NAME_LE(crc, data, size, g_CrcTable); +#elif defined(MY_CPU_BE) + return FUNC_NAME_BE(crc, data, size, g_CrcTable); +#else + if (g_Crc_Be) + return FUNC_NAME_BE(crc, data, size, g_CrcTable); + else + return FUNC_NAME_LE(crc, data, size, g_CrcTable); +#endif +#endif // Z7_CRC_NUM_TABLES_USE != 1 +} - if (size >= T0_64_UNROLL_BYTES) - { - const Byte *lim = p + size; - size &= (T0_64_UNROLL_BYTES - 1); - lim -= size; - do - { - v = __crc32d(v, *(const UInt64 *)(const void *)(p)); - v = __crc32d(v, *(const UInt64 *)(const void *)(p + 8)); p += 2 * 8; - v = __crc32d(v, *(const UInt64 *)(const void *)(p)); - v = __crc32d(v, *(const UInt64 *)(const void *)(p + 8)); p += 2 * 8; - } - while (p != lim); - } - - for (; size != 0; size--) - v = __crc32b(v, *p++); - return v; +#ifdef Z7_CRC_HW_USE +Z7_NO_INLINE +UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size) +{ + if (g_Crc_Algo == 0) + return CrcUpdate_HW(crc, data, size); + return CrcUpdate_Base(crc, data, size); } +#endif -#endif // defined(USE_ARM64_CRC) || defined(USE_CRC_EMU) +#endif // !defined(Z7_CRC_HW_FORCE) -#endif // MY_CPU_LE +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size) +{ + return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL; +} + + +MY_ALIGN(64) +UInt32 g_CrcTable[256 * Z7_CRC_NUM_TABLES_TOTAL]; -void MY_FAST_CALL CrcGenerateTable() +void Z7_FASTCALL CrcGenerateTable(void) { UInt32 i; for (i = 0; i < 256; i++) { +#if defined(Z7_CRC_HW_FORCE) + g_CrcTable[i] = __crc32b(i, 0); +#else + #define kCrcPoly 0xEDB88320 UInt32 r = i; unsigned j; for (j = 0; j < 8; j++) r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); g_CrcTable[i] = r; +#endif } - for (i = 256; i < 256 * CRC_NUM_TABLES; i++) + for (i = 256; i < 256 * Z7_CRC_NUM_TABLES_USE; i++) { - UInt32 r = g_CrcTable[(size_t)i - 256]; + const UInt32 r = g_CrcTable[(size_t)i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); } - #if CRC_NUM_TABLES < 4 - - g_CrcUpdate = CrcUpdateT1; - - #else - - #ifdef MY_CPU_LE +#if !defined(Z7_CRC_HW_FORCE) && \ + (defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) || defined(MY_CPU_BE)) - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT8; - - #ifdef MY_CPU_X86_OR_AMD64 - if (!CPU_Is_InOrder()) - #endif - g_CrcUpdate = CrcUpdateT8; - #endif - - #else +#if Z7_CRC_NUM_TABLES_USE <= 1 + g_Crc_Algo = 1; +#else // Z7_CRC_NUM_TABLES_USE <= 1 + +#if defined(MY_CPU_LE) + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; +#else // !defined(MY_CPU_LE) { - #ifndef MY_CPU_BE +#ifndef MY_CPU_BE UInt32 k = 0x01020304; const Byte *p = (const Byte *)&k; if (p[0] == 4 && p[1] == 3) - { - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT8; - g_CrcUpdate = CrcUpdateT8; - #endif - } + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; else if (p[0] != 1 || p[1] != 2) - g_CrcUpdate = CrcUpdateT1; + g_Crc_Algo = 1; else - #endif +#endif // MY_CPU_BE { - for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) + for (i = 256 * Z7_CRC_NUM_TABLES_TOTAL - 1; i >= 256; i--) { - UInt32 x = g_CrcTable[(size_t)i - 256]; - g_CrcTable[i] = CRC_UINT32_SWAP(x); + const UInt32 x = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = Z7_BSWAP32(x); } - g_CrcUpdateT4 = CrcUpdateT1_BeT4; - g_CrcUpdate = CrcUpdateT1_BeT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT1_BeT8; - g_CrcUpdate = CrcUpdateT1_BeT8; - #endif +#if defined(Z7_CRC_UPDATE_T1_FUNC_NAME) + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; +#endif +#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) + g_Crc_Be = 1; +#endif } } - #endif - #endif +#endif // !defined(MY_CPU_LE) - #ifdef MY_CPU_LE - #ifdef USE_ARM64_CRC - if (CPU_IsSupported_CRC32()) - { - g_CrcUpdateT0_32 = CrcUpdateT0_32; - g_CrcUpdateT0_64 = CrcUpdateT0_64; - g_CrcUpdate = - #if defined(MY_CPU_ARM) - CrcUpdateT0_32; - #else - CrcUpdateT0_64; - #endif - } - #endif - - #ifdef USE_CRC_EMU - g_CrcUpdateT0_32 = CrcUpdateT0_32; - g_CrcUpdateT0_64 = CrcUpdateT0_64; - g_CrcUpdate = CrcUpdateT0_64; - #endif +#ifdef MY_CPU_LE +#ifdef Z7_CRC_HW_USE + if (CPU_IsSupported_CRC32()) + g_Crc_Algo = 0; +#endif // Z7_CRC_HW_USE +#endif // MY_CPU_LE + +#endif // Z7_CRC_NUM_TABLES_USE <= 1 +#endif // g_Crc_Algo was declared +} + +Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo) +{ + if (algo == 0) + return &CrcUpdate; + +#if defined(Z7_CRC_HW_USE) + if (algo == sizeof(CRC_HW_WORD_TYPE) * 8) + { +#ifdef Z7_CRC_HW_FORCE + return &CrcUpdate; +#else + if (g_Crc_Algo == 0) + return &CrcUpdate_HW; +#endif + } +#endif + +#ifndef Z7_CRC_HW_FORCE + if (algo == Z7_CRC_NUM_TABLES_USE) + return + #ifdef Z7_CRC_HW_USE + &CrcUpdate_Base; + #else + &CrcUpdate; #endif +#endif + + return NULL; } + +#undef kCrcPoly +#undef Z7_CRC_NUM_TABLES_USE +#undef Z7_CRC_NUM_TABLES_TOTAL +#undef CRC_UPDATE_BYTE_2 +#undef FUNC_NAME_LE_2 +#undef FUNC_NAME_LE_1 +#undef FUNC_NAME_LE +#undef FUNC_NAME_BE_2 +#undef FUNC_NAME_BE_1 +#undef FUNC_NAME_BE + +#undef CRC_HW_UNROLL_BYTES +#undef CRC_HW_WORD_FUNC +#undef CRC_HW_WORD_TYPE diff -Nru 7zip-22.01+dfsg/C/7zCrc.h 7zip-22.01+really25.01+dfsg/C/7zCrc.h --- 7zip-22.01+dfsg/C/7zCrc.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zCrc.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7zCrc.h -- CRC32 calculation -2013-01-18 : Igor Pavlov : Public domain */ +2024-01-22 : Igor Pavlov : Public domain */ -#ifndef __7Z_CRC_H -#define __7Z_CRC_H +#ifndef ZIP7_INC_7Z_CRC_H +#define ZIP7_INC_7Z_CRC_H #include "7zTypes.h" @@ -11,14 +11,17 @@ extern UInt32 g_CrcTable[]; /* Call CrcGenerateTable one time before other CRC functions */ -void MY_FAST_CALL CrcGenerateTable(void); +void Z7_FASTCALL CrcGenerateTable(void); #define CRC_INIT_VAL 0xFFFFFFFF #define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); +UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size); + +typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_FUNC)(UInt32 v, const void *data, size_t size); +Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/7zCrcOpt.c 7zip-22.01+really25.01+dfsg/C/7zCrcOpt.c --- 7zip-22.01+dfsg/C/7zCrcOpt.c 2021-02-09 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zCrcOpt.c 2023-12-07 17:00:00.000000000 +0000 @@ -1,117 +1,199 @@ -/* 7zCrcOpt.c -- CRC32 calculation -2021-02-09 : Igor Pavlov : Public domain */ +/* 7zCrcOpt.c -- CRC32 calculation (optimized functions) +2023-12-07 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "CpuArch.h" +#if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1 + +// for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC_DEBUG_BE +#ifdef Z7_CRC_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +// the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c +#ifdef Z7_CRC_NUM_TABLES +#define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES +#else +#define Z7_CRC_NUM_TABLES_USE 12 +#endif + +#if Z7_CRC_NUM_TABLES_USE % 4 || \ + Z7_CRC_NUM_TABLES_USE < 4 * 1 || \ + Z7_CRC_NUM_TABLES_USE > 4 * 6 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif + + #ifndef MY_CPU_BE -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)(const void *)p; - v = - (table + 0x300)[((v ) & 0xFF)] - ^ (table + 0x200)[((v >> 8) & 0xFF)] - ^ (table + 0x100)[((v >> 16) & 0xFF)] - ^ (table + 0x000)[((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} +#define Q(n, d) \ + ( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] ) + +#define R(a) *((const UInt32 *)(const void *)p + (a)) + +#define CRC_FUNC_PRE_LE2(step) \ +UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table) -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +#define CRC_FUNC_PRE_LE(step) \ + CRC_FUNC_PRE_LE2(step); \ + CRC_FUNC_PRE_LE2(step) + +CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE) { const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) + const Byte *lim; + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++) v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 8; size -= 8, p += 8) + lim = p + size; + if (size >= Z7_CRC_NUM_TABLES_USE) { - UInt32 d; - v ^= *(const UInt32 *)(const void *)p; - v = - (table + 0x700)[((v ) & 0xFF)] - ^ (table + 0x600)[((v >> 8) & 0xFF)] - ^ (table + 0x500)[((v >> 16) & 0xFF)] - ^ (table + 0x400)[((v >> 24))]; - d = *((const UInt32 *)(const void *)p + 1); - v ^= - (table + 0x300)[((d ) & 0xFF)] - ^ (table + 0x200)[((d >> 8) & 0xFF)] - ^ (table + 0x100)[((d >> 16) & 0xFF)] - ^ (table + 0x000)[((d >> 24))]; + lim -= Z7_CRC_NUM_TABLES_USE; + do + { + v ^= R(0); + { +#if Z7_CRC_NUM_TABLES_USE == 1 * 4 + v = Q(0, v); +#else +#define U2(r, op) \ + { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); } + UInt32 d, x; + U2(1, =) +#if Z7_CRC_NUM_TABLES_USE >= 3 * 4 +#define U(r) U2(r, ^=) + U(2) +#if Z7_CRC_NUM_TABLES_USE >= 4 * 4 + U(3) +#if Z7_CRC_NUM_TABLES_USE >= 5 * 4 + U(4) +#if Z7_CRC_NUM_TABLES_USE >= 6 * 4 + U(5) +#if Z7_CRC_NUM_TABLES_USE >= 7 * 4 +#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif +#endif +#endif +#endif +#endif +#undef U +#undef U2 + v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v); +#endif + } + p += Z7_CRC_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC_NUM_TABLES_USE; } - for (; size > 0; size--, p++) + for (; p < lim; p++) v = CRC_UPDATE_BYTE_2(v, *p); return v; } +#undef CRC_UPDATE_BYTE_2 +#undef R +#undef Q +#undef CRC_FUNC_PRE_LE +#undef CRC_FUNC_PRE_LE2 + #endif + + #ifndef MY_CPU_LE -#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) +#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8)) -#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8)) +#define Q(n, d) \ + ( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] ) + +#ifdef Z7_CRC_DEBUG_BE + #define R(a) GetBe32a((const UInt32 *)(const void *)p + (a)) +#else + #define R(a) *((const UInt32 *)(const void *)p + (a)) +#endif -UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - table += 0x100; - v = CRC_UINT32_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)(const void *)p; - v = - (table + 0x000)[((v ) & 0xFF)] - ^ (table + 0x100)[((v >> 8) & 0xFF)] - ^ (table + 0x200)[((v >> 16) & 0xFF)] - ^ (table + 0x300)[((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT32_SWAP(v); -} -UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +#define CRC_FUNC_PRE_BE2(step) \ +UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table) + +#define CRC_FUNC_PRE_BE(step) \ + CRC_FUNC_PRE_BE2(step); \ + CRC_FUNC_PRE_BE2(step) + +CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE) { const Byte *p = (const Byte *)data; + const Byte *lim; table += 0x100; - v = CRC_UINT32_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) + v = Z7_BSWAP32(v); + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++) v = CRC_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 8; size -= 8, p += 8) + lim = p + size; + if (size >= Z7_CRC_NUM_TABLES_USE) { - UInt32 d; - v ^= *(const UInt32 *)(const void *)p; - v = - (table + 0x400)[((v ) & 0xFF)] - ^ (table + 0x500)[((v >> 8) & 0xFF)] - ^ (table + 0x600)[((v >> 16) & 0xFF)] - ^ (table + 0x700)[((v >> 24))]; - d = *((const UInt32 *)(const void *)p + 1); - v ^= - (table + 0x000)[((d ) & 0xFF)] - ^ (table + 0x100)[((d >> 8) & 0xFF)] - ^ (table + 0x200)[((d >> 16) & 0xFF)] - ^ (table + 0x300)[((d >> 24))]; + lim -= Z7_CRC_NUM_TABLES_USE; + do + { + v ^= R(0); + { +#if Z7_CRC_NUM_TABLES_USE == 1 * 4 + v = Q(0, v); +#else +#define U2(r, op) \ + { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); } + UInt32 d, x; + U2(1, =) +#if Z7_CRC_NUM_TABLES_USE >= 3 * 4 +#define U(r) U2(r, ^=) + U(2) +#if Z7_CRC_NUM_TABLES_USE >= 4 * 4 + U(3) +#if Z7_CRC_NUM_TABLES_USE >= 5 * 4 + U(4) +#if Z7_CRC_NUM_TABLES_USE >= 6 * 4 + U(5) +#if Z7_CRC_NUM_TABLES_USE >= 7 * 4 +#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif +#endif +#endif +#endif +#endif +#undef U +#undef U2 + v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v); +#endif + } + p += Z7_CRC_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC_NUM_TABLES_USE; } - for (; size > 0; size--, p++) + for (; p < lim; p++) v = CRC_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT32_SWAP(v); + return Z7_BSWAP32(v); } +#undef CRC_UPDATE_BYTE_2_BE +#undef R +#undef Q +#undef CRC_FUNC_PRE_BE +#undef CRC_FUNC_PRE_BE2 + +#endif +#undef Z7_CRC_NUM_TABLES_USE #endif diff -Nru 7zip-22.01+dfsg/C/7zDec.c 7zip-22.01+really25.01+dfsg/C/7zDec.c --- 7zip-22.01+dfsg/C/7zDec.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zDec.c 2024-11-29 10:00:00.000000000 +0000 @@ -1,11 +1,11 @@ /* 7zDec.c -- Decoding from 7z folder -2021-02-09 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" #include -/* #define _7ZIP_PPMD_SUPPPORT */ +/* #define Z7_PPMD_SUPPORT */ #include "7z.h" #include "7zCrc.h" @@ -16,27 +16,50 @@ #include "Delta.h" #include "LzmaDec.h" #include "Lzma2Dec.h" -#ifdef _7ZIP_PPMD_SUPPPORT +#ifdef Z7_PPMD_SUPPORT #include "Ppmd7.h" #endif #define k_Copy 0 -#ifndef _7Z_NO_METHOD_LZMA2 +#ifndef Z7_NO_METHOD_LZMA2 #define k_LZMA2 0x21 #endif #define k_LZMA 0x30101 #define k_BCJ2 0x303011B -#ifndef _7Z_NO_METHODS_FILTERS + +#if !defined(Z7_NO_METHODS_FILTERS) +#define Z7_USE_BRANCH_FILTER +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64) +#define Z7_USE_FILTER_ARM64 +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARM64 0xa +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT) +#define Z7_USE_FILTER_ARMT +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARMT 0x3030701 +#endif + +#ifndef Z7_NO_METHODS_FILTERS #define k_Delta 3 +#define k_RISCV 0xb #define k_BCJ 0x3030103 #define k_PPC 0x3030205 #define k_IA64 0x3030401 #define k_ARM 0x3030501 -#define k_ARMT 0x3030701 #define k_SPARC 0x3030805 #endif -#ifdef _7ZIP_PPMD_SUPPPORT +#ifdef Z7_PPMD_SUPPORT #define k_PPMD 0x30401 @@ -49,12 +72,12 @@ UInt64 processed; BoolInt extra; SRes res; - const ILookInStream *inStream; + ILookInStreamPtr inStream; } CByteInToLook; -static Byte ReadByte(const IByteIn *pp) +static Byte ReadByte(IByteInPtr pp) { - CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook) if (p->cur != p->end) return *p->cur++; if (p->res == SZ_OK) @@ -67,13 +90,13 @@ p->cur = p->begin; p->end = p->begin + size; if (size != 0) - return *p->cur++;; + return *p->cur++; } p->extra = True; return 0; } -static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, +static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CPpmd7 ppmd; @@ -138,14 +161,14 @@ #endif -static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, +static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzmaDec state; SRes res = SZ_OK; - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); + LzmaDec_CONSTRUCT(&state) + RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)) state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_Init(&state); @@ -196,18 +219,18 @@ } -#ifndef _7Z_NO_METHOD_LZMA2 +#ifndef Z7_NO_METHOD_LZMA2 -static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, +static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzma2Dec state; SRes res = SZ_OK; - Lzma2Dec_Construct(&state); + Lzma2Dec_CONSTRUCT(&state) if (propsSize != 1) return SZ_ERROR_DATA; - RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); + RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)) state.decoder.dic = outBuffer; state.decoder.dicBufSize = outSize; Lzma2Dec_Init(&state); @@ -257,7 +280,7 @@ #endif -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer) { while (inSize > 0) { @@ -265,13 +288,13 @@ size_t curSize = (1 << 18); if (curSize > inSize) curSize = (size_t)inSize; - RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); + RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)) if (curSize == 0) return SZ_ERROR_INPUT_EOF; memcpy(outBuffer, inBuf, curSize); outBuffer += curSize; inSize -= curSize; - RINOK(ILookInStream_Skip(inStream, curSize)); + RINOK(ILookInStream_Skip(inStream, curSize)) } return SZ_OK; } @@ -282,15 +305,16 @@ { case k_Copy: case k_LZMA: - #ifndef _7Z_NO_METHOD_LZMA2 + #ifndef Z7_NO_METHOD_LZMA2 case k_LZMA2: - #endif - #ifdef _7ZIP_PPMD_SUPPPORT + #endif + #ifdef Z7_PPMD_SUPPORT case k_PPMD: - #endif + #endif return True; + default: + return False; } - return False; } static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c) @@ -317,7 +341,7 @@ } - #ifndef _7Z_NO_METHODS_FILTERS + #if defined(Z7_USE_BRANCH_FILTER) if (f->NumCoders == 2) { @@ -333,13 +357,21 @@ return SZ_ERROR_UNSUPPORTED; switch ((UInt32)c->MethodID) { + #if !defined(Z7_NO_METHODS_FILTERS) case k_Delta: case k_BCJ: case k_PPC: case k_IA64: case k_SPARC: case k_ARM: + case k_RISCV: + #endif + #ifdef Z7_USE_FILTER_ARM64 + case k_ARM64: + #endif + #ifdef Z7_USE_FILTER_ARMT case k_ARMT: + #endif break; default: return SZ_ERROR_UNSUPPORTED; @@ -372,15 +404,16 @@ return SZ_ERROR_UNSUPPORTED; } -#ifndef _7Z_NO_METHODS_FILTERS -#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; -#endif + + + + static SRes SzFolder_Decode2(const CSzFolder *folder, const Byte *propsData, const UInt64 *unpackSizes, const UInt64 *packPositions, - ILookInStream *inStream, UInt64 startPos, + ILookInStreamPtr inStream, UInt64 startPos, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, Byte *tempBuf[]) { @@ -389,7 +422,7 @@ SizeT tempSize3 = 0; Byte *tempBuf3 = 0; - RINOK(CheckSupportedFolder(folder)); + RINOK(CheckSupportedFolder(folder)) for (ci = 0; ci < folder->NumCoders; ci++) { @@ -404,8 +437,8 @@ SizeT outSizeCur = outSize; if (folder->NumCoders == 4) { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = unpackSizes[ci]; + const UInt32 indices[] = { 3, 2, 0 }; + const UInt64 unpackSize = unpackSizes[ci]; si = indices[ci]; if (ci < 2) { @@ -431,37 +464,37 @@ } offset = packPositions[si]; inSize = packPositions[(size_t)si + 1] - offset; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) /* check it */ return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)) } else if (coder->MethodID == k_LZMA) { - RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #ifndef _7Z_NO_METHOD_LZMA2 + #ifndef Z7_NO_METHOD_LZMA2 else if (coder->MethodID == k_LZMA2) { - RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #endif - #ifdef _7ZIP_PPMD_SUPPPORT + #endif + #ifdef Z7_PPMD_SUPPORT else if (coder->MethodID == k_PPMD) { - RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #endif + #endif else return SZ_ERROR_UNSUPPORTED; } else if (coder->MethodID == k_BCJ2) { - UInt64 offset = packPositions[1]; - UInt64 s3Size = packPositions[2] - offset; + const UInt64 offset = packPositions[1]; + const UInt64 s3Size = packPositions[2] - offset; if (ci != 3) return SZ_ERROR_UNSUPPORTED; @@ -473,8 +506,8 @@ if (!tempBuf[2] && tempSizes[2] != 0) return SZ_ERROR_MEM; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])); + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) + RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])) if ((tempSizes[0] & 3) != 0 || (tempSizes[1] & 3) != 0 || @@ -493,26 +526,22 @@ p.destLim = outBuffer + outSize; Bcj2Dec_Init(&p); - RINOK(Bcj2Dec_Decode(&p)); + RINOK(Bcj2Dec_Decode(&p)) { unsigned i; for (i = 0; i < 4; i++) if (p.bufs[i] != p.lims[i]) return SZ_ERROR_DATA; - - if (!Bcj2Dec_IsFinished(&p)) - return SZ_ERROR_DATA; - - if (p.dest != p.destLim - || p.state != BCJ2_STREAM_MAIN) + if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p)) return SZ_ERROR_DATA; } } } - #ifndef _7Z_NO_METHODS_FILTERS +#if defined(Z7_USE_BRANCH_FILTER) else if (ci == 1) { +#if !defined(Z7_NO_METHODS_FILTERS) if (coder->MethodID == k_Delta) { if (coder->PropsSize != 1) @@ -522,31 +551,75 @@ Delta_Init(state); Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); } + continue; } - else +#endif + +#ifdef Z7_USE_FILTER_ARM64 + if (coder->MethodID == k_ARM64) + { + UInt32 pc = 0; + if (coder->PropsSize == 4) + { + pc = GetUi32(propsData + coder->PropsOffset); + if (pc & 3) + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc); + continue; + } +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) + if (coder->MethodID == k_RISCV) + { + UInt32 pc = 0; + if (coder->PropsSize == 4) + { + pc = GetUi32(propsData + coder->PropsOffset); + if (pc & 1) + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + z7_BranchConv_RISCV_Dec(outBuffer, outSize, pc); + continue; + } +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) { if (coder->PropsSize != 0) return SZ_ERROR_UNSUPPORTED; + #define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0; switch (coder->MethodID) { + #if !defined(Z7_NO_METHODS_FILTERS) case k_BCJ: { - UInt32 state; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); + UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0 break; } - CASE_BRA_CONV(PPC) + case k_PPC: Z7_BRANCH_CONV_DEC_2(BranchConv_PPC)(outBuffer, outSize, 0); break; // pc = 0; + // CASE_BRA_CONV(PPC) CASE_BRA_CONV(IA64) CASE_BRA_CONV(SPARC) CASE_BRA_CONV(ARM) + #endif + #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) CASE_BRA_CONV(ARMT) + #endif default: return SZ_ERROR_UNSUPPORTED; } + continue; } - } - #endif +#endif + } // (c == 1) +#endif // Z7_USE_BRANCH_FILTER else return SZ_ERROR_UNSUPPORTED; } @@ -556,7 +629,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *inStream, UInt64 startPos, + ILookInStreamPtr inStream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAllocPtr allocMain) { diff -Nru 7zip-22.01+dfsg/C/7zFile.c 7zip-22.01+really25.01+dfsg/C/7zFile.c --- 7zip-22.01+dfsg/C/7zFile.c 2021-04-29 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zFile.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* 7zFile.c -- File IO -2021-04-29 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -268,7 +268,7 @@ return errno; if (processed == 0) break; - data = (void *)((Byte *)data + (size_t)processed); + data = (const void *)((const Byte *)data + (size_t)processed); originalSize -= (size_t)processed; *size += (size_t)processed; } @@ -287,7 +287,8 @@ DWORD moveMethod; UInt32 low = (UInt32)*pos; LONG high = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ - switch (origin) + // (int) to eliminate clang warning + switch ((int)origin) { case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; @@ -308,7 +309,7 @@ int moveMethod; // = origin; - switch (origin) + switch ((int)origin) { case SZ_SEEK_SET: moveMethod = SEEK_SET; break; case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; @@ -387,10 +388,10 @@ /* ---------- FileSeqInStream ---------- */ -static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size) +static SRes FileSeqInStream_Read(ISeqInStreamPtr pp, void *buf, size_t *size) { - CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt); - WRes wres = File_Read(&p->file, buf, size); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileSeqInStream) + const WRes wres = File_Read(&p->file, buf, size); p->wres = wres; return (wres == 0) ? SZ_OK : SZ_ERROR_READ; } @@ -403,18 +404,18 @@ /* ---------- FileInStream ---------- */ -static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size) +static SRes FileInStream_Read(ISeekInStreamPtr pp, void *buf, size_t *size) { - CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); - WRes wres = File_Read(&p->file, buf, size); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Read(&p->file, buf, size); p->wres = wres; return (wres == 0) ? SZ_OK : SZ_ERROR_READ; } -static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin) +static SRes FileInStream_Seek(ISeekInStreamPtr pp, Int64 *pos, ESzSeek origin) { - CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); - WRes wres = File_Seek(&p->file, pos, origin); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Seek(&p->file, pos, origin); p->wres = wres; return (wres == 0) ? SZ_OK : SZ_ERROR_READ; } @@ -428,10 +429,10 @@ /* ---------- FileOutStream ---------- */ -static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size) +static size_t FileOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) { - CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt); - WRes wres = File_Write(&p->file, data, &size); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileOutStream) + const WRes wres = File_Write(&p->file, data, &size); p->wres = wres; return size; } diff -Nru 7zip-22.01+dfsg/C/7zFile.h 7zip-22.01+really25.01+dfsg/C/7zFile.h --- 7zip-22.01+dfsg/C/7zFile.h 2021-02-15 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zFile.h 2023-03-05 09:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7zFile.h -- File IO -2021-02-15 : Igor Pavlov : Public domain */ +2023-03-05 : Igor Pavlov : Public domain */ -#ifndef __7Z_FILE_H -#define __7Z_FILE_H +#ifndef ZIP7_INC_FILE_H +#define ZIP7_INC_FILE_H #ifdef _WIN32 #define USE_WINDOWS_FILE @@ -10,7 +10,8 @@ #endif #ifdef USE_WINDOWS_FILE -#include +#include "7zWindows.h" + #else // note: USE_FOPEN mode is limited to 32-bit file size // #define USE_FOPEN diff -Nru 7zip-22.01+dfsg/C/7zStream.c 7zip-22.01+really25.01+dfsg/C/7zStream.c --- 7zip-22.01+dfsg/C/7zStream.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zStream.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* 7zStream.c -- 7z Stream functions -2021-02-09 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,12 +7,33 @@ #include "7zTypes.h" -SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) + +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize) +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + size_t cur = size; + const SRes res = ISeqInStream_Read(stream, buf, &cur); + *processedSize += cur; + buf = (void *)((Byte *)buf + cur); + size -= cur; + if (res != SZ_OK) + return res; + if (cur == 0) + return SZ_OK; + } + return SZ_OK; +} + +/* +SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(ISeqInStream_Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)) if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -21,42 +42,44 @@ return SZ_OK; } -SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size) +SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size) { return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } +*/ + -SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf) +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf) { size_t processed = 1; - RINOK(ISeqInStream_Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)) return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; } -SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset) { Int64 t = (Int64)offset; return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); } -SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size) { const void *lookBuf; if (*size == 0) return SZ_OK; - RINOK(ILookInStream_Look(stream, &lookBuf, size)); + RINOK(ILookInStream_Look(stream, &lookBuf, size)) memcpy(buf, lookBuf, *size); return ILookInStream_Skip(stream, *size); } -SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(ILookInStream_Read(stream, buf, &processed)); + RINOK(ILookInStream_Read(stream, buf, &processed)) if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -65,16 +88,16 @@ return SZ_OK; } -SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size) { return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } -#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); +#define GET_LookToRead2 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLookToRead2) -static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) +static SRes LookToRead2_Look_Lookahead(ILookInStreamPtr pp, const void **buf, size_t *size) { SRes res = SZ_OK; GET_LookToRead2 @@ -93,7 +116,7 @@ return res; } -static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) +static SRes LookToRead2_Look_Exact(ILookInStreamPtr pp, const void **buf, size_t *size) { SRes res = SZ_OK; GET_LookToRead2 @@ -113,14 +136,14 @@ return res; } -static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) +static SRes LookToRead2_Skip(ILookInStreamPtr pp, size_t offset) { GET_LookToRead2 p->pos += offset; return SZ_OK; } -static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) +static SRes LookToRead2_Read(ILookInStreamPtr pp, void *buf, size_t *size) { GET_LookToRead2 size_t rem = p->size - p->pos; @@ -134,7 +157,7 @@ return SZ_OK; } -static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) +static SRes LookToRead2_Seek(ILookInStreamPtr pp, Int64 *pos, ESzSeek origin) { GET_LookToRead2 p->pos = p->size = 0; @@ -153,9 +176,9 @@ -static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) +static SRes SecToLook_Read(ISeqInStreamPtr pp, void *buf, size_t *size) { - CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToLook) return LookInStream_LookRead(p->realStream, buf, size); } @@ -164,9 +187,9 @@ p->vt.Read = SecToLook_Read; } -static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) +static SRes SecToRead_Read(ISeqInStreamPtr pp, void *buf, size_t *size) { - CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToRead) return ILookInStream_Read(p->realStream, buf, size); } diff -Nru 7zip-22.01+dfsg/C/7zTypes.h 7zip-22.01+really25.01+dfsg/C/7zTypes.h --- 7zip-22.01+dfsg/C/7zTypes.h 2022-04-01 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zTypes.h 2024-01-21 11:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* 7zTypes.h -- Basic types -2022-04-01 : Igor Pavlov : Public domain */ +2024-01-24 : Igor Pavlov : Public domain */ -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H +#ifndef ZIP7_7Z_TYPES_H +#define ZIP7_7Z_TYPES_H #ifdef _WIN32 /* #include */ @@ -52,6 +52,11 @@ #define MY_ALIGN(n) #endif #else + /* + // C11/C++11: + #include + #define MY_ALIGN(n) alignas(n) + */ #define MY_ALIGN(n) __attribute__ ((aligned(n))) #endif @@ -62,7 +67,7 @@ typedef unsigned WRes; #define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) -// #define MY_HRES_ERROR__INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) +// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) #else // _WIN32 @@ -70,13 +75,13 @@ typedef int WRes; // (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT -#define MY__FACILITY_ERRNO 0x800 -#define MY__FACILITY_WIN32 7 -#define MY__FACILITY__WRes MY__FACILITY_ERRNO +#define MY_FACILITY_ERRNO 0x800 +#define MY_FACILITY_WIN32 7 +#define MY_FACILITY_WRes MY_FACILITY_ERRNO #define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \ ( (HRESULT)(x) & 0x0000FFFF) \ - | (MY__FACILITY__WRes << 16) \ + | (MY_FACILITY_WRes << 16) \ | (HRESULT)0x80000000 )) #define MY_SRes_HRESULT_FROM_WRes(x) \ @@ -120,17 +125,17 @@ #define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L) #define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L) -// if (MY__FACILITY__WRes != FACILITY_WIN32), +// if (MY_FACILITY_WRes != FACILITY_WIN32), // we use FACILITY_WIN32 for COM errors: #define E_OUTOFMEMORY ((HRESULT)0x8007000EL) #define E_INVALIDARG ((HRESULT)0x80070057L) -#define MY__E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) +#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) /* // we can use FACILITY_ERRNO for some COM errors, that have errno equivalents: #define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM) #define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) -#define MY__E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) */ #define TEXT(quote) quote @@ -156,18 +161,18 @@ #ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; } #endif #ifndef RINOK_WRes -#define RINOK_WRes(x) { WRes __result__ = (x); if (__result__ != 0) return __result__; } +#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; } #endif typedef unsigned char Byte; typedef short Int16; typedef unsigned short UInt16; -#ifdef _LZMA_UINT32_IS_ULONG +#ifdef Z7_DECL_Int32_AS_long typedef long Int32; typedef unsigned long UInt32; #else @@ -206,37 +211,51 @@ #endif // _WIN32 -#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL) +#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL) -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ +#ifdef Z7_DECL_Int64_AS_long typedef long Int64; typedef unsigned long UInt64; #else -#if defined(_MSC_VER) || defined(__BORLANDC__) +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__) typedef __int64 Int64; typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n +#else +#if defined(__clang__) || defined(__GNUC__) +#include +typedef int64_t Int64; +typedef uint64_t UInt64; #else typedef long long int Int64; typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL +// #define UINT64_CONST(n) n ## ULL +#endif #endif #endif -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; +#define UINT64_CONST(n) n + + +#ifdef Z7_DECL_SizeT_AS_unsigned_int +typedef unsigned int SizeT; #else typedef size_t SizeT; #endif +/* +#if (defined(_MSC_VER) && _MSC_VER <= 1200) +typedef size_t MY_uintptr_t; +#else +#include +typedef uintptr_t MY_uintptr_t; +#endif +*/ + typedef int BoolInt; /* typedef BoolInt Bool; */ #define True 1 @@ -244,23 +263,23 @@ #ifdef _WIN32 -#define MY_STD_CALL __stdcall +#define Z7_STDCALL __stdcall #else -#define MY_STD_CALL +#define Z7_STDCALL #endif #ifdef _MSC_VER #if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) +#define Z7_NO_INLINE __declspec(noinline) #else -#define MY_NO_INLINE +#define Z7_NO_INLINE #endif -#define MY_FORCE_INLINE __forceinline +#define Z7_FORCE_INLINE __forceinline -#define MY_CDECL __cdecl -#define MY_FAST_CALL __fastcall +#define Z7_CDECL __cdecl +#define Z7_FASTCALL __fastcall #else // _MSC_VER @@ -268,27 +287,25 @@ || (defined(__clang__) && (__clang_major__ >= 4)) \ || defined(__INTEL_COMPILER) \ || defined(__xlC__) -#define MY_NO_INLINE __attribute__((noinline)) -// #define MY_FORCE_INLINE __attribute__((always_inline)) inline +#define Z7_NO_INLINE __attribute__((noinline)) +#define Z7_FORCE_INLINE __attribute__((always_inline)) inline #else -#define MY_NO_INLINE +#define Z7_NO_INLINE +#define Z7_FORCE_INLINE #endif -#define MY_FORCE_INLINE - - -#define MY_CDECL +#define Z7_CDECL #if defined(_M_IX86) \ || defined(__i386__) -// #define MY_FAST_CALL __attribute__((fastcall)) -// #define MY_FAST_CALL __attribute__((cdecl)) -#define MY_FAST_CALL +// #define Z7_FASTCALL __attribute__((fastcall)) +// #define Z7_FASTCALL __attribute__((cdecl)) +#define Z7_FASTCALL #elif defined(MY_CPU_AMD64) -// #define MY_FAST_CALL __attribute__((ms_abi)) -#define MY_FAST_CALL +// #define Z7_FASTCALL __attribute__((ms_abi)) +#define Z7_FASTCALL #else -#define MY_FAST_CALL +#define Z7_FASTCALL #endif #endif // _MSC_VER @@ -296,41 +313,49 @@ /* The following interfaces use first parameter as pointer to structure */ -typedef struct IByteIn IByteIn; -struct IByteIn +// #define Z7_C_IFACE_CONST_QUAL +#define Z7_C_IFACE_CONST_QUAL const + +#define Z7_C_IFACE_DECL(a) \ + struct a ## _; \ + typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \ + typedef struct a ## _ a; \ + struct a ## _ + + +Z7_C_IFACE_DECL (IByteIn) { - Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */ + Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */ }; #define IByteIn_Read(p) (p)->Read(p) -typedef struct IByteOut IByteOut; -struct IByteOut +Z7_C_IFACE_DECL (IByteOut) { - void (*Write)(const IByteOut *p, Byte b); + void (*Write)(IByteOutPtr p, Byte b); }; #define IByteOut_Write(p, b) (p)->Write(p, b) -typedef struct ISeqInStream ISeqInStream; -struct ISeqInStream +Z7_C_IFACE_DECL (ISeqInStream) { - SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size); + SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) < input(*size)) is allowed */ }; #define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) +/* try to read as much as avail in stream and limited by (*processedSize) */ +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize); /* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf); +// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size); +// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf); -typedef struct ISeqOutStream ISeqOutStream; -struct ISeqOutStream +Z7_C_IFACE_DECL (ISeqOutStream) { - size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size); + size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size); /* Returns: result - the number of actually written bytes. (result < size) means error */ }; @@ -344,29 +369,26 @@ } ESzSeek; -typedef struct ISeekInStream ISeekInStream; -struct ISeekInStream +Z7_C_IFACE_DECL (ISeekInStream) { - SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin); + SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin); }; #define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) #define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) -typedef struct ILookInStream ILookInStream; -struct ILookInStream +Z7_C_IFACE_DECL (ILookInStream) { - SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size); + SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) > input(*size)) is not allowed (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(const ILookInStream *p, size_t offset); + SRes (*Skip)(ILookInStreamPtr p, size_t offset); /* offset must be <= output(*size) of Look */ - - SRes (*Read)(const ILookInStream *p, void *buf, size_t *size); + SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size); /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin); + SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin); }; #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) @@ -375,19 +397,18 @@ #define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) -SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset); +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset); /* reads via ILookInStream::Read */ -SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size); - +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size); typedef struct { ILookInStream vt; - const ISeekInStream *realStream; + ISeekInStreamPtr realStream; size_t pos; size_t size; /* it's data size */ @@ -399,13 +420,13 @@ void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); -#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; } +#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; } typedef struct { ISeqInStream vt; - const ILookInStream *realStream; + ILookInStreamPtr realStream; } CSecToLook; void SecToLook_CreateVTable(CSecToLook *p); @@ -415,20 +436,19 @@ typedef struct { ISeqInStream vt; - const ILookInStream *realStream; + ILookInStreamPtr realStream; } CSecToRead; void SecToRead_CreateVTable(CSecToRead *p); -typedef struct ICompressProgress ICompressProgress; - -struct ICompressProgress +Z7_C_IFACE_DECL (ICompressProgress) { - SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize); + SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize); /* Returns: result. (result != SZ_OK) means break. Value (UInt64)(Int64)-1 for size means unknown value. */ }; + #define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) @@ -466,13 +486,13 @@ -#ifndef MY_container_of +#ifndef Z7_container_of /* -#define MY_container_of(ptr, type, m) container_of(ptr, type, m) -#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) -#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) -#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +#define Z7_container_of(ptr, type, m) container_of(ptr, type, m) +#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) */ /* @@ -481,24 +501,64 @@ GCC 4.8.1 : classes with non-public variable members" */ -#define MY_container_of(ptr, type, m) ((type *)(void *)((char *)(void *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m))) +#define Z7_container_of(ptr, type, m) \ + ((type *)(void *)((char *)(void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +#define Z7_container_of_CONST(ptr, type, m) \ + ((const type *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +/* +#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \ + ((type *)(void *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) +*/ #endif -#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) +#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) -/* -#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) -*/ -#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) -#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) /* -#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m) */ +#if defined (__clang__) || defined(__GNUC__) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL +#endif + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \ + Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \ + Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p) -#define MY_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) +// #define ZIP7_DECLARE_HANDLE(name) typedef void *name; +#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name; + + +#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) + +#ifndef Z7_ARRAY_SIZE +#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + #ifdef _WIN32 @@ -527,3 +587,11 @@ EXTERN_C_END #endif + +/* +#ifndef Z7_ST +#ifdef _7ZIP_ST +#define Z7_ST +#endif +#endif +*/ diff -Nru 7zip-22.01+dfsg/C/7zVersion.h 7zip-22.01+really25.01+dfsg/C/7zVersion.h --- 7zip-22.01+dfsg/C/7zVersion.h 2022-07-15 13:00:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zVersion.h 2025-08-03 06:00:00.000000000 +0000 @@ -1,7 +1,7 @@ -#define MY_VER_MAJOR 22 -#define MY_VER_MINOR 01 +#define MY_VER_MAJOR 25 +#define MY_VER_MINOR 1 #define MY_VER_BUILD 0 -#define MY_VERSION_NUMBERS "22.01" +#define MY_VERSION_NUMBERS "25.01" #define MY_VERSION MY_VERSION_NUMBERS #ifdef MY_CPU_NAME @@ -10,12 +10,12 @@ #define MY_VERSION_CPU MY_VERSION #endif -#define MY_DATE "2022-07-15" +#define MY_DATE "2025-08-03" #undef MY_COPYRIGHT #undef MY_VERSION_COPYRIGHT_DATE #define MY_AUTHOR_NAME "Igor Pavlov" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" -#define MY_COPYRIGHT_CR "Copyright (c) 1999-2022 Igor Pavlov" +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2025 Igor Pavlov" #ifdef USE_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR diff -Nru 7zip-22.01+dfsg/C/7zWindows.h 7zip-22.01+really25.01+dfsg/C/7zWindows.h --- 7zip-22.01+dfsg/C/7zWindows.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zWindows.h 2023-04-02 11:00:00.000000000 +0000 @@ -0,0 +1,101 @@ +/* 7zWindows.h -- StdAfx +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_WINDOWS_H +#define ZIP7_INC_7Z_WINDOWS_H + +#ifdef _WIN32 + +#if defined(__clang__) +# pragma clang diagnostic push +#endif + +#if defined(_MSC_VER) + +#pragma warning(push) +#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + +#if _MSC_VER == 1900 +// for old kit10 versions +// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext': +#endif +// win10 Windows Kit: +#endif // _MSC_VER + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +// for msvc6 without sdk2003 +#define RPC_NO_WINDOWS_H +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +// #if defined(__GNUC__) && !defined(__clang__) +#include +#else +#include +#endif +// #include +// #include + +// but if precompiled with clang-cl then we need +// #include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +#ifndef _W64 + +typedef long LONG_PTR, *PLONG_PTR; +typedef unsigned long ULONG_PTR, *PULONG_PTR; +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + +#define Z7_OLD_WIN_SDK +#endif // _W64 +#endif // _MSC_VER == 1200 + +#ifdef Z7_OLD_WIN_SDK + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif +#ifndef FILE_SPECIAL_ACCESS +#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#endif + +// ShlObj.h: +// #define BIF_NEWDIALOGSTYLE 0x0040 + +#pragma warning(disable : 4201) +// #pragma warning(disable : 4115) + +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + +#endif // Z7_OLD_WIN_SDK + +#ifdef UNDER_CE +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + + +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 && _MSC_VER <= 1600 + // BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed + // string.h + // #pragma warning(disable : 4514) +#endif +#endif + + +/* #include "7zTypes.h" */ + +#endif diff -Nru 7zip-22.01+dfsg/C/7zip_gcc_c.mak 7zip-22.01+really25.01+dfsg/C/7zip_gcc_c.mak --- 7zip-22.01+dfsg/C/7zip_gcc_c.mak 2022-07-15 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/7zip_gcc_c.mak 2024-02-28 10:00:00.000000000 +0000 @@ -4,15 +4,28 @@ MY_ASM = jwasm MY_ASM = asmc +ifndef RC +#RC=windres.exe --target=pe-x86-64 +#RC=windres.exe -F pe-i386 +RC=windres.exe +endif + PROGPATH = $(O)/$(PROG) PROGPATH_STATIC = $(O)/$(PROG)s +ifneq ($(CC), xlc) +CFLAGS_WARN_WALL = -Wall -Werror -Wextra +endif # for object file CFLAGS_BASE_LIST = -c # for ASM file # CFLAGS_BASE_LIST = -S -CFLAGS_BASE = $(MY_ARCH_2) -O2 $(CFLAGS_BASE_LIST) -Wall -Werror -Wextra $(CFLAGS_WARN) \ + +FLAGS_FLTO = -flto +FLAGS_FLTO = + +CFLAGS_BASE = $(MY_ARCH_2) -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE @@ -93,9 +106,9 @@ endif -LIB2 = -lOle32 -loleaut32 -luuid -ladvapi32 -lUser32 +LIB2 = -lOle32 -loleaut32 -luuid -ladvapi32 -lUser32 -lShell32 -CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE +CFLAGS_EXTRA = -DUNICODE -D_UNICODE # -Wno-delete-non-virtual-dtor @@ -103,8 +116,8 @@ RM = rm -f MY_MKDIR=mkdir -p -# CFLAGS_BASE := $(CFLAGS_BASE) -D_7ZIP_ST -# CXXFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +# CFLAGS_BASE := $(CFLAGS_BASE) -DZ7_ST +# CFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE # LOCAL_LIBS=-lpthread # LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl @@ -115,10 +128,6 @@ endif - -CFLAGS = $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(CC_SHARED) -o $@ - - ifdef IS_X64 AFLAGS_ABI = -elf64 -DABI_LINUX else @@ -129,12 +138,9 @@ endif AFLAGS = $(AFLAGS_ABI) -Fo$(O)/ +C_WARN_FLAGS = -CXX_WARN_FLAGS = -#-Wno-invalid-offsetof -#-Wno-reorder - -CXXFLAGS = $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS) +CFLAGS = $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(CFLAGS_EXTRA) $(C_WARN_FLAGS) $(FLAGS_FLTO) $(CC_SHARED) -o $@ STATIC_TARGET= ifdef COMPL_STATIC @@ -147,18 +153,27 @@ $(O): $(MY_MKDIR) $(O) -LFLAGS_ALL = -s $(MY_ARCH_2) $(LDFLAGS) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) +ifneq ($(CC), $(CROSS_COMPILE)clang) +LFLAGS_STRIP = -s +endif + +LFLAGS_ALL = $(LFLAGS_STRIP) $(MY_ARCH_2) $(LDFLAGS) $(FLAGS_FLTO) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) $(PROGPATH): $(OBJS) - $(CXX) -o $(PROGPATH) $(LFLAGS_ALL) + $(CC) -o $(PROGPATH) $(LFLAGS_ALL) $(PROGPATH_STATIC): $(OBJS) - $(CXX) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL) + $(CC) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL) ifndef NO_DEFAULT_RES +# old mingw without -FO +# windres.exe $(RFLAGS) resource.rc $O/resource.o $O/resource.o: resource.rc - windres.exe $(RFLAGS) resource.rc $O/resource.o + $(RC) $(RFLAGS) resource.rc $(O)/resource.o endif +# windres.exe $(RFLAGS) resource.rc $(O)\resource.o +# windres.exe $(RFLAGS) resource.rc -FO $(O)/resource.o +# $(RC) $(RFLAGS) resource.rc -FO $(O)/resource.o @@ -256,10 +271,18 @@ $(CC) $(CFLAGS) $< $O/Sort.o: ../../../C/Sort.c $(CC) $(CFLAGS) $< +$O/SwapBytes.o: ../../../C/SwapBytes.c + $(CC) $(CFLAGS) $< $O/Xz.o: ../../../C/Xz.c $(CC) $(CFLAGS) $< $O/XzCrc64.o: ../../../C/XzCrc64.c $(CC) $(CFLAGS) $< +$O/XzDec.o: ../../../C/XzDec.c + $(CC) $(CFLAGS) $< +$O/XzEnc.o: ../../../C/XzEnc.c + $(CC) $(CFLAGS) $< +$O/XzIn.o: ../../../C/XzIn.c + $(CC) $(CFLAGS) $< ifdef USE_ASM @@ -306,11 +329,11 @@ ifdef IS_ARM64 $O/LzmaDecOpt.o: ../../../Asm/arm64/LzmaDecOpt.S ../../../Asm/arm64/7zAsm.S - $(CC) $(CFLAGS) $< + $(CC) $(CFLAGS) $(ASM_FLAGS) $< endif $O/LzmaDec.o: ../../LzmaDec.c - $(CC) $(CFLAGS) -D_LZMA_DEC_OPT $< + $(CC) $(CFLAGS) -DZ7_LZMA_DEC_OPT $< else @@ -321,22 +344,16 @@ -$O/XzDec.o: ../../../C/XzDec.c - $(CC) $(CFLAGS) $< -$O/XzEnc.o: ../../../C/XzEnc.c - $(CC) $(CFLAGS) $< -$O/XzIn.o: ../../../C/XzIn.c - $(CC) $(CFLAGS) $< - - $O/7zMain.o: ../../../C/Util/7z/7zMain.c $(CC) $(CFLAGS) $< -$O/LzmaUtil.o: ../../../C/Util/Lzma/LzmaUtil.c - $(CC) $(CFLAGS) $< $O/7zipInstall.o: ../../../C/Util/7zipInstall/7zipInstall.c $(CC) $(CFLAGS) $< $O/7zipUninstall.o: ../../../C/Util/7zipUninstall/7zipUninstall.c $(CC) $(CFLAGS) $< +$O/LzmaUtil.o: ../../../C/Util/Lzma/LzmaUtil.c + $(CC) $(CFLAGS) $< +$O/XzUtil.o: ../../../C/Util/Xz/XzUtil.c + $(CC) $(CFLAGS) $< clean: diff -Nru 7zip-22.01+dfsg/C/Aes.c 7zip-22.01+really25.01+dfsg/C/Aes.c --- 7zip-22.01+dfsg/C/Aes.c 2021-05-13 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Aes.c 2024-03-01 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Aes.c -- AES encryption / decryption -2021-05-13 : Igor Pavlov : Public domain */ +2024-03-01 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,13 +7,15 @@ #include "Aes.h" AES_CODE_FUNC g_AesCbc_Decode; -#ifndef _SFX +#ifndef Z7_SFX AES_CODE_FUNC g_AesCbc_Encode; AES_CODE_FUNC g_AesCtr_Code; UInt32 g_Aes_SupportedFunctions_Flags; #endif +MY_ALIGN(64) static UInt32 T[256 * 4]; +MY_ALIGN(64) static const Byte Sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, @@ -33,7 +35,9 @@ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; +MY_ALIGN(64) static UInt32 D[256 * 4]; +MY_ALIGN(64) static Byte InvS[256]; #define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) @@ -51,32 +55,62 @@ #define DD(x) (D + (x << 8)) -// #define _SHOW_AES_STATUS +// #define Z7_SHOW_AES_STATUS #ifdef MY_CPU_X86_OR_AMD64 - #define USE_HW_AES -#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define USE_HW_AES - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check + + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) #define USE_HW_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_HW_VAES + #endif #endif + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_HW_AES + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_HW_VAES + #endif #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 + #define USE_HW_AES + #define USE_HW_VAES + #endif + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) #define USE_HW_AES #endif + #endif + #endif #endif #endif #ifdef USE_HW_AES -#ifdef _SHOW_AES_STATUS +// #pragma message("=== Aes.c USE_HW_AES === ") +#ifdef Z7_SHOW_AES_STATUS #include -#define _PRF(x) x +#define PRF(x) x #else -#define _PRF(x) +#define PRF(x) #endif #endif @@ -90,23 +124,23 @@ for (i = 0; i < 256; i++) { { - UInt32 a1 = Sbox[i]; - UInt32 a2 = xtime(a1); - UInt32 a3 = a2 ^ a1; + const UInt32 a1 = Sbox[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a3 = a2 ^ a1; TT(0)[i] = Ui32(a2, a1, a1, a3); TT(1)[i] = Ui32(a3, a2, a1, a1); TT(2)[i] = Ui32(a1, a3, a2, a1); TT(3)[i] = Ui32(a1, a1, a3, a2); } { - UInt32 a1 = InvS[i]; - UInt32 a2 = xtime(a1); - UInt32 a4 = xtime(a2); - UInt32 a8 = xtime(a4); - UInt32 a9 = a8 ^ a1; - UInt32 aB = a8 ^ a2 ^ a1; - UInt32 aD = a8 ^ a4 ^ a1; - UInt32 aE = a8 ^ a4 ^ a2; + const UInt32 a1 = InvS[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a4 = xtime(a2); + const UInt32 a8 = xtime(a4); + const UInt32 a9 = a8 ^ a1; + const UInt32 aB = a8 ^ a2 ^ a1; + const UInt32 aD = a8 ^ a4 ^ a1; + const UInt32 aE = a8 ^ a4 ^ a2; DD(0)[i] = Ui32(aE, a9, aD, aB); DD(1)[i] = Ui32(aB, aE, a9, aD); DD(2)[i] = Ui32(aD, aB, aE, a9); @@ -116,7 +150,7 @@ { AES_CODE_FUNC d = AesCbc_Decode; - #ifndef _SFX + #ifndef Z7_SFX AES_CODE_FUNC e = AesCbc_Encode; AES_CODE_FUNC c = AesCtr_Code; UInt32 flags = 0; @@ -126,31 +160,33 @@ if (CPU_IsSupported_AES()) { // #pragma message ("AES HW") - _PRF(printf("\n===AES HW\n")); + PRF(printf("\n===AES HW\n")); d = AesCbc_Decode_HW; - #ifndef _SFX + #ifndef Z7_SFX e = AesCbc_Encode_HW; c = AesCtr_Code_HW; flags = k_Aes_SupportedFunctions_HW; #endif #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_HW_VAES if (CPU_IsSupported_VAES_AVX2()) { - _PRF(printf("\n===vaes avx2\n")); + PRF(printf("\n===vaes avx2\n")); d = AesCbc_Decode_HW_256; - #ifndef _SFX + #ifndef Z7_SFX c = AesCtr_Code_HW_256; flags |= k_Aes_SupportedFunctions_HW_256; #endif } #endif + #endif } #endif g_AesCbc_Decode = d; - #ifndef _SFX + #ifndef Z7_SFX g_AesCbc_Encode = e; g_AesCtr_Code = c; g_Aes_SupportedFunctions_Flags = flags; @@ -194,7 +230,7 @@ #define FD(i, x) InvS[gb(x, m[(i - x) & 3])] #define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) { unsigned i, m; const UInt32 *wLim; @@ -230,7 +266,7 @@ while (++w != wLim); } -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) { unsigned i, num; Aes_SetKey_Enc(w, key, keySize); @@ -251,7 +287,7 @@ src and dest are pointers to 4 UInt32 words. src and dest can point to same block */ -// MY_FORCE_INLINE +// Z7_FORCE_INLINE static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) { UInt32 s[4]; @@ -265,17 +301,20 @@ w += 4; for (;;) { - HT16(m, s, 0); + HT16(m, s, 0) if (--numRounds2 == 0) break; - HT16(s, m, 4); + HT16(s, m, 4) w += 8; } w += 4; - FT4(0); FT4(1); FT4(2); FT4(3); + FT4(0) + FT4(1) + FT4(2) + FT4(3) } -MY_FORCE_INLINE +Z7_FORCE_INLINE static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) { UInt32 s[4]; @@ -289,12 +328,15 @@ for (;;) { w -= 8; - HD16(m, s, 4); + HD16(m, s, 4) if (--numRounds2 == 0) break; - HD16(s, m, 0); + HD16(s, m, 0) } - FD4(0); FD4(1); FD4(2); FD4(3); + FD4(0) + FD4(1) + FD4(2) + FD4(3) } void AesCbc_Init(UInt32 *p, const Byte *iv) @@ -304,7 +346,7 @@ p[i] = GetUi32(iv + i * 4); } -void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) +void Z7_FASTCALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) { for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) { @@ -315,14 +357,14 @@ Aes_Encode(p + 4, p, p); - SetUi32(data, p[0]); - SetUi32(data + 4, p[1]); - SetUi32(data + 8, p[2]); - SetUi32(data + 12, p[3]); + SetUi32(data, p[0]) + SetUi32(data + 4, p[1]) + SetUi32(data + 8, p[2]) + SetUi32(data + 12, p[3]) } } -void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) +void Z7_FASTCALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) { UInt32 in[4], out[4]; for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) @@ -334,10 +376,10 @@ Aes_Decode(p + 4, out, in); - SetUi32(data, p[0] ^ out[0]); - SetUi32(data + 4, p[1] ^ out[1]); - SetUi32(data + 8, p[2] ^ out[2]); - SetUi32(data + 12, p[3] ^ out[3]); + SetUi32(data, p[0] ^ out[0]) + SetUi32(data + 4, p[1] ^ out[1]) + SetUi32(data + 8, p[2] ^ out[2]) + SetUi32(data + 12, p[3] ^ out[3]) p[0] = in[0]; p[1] = in[1]; @@ -346,7 +388,7 @@ } } -void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) +void Z7_FASTCALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) { for (; numBlocks != 0; numBlocks--) { @@ -360,7 +402,7 @@ for (i = 0; i < 4; i++, data += 4) { - UInt32 t = temp[i]; + const UInt32 t = temp[i]; #ifdef MY_CPU_LE_UNALIGN *((UInt32 *)(void *)data) ^= t; @@ -373,3 +415,15 @@ } } } + +#undef xtime +#undef Ui32 +#undef gb0 +#undef gb1 +#undef gb2 +#undef gb3 +#undef gb +#undef TT +#undef DD +#undef USE_HW_AES +#undef PRF diff -Nru 7zip-22.01+dfsg/C/Aes.h 7zip-22.01+really25.01+dfsg/C/Aes.h --- 7zip-22.01+dfsg/C/Aes.h 2019-08-28 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Aes.h 2023-04-02 11:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Aes.h -- AES encryption / decryption -2018-04-28 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __AES_H -#define __AES_H +#ifndef ZIP7_INC_AES_H +#define ZIP7_INC_AES_H #include "7zTypes.h" @@ -20,19 +20,19 @@ /* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ /* keySize = 16 or 24 or 32 (bytes) */ -typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); +typedef void (Z7_FASTCALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); /* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ /* data - 16-byte aligned pointer to data */ /* numBlocks - the number of 16-byte blocks in data array */ -typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); +typedef void (Z7_FASTCALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); extern AES_CODE_FUNC g_AesCbc_Decode; -#ifndef _SFX +#ifndef Z7_SFX extern AES_CODE_FUNC g_AesCbc_Encode; extern AES_CODE_FUNC g_AesCtr_Code; #define k_Aes_SupportedFunctions_HW (1 << 2) @@ -41,19 +41,19 @@ #endif -#define DECLARE__AES_CODE_FUNC(funcName) \ - void MY_FAST_CALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks); +#define Z7_DECLARE_AES_CODE_FUNC(funcName) \ + void Z7_FASTCALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks); -DECLARE__AES_CODE_FUNC (AesCbc_Encode) -DECLARE__AES_CODE_FUNC (AesCbc_Decode) -DECLARE__AES_CODE_FUNC (AesCtr_Code) - -DECLARE__AES_CODE_FUNC (AesCbc_Encode_HW) -DECLARE__AES_CODE_FUNC (AesCbc_Decode_HW) -DECLARE__AES_CODE_FUNC (AesCtr_Code_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code) + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW) -DECLARE__AES_CODE_FUNC (AesCbc_Decode_HW_256) -DECLARE__AES_CODE_FUNC (AesCtr_Code_HW_256) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW_256) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW_256) EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/AesOpt.c 7zip-22.01+really25.01+dfsg/C/AesOpt.c --- 7zip-22.01+dfsg/C/AesOpt.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/AesOpt.c 2024-11-24 15:00:00.000000000 +0000 @@ -1,39 +1,33 @@ /* AesOpt.c -- AES optimized code for x86 AES hardware instructions -2021-04-01 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ #include "Precomp.h" +#include "Aes.h" #include "CpuArch.h" #ifdef MY_CPU_X86_OR_AMD64 - #if defined(__clang__) - #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 8) - #define USE_INTEL_AES - #define ATTRIB_AES __attribute__((__target__("aes"))) - #if (__clang_major__ >= 8) - #define USE_INTEL_VAES - #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx2"))) - #endif - #endif - #elif defined(__GNUC__) - #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) - #define USE_INTEL_AES - #ifndef __AES__ - #define ATTRIB_AES __attribute__((__target__("aes"))) - #endif - #if (__GNUC__ >= 8) - #define USE_INTEL_VAES - #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx2"))) - #endif - #endif - #elif defined(__INTEL_COMPILER) + #if defined(__INTEL_COMPILER) #if (__INTEL_COMPILER >= 1110) #define USE_INTEL_AES #if (__INTEL_COMPILER >= 1900) #define USE_INTEL_VAES #endif #endif + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_INTEL_AES + #if !defined(__AES__) + #define ATTRIB_AES __attribute__((__target__("aes"))) + #endif + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_INTEL_VAES + #if !defined(__AES__) || !defined(__VAES__) || !defined(__AVX__) || !defined(__AVX2__) + #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx,avx2"))) + #endif + #endif #elif defined(_MSC_VER) #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) #define USE_INTEL_AES @@ -41,27 +35,40 @@ #define USE_INTEL_VAES #endif #endif + #ifndef USE_INTEL_AES + #define Z7_USE_AES_HW_STUB + #endif + #ifndef USE_INTEL_VAES + #define Z7_USE_VAES_HW_STUB + #endif #endif -#ifndef ATTRIB_AES - #define ATTRIB_AES -#endif -#ifndef ATTRIB_VAES - #define ATTRIB_VAES -#endif + #ifndef USE_INTEL_AES + // #define Z7_USE_AES_HW_STUB // for debug + #endif + #ifndef USE_INTEL_VAES + // #define Z7_USE_VAES_HW_STUB // for debug + #endif #ifdef USE_INTEL_AES #include -#ifndef USE_INTEL_VAES -#define AES_TYPE_keys __m128i -#define AES_TYPE_data __m128i +#if !defined(USE_INTEL_VAES) && defined(Z7_USE_VAES_HW_STUB) +#define AES_TYPE_keys UInt32 +#define AES_TYPE_data Byte +// #define AES_TYPE_keys __m128i +// #define AES_TYPE_data __m128i +#endif + +#ifndef ATTRIB_AES + #define ATTRIB_AES #endif #define AES_FUNC_START(name) \ - void MY_FAST_CALL name(__m128i *p, __m128i *data, size_t numBlocks) + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(__m128i *p, __m128i *data, size_t numBlocks) #define AES_FUNC_START2(name) \ AES_FUNC_START (name); \ @@ -69,49 +76,72 @@ AES_FUNC_START (name) #define MM_OP(op, dest, src) dest = op(dest, src); -#define MM_OP_m(op, src) MM_OP(op, m, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) -#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src); -#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src); +#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src) +#if 1 +// use aligned SSE load/store for data. +// It is required for our Aes functions, that data is aligned for 16-bytes. +// So we can use this branch of code. +// and compiler can use fused load-op SSE instructions: +// xorps xmm0, XMMWORD PTR [rdx] +#define LOAD_128(pp) (*(__m128i *)(void *)(pp)) +#define STORE_128(pp, _v) *(__m128i *)(void *)(pp) = _v +// use aligned SSE load/store for data. Alternative code with direct access +// #define LOAD_128(pp) _mm_load_si128(pp) +// #define STORE_128(pp, _v) _mm_store_si128(pp, _v) +#else +// use unaligned load/store for data: movdqu XMMWORD PTR [rdx] +#define LOAD_128(pp) _mm_loadu_si128(pp) +#define STORE_128(pp, _v) _mm_storeu_si128(pp, _v) +#endif AES_FUNC_START2 (AesCbc_Encode_HW) { + if (numBlocks == 0) + return; + { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; __m128i m = *p; const __m128i k0 = p[2]; const __m128i k1 = p[3]; const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; - for (; numBlocks != 0; numBlocks--, data++) + do { UInt32 r = numRounds2; const __m128i *w = p + 4; - __m128i temp = *data; - MM_XOR (temp, k0); - MM_XOR (m, temp); - MM_OP_m (_mm_aesenc_si128, k1); + __m128i temp = LOAD_128(data); + MM_XOR (temp, k0) + MM_XOR (m, temp) + MM_OP_m (_mm_aesenc_si128, k1) do { - MM_OP_m (_mm_aesenc_si128, w[0]); - MM_OP_m (_mm_aesenc_si128, w[1]); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) w += 2; } while (--r); - MM_OP_m (_mm_aesenclast_si128, w[0]); - *data = m; + MM_OP_m (_mm_aesenclast_si128, w[0]) + STORE_128(data, m); + data++; } + while (--numBlocks); *p = m; + } } #define WOP_1(op) -#define WOP_2(op) WOP_1 (op) op (m1, 1); -#define WOP_3(op) WOP_2 (op) op (m2, 2); -#define WOP_4(op) WOP_3 (op) op (m3, 3); +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) #ifdef MY_CPU_AMD64 -#define WOP_5(op) WOP_4 (op) op (m4, 4); -#define WOP_6(op) WOP_5 (op) op (m5, 5); -#define WOP_7(op) WOP_6 (op) op (m6, 6); -#define WOP_8(op) WOP_7 (op) op (m7, 7); +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) #endif /* #define WOP_9(op) WOP_8 (op) op (m8, 8); @@ -130,21 +160,16 @@ #define WOP_M1 WOP_4 #endif -#define WOP(op) op (m0, 0); WOP_M1(op) +#define WOP(op) op (m0, 0) WOP_M1(op) - -#define DECLARE_VAR(reg, ii) __m128i reg -#define LOAD_data( reg, ii) reg = data[ii]; -#define STORE_data( reg, ii) data[ii] = reg; +#define DECLARE_VAR(reg, ii) __m128i reg; +#define LOAD_data_ii(ii) LOAD_128(data + (ii)) +#define LOAD_data( reg, ii) reg = LOAD_data_ii(ii); +#define STORE_data( reg, ii) STORE_128(data + (ii), reg); #if (NUM_WAYS > 1) -#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]); +#define XOR_data_M1(reg, ii) MM_XOR (reg, LOAD_128(data + (ii- 1))) #endif -#define AVX__DECLARE_VAR(reg, ii) __m256i reg -#define AVX__LOAD_data( reg, ii) reg = ((const __m256i *)(const void *)data)[ii]; -#define AVX__STORE_data( reg, ii) ((__m256i *)(void *)data)[ii] = reg; -#define AVX__XOR_data_M1(reg, ii) AVX_XOR (reg, (((const __m256i *)(const void *)(data - 1))[ii])); - #define MM_OP_key(op, reg) MM_OP(op, reg, key); #define AES_DEC( reg, ii) MM_OP_key (_mm_aesdec_si128, reg) @@ -153,116 +178,156 @@ #define AES_ENC_LAST( reg, ii) MM_OP_key (_mm_aesenclast_si128, reg) #define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg) - -#define AVX__AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg) -#define AVX__AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg) -#define AVX__AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg) -#define AVX__AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg) -#define AVX__AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg) - -#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one); reg = ctr; -#define CTR_END( reg, ii) MM_XOR (data[ii], reg); - -#define AVX__CTR_START(reg, ii) MM_OP (_mm256_add_epi64, ctr2, two); reg = _mm256_xor_si256(ctr2, key); -#define AVX__CTR_END( reg, ii) AVX_XOR (((__m256i *)(void *)data)[ii], reg); - +#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr; +#define CTR_END( reg, ii) STORE_128(data + (ii), _mm_xor_si128(reg, \ + LOAD_128 (data + (ii)))); #define WOP_KEY(op, n) { \ const __m128i key = w[n]; \ - WOP(op); } - -#define AVX__WOP_KEY(op, n) { \ - const __m256i key = w[n]; \ - WOP(op); } - + WOP(op) } #define WIDE_LOOP_START \ dataEnd = data + numBlocks; \ if (numBlocks >= NUM_WAYS) \ { dataEnd -= NUM_WAYS; do { \ - #define WIDE_LOOP_END \ data += NUM_WAYS; \ } while (data <= dataEnd); \ dataEnd += NUM_WAYS; } \ - #define SINGLE_LOOP \ for (; data < dataEnd; data++) + +#ifdef USE_INTEL_VAES + +#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src) +#define AVX_DECLARE_VAR(reg, ii) __m256i reg; + +#if 1 +// use unaligned AVX load/store for data. +// It is required for our Aes functions, that data is aligned for 16-bytes. +// But we need 32-bytes reading. +// So we use intrinsics for unaligned AVX load/store. +// notes for _mm256_storeu_si256: +// msvc2022: uses vmovdqu and keeps the order of instruction sequence. +// new gcc11 uses vmovdqu +// old gcc9 could use pair of instructions: +// vmovups %xmm7, -224(%rax) +// vextracti128 $0x1, %ymm7, -208(%rax) +#define AVX_LOAD(p) _mm256_loadu_si256((const __m256i *)(const void *)(p)) +#define AVX_STORE(p, _v) _mm256_storeu_si256((__m256i *)(void *)(p), _v); +#else +// use aligned AVX load/store for data. +// for debug: we can use this branch, if we are sure that data is aligned for 32-bytes. +// msvc2022 uses vmovdqu still +// gcc uses vmovdqa (that requires 32-bytes alignment) +#define AVX_LOAD(p) (*(const __m256i *)(const void *)(p)) +#define AVX_STORE(p, _v) (*(__m256i *)(void *)(p)) = _v; +#endif + +#define AVX_LOAD_data( reg, ii) reg = AVX_LOAD((const __m256i *)(const void *)data + (ii)); +#define AVX_STORE_data( reg, ii) AVX_STORE((__m256i *)(void *)data + (ii), reg) +/* +AVX_XOR_data_M1() needs unaligned memory load, even if (data) +is aligned for 256-bits, because we read 32-bytes chunk that +crosses (data) position: from (data - 16bytes) to (data + 16bytes). +*/ +#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, _mm256_loadu_si256((const __m256i *)(const void *)(data - 1) + (ii))) + +#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg) +#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg) +#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg) +#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg) +#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg) +#define AVX_CTR_START(reg, ii) \ + MM_OP (_mm256_add_epi64, ctr2, two) \ + reg = _mm256_xor_si256(ctr2, key); + +#define AVX_CTR_END(reg, ii) \ + AVX_STORE((__m256i *)(void *)data + (ii), _mm256_xor_si256(reg, \ + AVX_LOAD ((__m256i *)(void *)data + (ii)))); + +#define AVX_WOP_KEY(op, n) { \ + const __m256i key = w[n]; \ + WOP(op) } + #define NUM_AES_KEYS_MAX 15 #define WIDE_LOOP_START_AVX(OP) \ dataEnd = data + numBlocks; \ if (numBlocks >= NUM_WAYS * 2) \ - { __m256i keys[NUM_AES_KEYS_MAX]; \ - UInt32 ii; \ - OP \ - for (ii = 0; ii < numRounds; ii++) \ - keys[ii] = _mm256_broadcastsi128_si256(p[ii]); \ - dataEnd -= NUM_WAYS * 2; do { \ - + { __m256i keys[NUM_AES_KEYS_MAX]; \ + OP \ + { UInt32 ii; for (ii = 0; ii < numRounds; ii++) \ + keys[ii] = _mm256_broadcastsi128_si256(p[ii]); } \ + dataEnd -= NUM_WAYS * 2; \ + do { \ #define WIDE_LOOP_END_AVX(OP) \ - data += NUM_WAYS * 2; \ - } while (data <= dataEnd); \ - dataEnd += NUM_WAYS * 2; \ - OP \ - _mm256_zeroupper(); \ + data += NUM_WAYS * 2; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS * 2; \ + OP \ + _mm256_zeroupper(); \ } \ /* MSVC for x86: If we don't call _mm256_zeroupper(), and -arch:IA32 is not specified, MSVC still can insert vzeroupper instruction. */ +#endif + + AES_FUNC_START2 (AesCbc_Decode_HW) { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; __m128i iv = *p; - const __m128i *wStart = p + *(const UInt32 *)(p + 1) * 2 + 2 - 1; + const __m128i * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2 + 2 - 1; const __m128i *dataEnd; p += 2; WIDE_LOOP_START { const __m128i *w = wStart; - WOP (DECLARE_VAR) - WOP (LOAD_data); + WOP (LOAD_data) WOP_KEY (AES_XOR, 1) - do { WOP_KEY (AES_DEC, 0) + w--; } while (w != p); WOP_KEY (AES_DEC_LAST, 0) - MM_XOR (m0, iv); + MM_XOR (m0, iv) WOP_M1 (XOR_data_M1) - iv = data[NUM_WAYS - 1]; - WOP (STORE_data); + LOAD_data(iv, NUM_WAYS - 1) + WOP (STORE_data) } WIDE_LOOP_END SINGLE_LOOP { const __m128i *w = wStart - 1; - __m128i m = _mm_xor_si128 (w[2], *data); + __m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0)); + do { - MM_OP_m (_mm_aesdec_si128, w[1]); - MM_OP_m (_mm_aesdec_si128, w[0]); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) w -= 2; } while (w != p); - MM_OP_m (_mm_aesdec_si128, w[1]); - MM_OP_m (_mm_aesdeclast_si128, w[0]); - - MM_XOR (m, iv); - iv = *data; - *data = m; + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) + MM_XOR (m, iv) + LOAD_data(iv, 0) + STORE_data(m, 0) } p[-2] = iv; @@ -271,10 +336,12 @@ AES_FUNC_START2 (AesCtr_Code_HW) { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; __m128i ctr = *p; - UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1; + const UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1; const __m128i *dataEnd; - __m128i one = _mm_cvtsi32_si128(1); + const __m128i one = _mm_cvtsi32_si128(1); p += 2; @@ -283,7 +350,7 @@ const __m128i *w = p; UInt32 r = numRoundsMinus2; WOP (DECLARE_VAR) - WOP (CTR_START); + WOP (CTR_START) WOP_KEY (AES_XOR, 0) w += 1; do @@ -293,8 +360,7 @@ } while (--r); WOP_KEY (AES_ENC_LAST, 0) - - WOP (CTR_END); + WOP (CTR_END) } WIDE_LOOP_END @@ -303,19 +369,19 @@ UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; const __m128i *w = p; __m128i m; - MM_OP (_mm_add_epi64, ctr, one); + MM_OP (_mm_add_epi64, ctr, one) m = _mm_xor_si128 (ctr, p[0]); w += 1; do { - MM_OP_m (_mm_aesenc_si128, w[0]); - MM_OP_m (_mm_aesenc_si128, w[1]); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) w += 2; } while (--numRounds2); - MM_OP_m (_mm_aesenc_si128, w[0]); - MM_OP_m (_mm_aesenclast_si128, w[1]); - MM_XOR (*data, m); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + CTR_END (m, 0) } p[-2] = ctr; @@ -325,17 +391,61 @@ #ifdef USE_INTEL_VAES +/* +GCC before 2013-Jun: + : + #ifdef __AVX__ + #include + #endif +GCC after 2013-Jun: + : + #include +CLANG 3.8+: +{ + : + #if !defined(_MSC_VER) || defined(__AVX__) + #include + #endif + + if (the compiler is clang for Windows and if global arch is not set for __AVX__) + [ if (defined(_MSC_VER) && !defined(__AVX__)) ] + { + doesn't include + and we have 2 ways to fix it: + 1) we can define required __AVX__ before + or + 2) we can include after + } +} + +If we include manually for GCC/CLANG, it's +required that must be included before . +*/ + +/* #if defined(__clang__) && defined(_MSC_VER) -#define __SSE4_2__ -#define __AES__ #define __AVX__ #define __AVX2__ #define __VAES__ -#define __AVX512F__ -#define __AVX512VL__ #endif +*/ #include +#if defined(__clang__) && defined(_MSC_VER) + #if !defined(__AVX__) + #include + #endif + #if !defined(__AVX2__) + #include + #endif + #if !defined(__VAES__) + #include + #endif +#endif // __clang__ && _MSC_VER + +#ifndef ATTRIB_VAES + #define ATTRIB_VAES +#endif #define VAES_FUNC_START2(name) \ AES_FUNC_START (name); \ @@ -344,51 +454,53 @@ VAES_FUNC_START2 (AesCbc_Decode_HW_256) { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; __m128i iv = *p; const __m128i *dataEnd; - UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; p += 2; WIDE_LOOP_START_AVX(;) { const __m256i *w = keys + numRounds - 2; - WOP (AVX__DECLARE_VAR) - WOP (AVX__LOAD_data); - AVX__WOP_KEY (AVX__AES_XOR, 1) + WOP (AVX_DECLARE_VAR) + WOP (AVX_LOAD_data) + AVX_WOP_KEY (AVX_AES_XOR, 1) do { - AVX__WOP_KEY (AVX__AES_DEC, 0) + AVX_WOP_KEY (AVX_AES_DEC, 0) w--; } while (w != keys); - AVX__WOP_KEY (AVX__AES_DEC_LAST, 0) + AVX_WOP_KEY (AVX_AES_DEC_LAST, 0) - AVX_XOR (m0, _mm256_setr_m128i(iv, data[0])); - WOP_M1 (AVX__XOR_data_M1) - iv = data[NUM_WAYS * 2 - 1]; - WOP (AVX__STORE_data); + AVX_XOR (m0, _mm256_setr_m128i(iv, LOAD_data_ii(0))) + WOP_M1 (AVX_XOR_data_M1) + LOAD_data (iv, NUM_WAYS * 2 - 1) + WOP (AVX_STORE_data) } WIDE_LOOP_END_AVX(;) SINGLE_LOOP { - const __m128i *w = p + *(const UInt32 *)(p + 1 - 2) * 2 + 1 - 3; - __m128i m = _mm_xor_si128 (w[2], *data); + const __m128i *w = p - 2 + (size_t)*(const UInt32 *)(p + 1 - 2) * 2; + __m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0)); do { - MM_OP_m (_mm_aesdec_si128, w[1]); - MM_OP_m (_mm_aesdec_si128, w[0]); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) w -= 2; } while (w != p); - MM_OP_m (_mm_aesdec_si128, w[1]); - MM_OP_m (_mm_aesdeclast_si128, w[0]); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) - MM_XOR (m, iv); - iv = *data; - *data = m; + MM_XOR (m, iv) + LOAD_data(iv, 0) + STORE_data(m, 0) } p[-2] = iv; @@ -403,63 +515,65 @@ _mm256_broadcastsi128_si256 : vbroadcasti128 */ -#define AVX__CTR_LOOP_START \ +#define AVX_CTR_LOOP_START \ ctr2 = _mm256_setr_m128i(_mm_sub_epi64(ctr, one), ctr); \ two = _mm256_setr_m128i(one, one); \ two = _mm256_add_epi64(two, two); \ // two = _mm256_setr_epi64x(2, 0, 2, 0); -#define AVX__CTR_LOOP_ENC \ +#define AVX_CTR_LOOP_ENC \ ctr = _mm256_extracti128_si256 (ctr2, 1); \ VAES_FUNC_START2 (AesCtr_Code_HW_256) { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; __m128i ctr = *p; - UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; const __m128i *dataEnd; - __m128i one = _mm_cvtsi32_si128(1); + const __m128i one = _mm_cvtsi32_si128(1); __m256i ctr2, two; p += 2; - WIDE_LOOP_START_AVX (AVX__CTR_LOOP_START) + WIDE_LOOP_START_AVX (AVX_CTR_LOOP_START) { const __m256i *w = keys; UInt32 r = numRounds - 2; - WOP (AVX__DECLARE_VAR) - AVX__WOP_KEY (AVX__CTR_START, 0); + WOP (AVX_DECLARE_VAR) + AVX_WOP_KEY (AVX_CTR_START, 0) w += 1; do { - AVX__WOP_KEY (AVX__AES_ENC, 0) + AVX_WOP_KEY (AVX_AES_ENC, 0) w += 1; } while (--r); - AVX__WOP_KEY (AVX__AES_ENC_LAST, 0) + AVX_WOP_KEY (AVX_AES_ENC_LAST, 0) - WOP (AVX__CTR_END); + WOP (AVX_CTR_END) } - WIDE_LOOP_END_AVX (AVX__CTR_LOOP_ENC) + WIDE_LOOP_END_AVX (AVX_CTR_LOOP_ENC) SINGLE_LOOP { UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; const __m128i *w = p; __m128i m; - MM_OP (_mm_add_epi64, ctr, one); + MM_OP (_mm_add_epi64, ctr, one) m = _mm_xor_si128 (ctr, p[0]); w += 1; do { - MM_OP_m (_mm_aesenc_si128, w[0]); - MM_OP_m (_mm_aesenc_si128, w[1]); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) w += 2; } while (--numRounds2); - MM_OP_m (_mm_aesenc_si128, w[0]); - MM_OP_m (_mm_aesenclast_si128, w[1]); - MM_XOR (*data, m); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + CTR_END (m, 0) } p[-2] = ctr; @@ -471,13 +585,21 @@ /* no USE_INTEL_AES */ +#if defined(Z7_USE_AES_HW_STUB) +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. +// #if defined(_MSC_VER) #pragma message("AES HW_SW stub was used") +// #endif +#if !defined(USE_INTEL_VAES) && defined(Z7_USE_VAES_HW_STUB) #define AES_TYPE_keys UInt32 #define AES_TYPE_data Byte +#endif #define AES_FUNC_START(name) \ - void MY_FAST_CALL name(UInt32 *p, Byte *data, size_t numBlocks) \ + void Z7_FASTCALL name(UInt32 *p, Byte *data, size_t numBlocks) \ #define AES_COMPAT_STUB(name) \ AES_FUNC_START(name); \ @@ -487,51 +609,77 @@ AES_COMPAT_STUB (AesCbc_Encode) AES_COMPAT_STUB (AesCbc_Decode) AES_COMPAT_STUB (AesCtr_Code) +#endif // Z7_USE_AES_HW_STUB #endif // USE_INTEL_AES #ifndef USE_INTEL_VAES - +#if defined(Z7_USE_VAES_HW_STUB) +// #if defined(_MSC_VER) #pragma message("VAES HW_SW stub was used") +// #endif #define VAES_COMPAT_STUB(name) \ - void MY_FAST_CALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks); \ - void MY_FAST_CALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks) \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks); \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks) \ { name((AES_TYPE_keys *)(void *)p, (AES_TYPE_data *)(void *)data, numBlocks); } VAES_COMPAT_STUB (AesCbc_Decode_HW) VAES_COMPAT_STUB (AesCtr_Code_HW) - +#endif #endif // ! USE_INTEL_VAES + + #elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) #define USE_HW_AES #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_AES #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_AES #endif #endif #ifdef USE_HW_AES // #pragma message("=== AES HW === ") +// __ARM_FEATURE_CRYPTO macro is deprecated in favor of the finer grained feature macro __ARM_FEATURE_AES #if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_AES) && \ + !defined(__ARM_FEATURE_CRYPTO) #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_AES __attribute__((__target__("crypto"))) +#else #define ATTRIB_AES __attribute__((__target__("+crypto"))) +#endif #else +#if defined(__clang__) + #define ATTRIB_AES __attribute__((__target__("armv8-a,aes"))) +#else #define ATTRIB_AES __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif #endif +#endif #else // _MSC_VER // for arm32 @@ -542,16 +690,65 @@ #define ATTRIB_AES #endif -#if defined(_MSC_VER) && defined(MY_CPU_ARM64) +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) #include #else +/* + clang-17.0.1: error : Cannot select: intrinsic %llvm.arm.neon.aese + clang + 3.8.1 : __ARM_NEON : defined(__ARM_FEATURE_CRYPTO) + 7.0.1 : __ARM_NEON : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO) + 11.?.0 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO) + 13.0.1 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_AES) + 16 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 +*/ +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_AES) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_AES 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + #include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_AES) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_AES + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") #endif +#endif // Z7_MSC_VER_ORIGINAL + typedef uint8x16_t v128; #define AES_FUNC_START(name) \ - void MY_FAST_CALL name(v128 *p, v128 *data, size_t numBlocks) + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(v128 *p, v128 *data, size_t numBlocks) #define AES_FUNC_START2(name) \ AES_FUNC_START (name); \ @@ -559,19 +756,26 @@ AES_FUNC_START (name) #define MM_OP(op, dest, src) dest = op(dest, src); -#define MM_OP_m(op, src) MM_OP(op, m, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) #define MM_OP1_m(op) m = op(m); -#define MM_XOR( dest, src) MM_OP(veorq_u8, dest, src); -#define MM_XOR_m( src) MM_XOR(m, src); +#define MM_XOR( dest, src) MM_OP(veorq_u8, dest, src) +#define MM_XOR_m( src) MM_XOR(m, src) -#define AES_E_m(k) MM_OP_m (vaeseq_u8, k); -#define AES_E_MC_m(k) AES_E_m (k); MM_OP1_m(vaesmcq_u8); +#define AES_E_m(k) MM_OP_m (vaeseq_u8, k) +#define AES_E_MC_m(k) AES_E_m (k) MM_OP1_m(vaesmcq_u8) AES_FUNC_START2 (AesCbc_Encode_HW) { + if (numBlocks == 0) + return; + { + v128 * const p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; v128 m = *p; + const UInt32 numRounds2 = *(const UInt32 *)(p + 1); + const v128 *w = p + (size_t)numRounds2 * 2; const v128 k0 = p[2]; const v128 k1 = p[3]; const v128 k2 = p[4]; @@ -582,79 +786,84 @@ const v128 k7 = p[9]; const v128 k8 = p[10]; const v128 k9 = p[11]; - const UInt32 numRounds2 = *(const UInt32 *)(p + 1); - const v128 *w = p + ((size_t)numRounds2 * 2); + const v128 k_z4 = w[-2]; + const v128 k_z3 = w[-1]; + const v128 k_z2 = w[0]; const v128 k_z1 = w[1]; const v128 k_z0 = w[2]; - for (; numBlocks != 0; numBlocks--, data++) + // we don't use optimization veorq_u8(*data, k_z0) that can reduce one cycle, + // because gcc/clang compilers are not good for that optimization. + do { - MM_XOR_m (*data); + MM_XOR_m (*data) AES_E_MC_m (k0) AES_E_MC_m (k1) AES_E_MC_m (k2) AES_E_MC_m (k3) AES_E_MC_m (k4) AES_E_MC_m (k5) - AES_E_MC_m (k6) - AES_E_MC_m (k7) - AES_E_MC_m (k8) if (numRounds2 >= 6) { - AES_E_MC_m (k9) - AES_E_MC_m (p[12]) + AES_E_MC_m (k6) + AES_E_MC_m (k7) if (numRounds2 != 6) { - AES_E_MC_m (p[13]) - AES_E_MC_m (p[14]) + AES_E_MC_m (k8) + AES_E_MC_m (k9) } } - AES_E_m (k_z1); - MM_XOR_m (k_z0); - *data = m; + AES_E_MC_m (k_z4) + AES_E_MC_m (k_z3) + AES_E_MC_m (k_z2) + AES_E_m (k_z1) + MM_XOR_m (k_z0) + *data++ = m; } + while (--numBlocks); *p = m; + } } #define WOP_1(op) -#define WOP_2(op) WOP_1 (op) op (m1, 1); -#define WOP_3(op) WOP_2 (op) op (m2, 2); -#define WOP_4(op) WOP_3 (op) op (m3, 3); -#define WOP_5(op) WOP_4 (op) op (m4, 4); -#define WOP_6(op) WOP_5 (op) op (m5, 5); -#define WOP_7(op) WOP_6 (op) op (m6, 6); -#define WOP_8(op) WOP_7 (op) op (m7, 7); +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) #define NUM_WAYS 8 #define WOP_M1 WOP_8 -#define WOP(op) op (m0, 0); WOP_M1(op) +#define WOP(op) op (m0, 0) WOP_M1(op) -#define DECLARE_VAR(reg, ii) v128 reg +#define DECLARE_VAR(reg, ii) v128 reg; #define LOAD_data( reg, ii) reg = data[ii]; #define STORE_data( reg, ii) data[ii] = reg; #if (NUM_WAYS > 1) -#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]); +#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) #endif -#define MM_OP_key(op, reg) MM_OP (op, reg, key); +#define MM_OP_key(op, reg) MM_OP (op, reg, key) -#define AES_D_m(k) MM_OP_m (vaesdq_u8, k); -#define AES_D_IMC_m(k) AES_D_m (k); MM_OP1_m (vaesimcq_u8); +#define AES_D_m(k) MM_OP_m (vaesdq_u8, k) +#define AES_D_IMC_m(k) AES_D_m (k) MM_OP1_m (vaesimcq_u8) #define AES_XOR( reg, ii) MM_OP_key (veorq_u8, reg) #define AES_D( reg, ii) MM_OP_key (vaesdq_u8, reg) #define AES_E( reg, ii) MM_OP_key (vaeseq_u8, reg) -#define AES_D_IMC( reg, ii) AES_D (reg, ii); reg = vaesimcq_u8(reg) -#define AES_E_MC( reg, ii) AES_E (reg, ii); reg = vaesmcq_u8(reg) +#define AES_D_IMC( reg, ii) AES_D (reg, ii) reg = vaesimcq_u8(reg); +#define AES_E_MC( reg, ii) AES_E (reg, ii) reg = vaesmcq_u8(reg); -#define CTR_START(reg, ii) MM_OP (vaddq_u64, ctr, one); reg = vreinterpretq_u8_u64(ctr); -#define CTR_END( reg, ii) MM_XOR (data[ii], reg); +#define CTR_START(reg, ii) MM_OP (vaddq_u64, ctr, one) reg = vreinterpretq_u8_u64(ctr); +#define CTR_END( reg, ii) MM_XOR (data[ii], reg) #define WOP_KEY(op, n) { \ const v128 key = w[n]; \ - WOP(op); } + WOP(op) } #define WIDE_LOOP_START \ dataEnd = data + numBlocks; \ @@ -672,8 +881,10 @@ AES_FUNC_START2 (AesCbc_Decode_HW) { + v128 *p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; v128 iv = *p; - const v128 *wStart = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; + const v128 * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2; const v128 *dataEnd; p += 2; @@ -681,7 +892,7 @@ { const v128 *w = wStart; WOP (DECLARE_VAR) - WOP (LOAD_data); + WOP (LOAD_data) WOP_KEY (AES_D_IMC, 2) do { @@ -692,30 +903,30 @@ while (w != p); WOP_KEY (AES_D, 1) WOP_KEY (AES_XOR, 0) - MM_XOR (m0, iv); + MM_XOR (m0, iv) WOP_M1 (XOR_data_M1) - iv = data[NUM_WAYS - 1]; - WOP (STORE_data); + LOAD_data(iv, NUM_WAYS - 1) + WOP (STORE_data) } WIDE_LOOP_END SINGLE_LOOP { const v128 *w = wStart; - v128 m = *data; + v128 m; LOAD_data(m, 0) AES_D_IMC_m (w[2]) do { - AES_D_IMC_m (w[1]); - AES_D_IMC_m (w[0]); + AES_D_IMC_m (w[1]) + AES_D_IMC_m (w[0]) w -= 2; } while (w != p); - AES_D_m (w[1]); - MM_XOR_m (w[0]); - MM_XOR_m (iv); - iv = *data; - *data = m; + AES_D_m (w[1]) + MM_XOR_m (w[0]) + MM_XOR_m (iv) + LOAD_data(iv, 0) + STORE_data(m, 0) } p[-2] = iv; @@ -724,18 +935,24 @@ AES_FUNC_START2 (AesCtr_Code_HW) { + v128 *p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; uint64x2_t ctr = vreinterpretq_u64_u8(*p); - const v128 *wEnd = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; + const v128 * const wEnd = p + (size_t)*(const UInt32 *)(p + 1) * 2; const v128 *dataEnd; - uint64x2_t one = vdupq_n_u64(0); - one = vsetq_lane_u64(1, one, 0); +// the bug in clang: +// __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); +#if defined(__clang__) && (__clang_major__ <= 9) +#pragma GCC diagnostic ignored "-Wvector-conversion" +#endif + const uint64x2_t one = vsetq_lane_u64(1, vdupq_n_u64(0), 0); p += 2; WIDE_LOOP_START { const v128 *w = p; WOP (DECLARE_VAR) - WOP (CTR_START); + WOP (CTR_START) do { WOP_KEY (AES_E_MC, 0) @@ -746,7 +963,7 @@ WOP_KEY (AES_E_MC, 0) WOP_KEY (AES_E, 1) WOP_KEY (AES_XOR, 2) - WOP (CTR_END); + WOP (CTR_END) } WIDE_LOOP_END @@ -754,18 +971,18 @@ { const v128 *w = p; v128 m; - CTR_START (m, 0); + CTR_START (m, 0) do { - AES_E_MC_m (w[0]); - AES_E_MC_m (w[1]); + AES_E_MC_m (w[0]) + AES_E_MC_m (w[1]) w += 2; } while (w != wEnd); - AES_E_MC_m (w[0]); - AES_E_m (w[1]); - MM_XOR_m (w[2]); - CTR_END (m, 0); + AES_E_MC_m (w[0]) + AES_E_m (w[1]) + MM_XOR_m (w[2]) + CTR_END (m, 0) } p[-2] = vreinterpretq_u8_u64(ctr); @@ -774,3 +991,12 @@ #endif // USE_HW_AES #endif // MY_CPU_ARM_OR_ARM64 + +#undef NUM_WAYS +#undef WOP_M1 +#undef WOP +#undef DECLARE_VAR +#undef LOAD_data +#undef STORE_data +#undef USE_INTEL_AES +#undef USE_HW_AES diff -Nru 7zip-22.01+dfsg/C/Alloc.c 7zip-22.01+really25.01+dfsg/C/Alloc.c --- 7zip-22.01+dfsg/C/Alloc.c 2021-07-13 09:20:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Alloc.c 2024-02-18 18:00:00.000000000 +0000 @@ -1,38 +1,53 @@ /* Alloc.c -- Memory allocation functions -2021-07-13 : Igor Pavlov : Public domain */ +2024-02-18 : Igor Pavlov : Public domain */ #include "Precomp.h" -#include - #ifdef _WIN32 -#include +#include "7zWindows.h" #endif #include #include "Alloc.h" -/* #define _SZ_ALLOC_DEBUG */ +#if defined(Z7_LARGE_PAGES) && defined(_WIN32) && \ + (!defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502) // < Win2003 (xp-64) + #define Z7_USE_DYN_GetLargePageMinimum +#endif + +// for debug: +#if 0 +#if defined(__CHERI__) && defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// #pragma message("=== Z7_ALLOC_NO_OFFSET_ALLOCATOR === ") +#define Z7_ALLOC_NO_OFFSET_ALLOCATOR +#endif +#endif -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ -#ifdef _SZ_ALLOC_DEBUG +// #define SZ_ALLOC_DEBUG +/* #define SZ_ALLOC_DEBUG */ +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef SZ_ALLOC_DEBUG + +#include #include -int g_allocCount = 0; -int g_allocCountMid = 0; -int g_allocCountBig = 0; +static int g_allocCount = 0; +#ifdef _WIN32 +static int g_allocCountMid = 0; +static int g_allocCountBig = 0; +#endif #define CONVERT_INT_TO_STR(charType, tempSize) \ - unsigned char temp[tempSize]; unsigned i = 0; \ - while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ + char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (char)('0' + (unsigned)(val % 10)); val /= 10; } \ *s++ = (charType)('0' + (unsigned)val); \ while (i != 0) { i--; *s++ = temp[i]; } \ *s = 0; static void ConvertUInt64ToString(UInt64 val, char *s) { - CONVERT_INT_TO_STR(char, 24); + CONVERT_INT_TO_STR(char, 24) } #define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) @@ -77,7 +92,7 @@ Print(s); } -static void PrintLn() +static void PrintLn(void) { Print("\n"); } @@ -89,10 +104,10 @@ PrintAligned(s, align); } -static void PrintDec(UInt64 v, size_t align) +static void PrintDec(int v, size_t align) { char s[32]; - ConvertUInt64ToString(v, s); + ConvertUInt64ToString((unsigned)v, s); PrintAligned(s, align); } @@ -102,12 +117,19 @@ } -#define PRINT_ALLOC(name, cnt, size, ptr) \ +#define PRINT_REALLOC(name, cnt, size, ptr) { \ + Print(name " "); \ + if (!ptr) PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#define PRINT_ALLOC(name, cnt, size, ptr) { \ Print(name " "); \ PrintDec(cnt++, 10); \ PrintHex(size, 10); \ PrintAddr(ptr); \ - PrintLn(); + PrintLn(); } #define PRINT_FREE(name, cnt, ptr) if (ptr) { \ Print(name " "); \ @@ -117,26 +139,45 @@ #else +#ifdef _WIN32 #define PRINT_ALLOC(name, cnt, size, ptr) +#endif #define PRINT_FREE(name, cnt, ptr) #define Print(s) #define PrintLn() +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR #define PrintHex(v, align) +#endif #define PrintAddr(p) #endif +/* +by specification: + malloc(non_NULL, 0) : returns NULL or a unique pointer value that can later be successfully passed to free() + realloc(NULL, size) : the call is equivalent to malloc(size) + realloc(non_NULL, 0) : the call is equivalent to free(ptr) + +in main compilers: + malloc(0) : returns non_NULL + realloc(NULL, 0) : returns non_NULL + realloc(non_NULL, 0) : returns NULL +*/ + void *MyAlloc(size_t size) { if (size == 0) return NULL; - PRINT_ALLOC("Alloc ", g_allocCount, size, NULL); - #ifdef _SZ_ALLOC_DEBUG + // PRINT_ALLOC("Alloc ", g_allocCount, size, NULL) + #ifdef SZ_ALLOC_DEBUG { void *p = malloc(size); - // PRINT_ALLOC("Alloc ", g_allocCount, size, p); + if (p) + { + PRINT_ALLOC("Alloc ", g_allocCount, size, p) + } return p; } #else @@ -146,71 +187,107 @@ void MyFree(void *address) { - PRINT_FREE("Free ", g_allocCount, address); + PRINT_FREE("Free ", g_allocCount, address) free(address); } +void *MyRealloc(void *address, size_t size) +{ + if (size == 0) + { + MyFree(address); + return NULL; + } + // PRINT_REALLOC("Realloc ", g_allocCount, size, address) + #ifdef SZ_ALLOC_DEBUG + { + void *p = realloc(address, size); + if (p) + { + PRINT_REALLOC("Realloc ", g_allocCount, size, address) + } + return p; + } + #else + return realloc(address, size); + #endif +} + + #ifdef _WIN32 void *MidAlloc(size_t size) { if (size == 0) return NULL; - - PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL); - + #ifdef SZ_ALLOC_DEBUG + { + void *p = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, p) + } + return p; + } + #else return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + #endif } void MidFree(void *address) { - PRINT_FREE("Free-Mid", g_allocCountMid, address); + PRINT_FREE("Free-Mid", g_allocCountMid, address) if (!address) return; VirtualFree(address, 0, MEM_RELEASE); } -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES #ifdef MEM_LARGE_PAGES - #define MY__MEM_LARGE_PAGES MEM_LARGE_PAGES + #define MY_MEM_LARGE_PAGES MEM_LARGE_PAGES #else - #define MY__MEM_LARGE_PAGES 0x20000000 + #define MY_MEM_LARGE_PAGES 0x20000000 #endif extern SIZE_T g_LargePageSize; SIZE_T g_LargePageSize = 0; -typedef SIZE_T (WINAPI *GetLargePageMinimumP)(VOID); +typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID); -#endif // _7ZIP_LARGE_PAGES - -void SetLargePageSize() +void SetLargePageSize(void) { - #ifdef _7ZIP_LARGE_PAGES SIZE_T size; - GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) - GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); - if (!largePageMinimum) +#ifdef Z7_USE_DYN_GetLargePageMinimum +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + + const + Func_GetLargePageMinimum fn = + (Func_GetLargePageMinimum) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetLargePageMinimum"); + if (!fn) return; - size = largePageMinimum(); + size = fn(); +#else + size = GetLargePageMinimum(); +#endif if (size == 0 || (size & (size - 1)) != 0) return; g_LargePageSize = size; - #endif } +#endif // Z7_LARGE_PAGES void *BigAlloc(size_t size) { if (size == 0) return NULL; - PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL); - - #ifdef _7ZIP_LARGE_PAGES + PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL) + + #ifdef Z7_LARGE_PAGES { SIZE_T ps = g_LargePageSize; if (ps != 0 && ps <= (1 << 30) && size > (ps / 2)) @@ -220,56 +297,43 @@ size2 = (size + ps) & ~ps; if (size2 >= size) { - void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MY__MEM_LARGE_PAGES, PAGE_READWRITE); - if (res) - return res; + void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY_MEM_LARGE_PAGES, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-BM ", g_allocCountMid, size2, p) + return p; + } } } } #endif - return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + return MidAlloc(size); } void BigFree(void *address) { - PRINT_FREE("Free-Big", g_allocCountBig, address); - - if (!address) - return; - VirtualFree(address, 0, MEM_RELEASE); + PRINT_FREE("Free-Big", g_allocCountBig, address) + MidFree(address); } -#endif +#endif // _WIN32 -static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); } -static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); } +static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MyAlloc(size); } +static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MyFree(address); } const ISzAlloc g_Alloc = { SzAlloc, SzFree }; #ifdef _WIN32 -static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); } -static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); } -static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); } -static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); } +static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MidAlloc(size); } +static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MidFree(address); } +static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return BigAlloc(size); } +static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) BigFree(address); } const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree }; const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; #endif -/* - uintptr_t : C99 (optional) - : unsupported in VS6 -*/ - -#ifdef _WIN32 - typedef UINT_PTR UIntPtr; -#else - /* - typedef uintptr_t UIntPtr; - */ - typedef ptrdiff_t UIntPtr; -#endif - +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR #define ADJUST_ALLOC_SIZE 0 /* @@ -280,14 +344,36 @@ MyAlloc() can return address that is NOT multiple of sizeof(void *). */ - /* -#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1)))) + uintptr_t : C99 (optional) + : unsupported in VS6 */ -#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1)))) +typedef + #ifdef _WIN32 + UINT_PTR + #elif 1 + uintptr_t + #else + ptrdiff_t + #endif + MY_uintptr_t; + +#if 0 \ + || (defined(__CHERI__) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ > 8)) +// for 128-bit pointers (cheri): +#define MY_ALIGN_PTR_DOWN(p, align) \ + ((void *)((char *)(p) - ((size_t)(MY_uintptr_t)(p) & ((align) - 1)))) +#else +#define MY_ALIGN_PTR_DOWN(p, align) \ + ((void *)((((MY_uintptr_t)(p)) & ~((MY_uintptr_t)(align) - 1)))) +#endif +#endif -#if !defined(_WIN32) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) +#if !defined(_WIN32) \ + && (defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) \ + || defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) #define USE_posix_memalign #endif @@ -327,14 +413,13 @@ #define ALLOC_ALIGN_SIZE ((size_t)1 << 7) -static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) +void *z7_AlignedAlloc(size_t size) { - #ifndef USE_posix_memalign +#ifndef USE_posix_memalign void *p; void *pAligned; size_t newSize; - UNUSED_VAR(pp); /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned block to prevent cache line sharing with another allocated blocks */ @@ -359,10 +444,9 @@ return pAligned; - #else +#else void *p; - UNUSED_VAR(pp); if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size)) return NULL; @@ -371,19 +455,37 @@ return p; - #endif +#endif +} + + +void z7_AlignedFree(void *address) +{ +#ifndef USE_posix_memalign + if (address) + MyFree(((void **)address)[-1]); +#else + free(address); +#endif +} + + +static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) +{ + UNUSED_VAR(pp) + return z7_AlignedAlloc(size); } static void SzAlignedFree(ISzAllocPtr pp, void *address) { - UNUSED_VAR(pp); - #ifndef USE_posix_memalign + UNUSED_VAR(pp) +#ifndef USE_posix_memalign if (address) MyFree(((void **)address)[-1]); - #else +#else free(address); - #endif +#endif } @@ -391,17 +493,45 @@ -#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) - /* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */ -#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] -/* -#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1] -*/ +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR +#if 1 + #define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) + #define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] +#else + // we can use this simplified code, + // if (CAlignOffsetAlloc::offset == (k * sizeof(void *)) + #define REAL_BLOCK_PTR_VAR(p) (((void **)(p))[-1]) +#endif +#endif + + +#if 0 +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR +#include +static void PrintPtr(const char *s, const void *p) +{ + const Byte *p2 = (const Byte *)&p; + unsigned i; + printf("%s %p ", s, p); + for (i = sizeof(p); i != 0;) + { + i--; + printf("%02x", p2[i]); + } + printf("\n"); +} +#endif +#endif + static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size) { - CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); +#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) + UNUSED_VAR(pp) + return z7_AlignedAlloc(size); +#else + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); void *adr; void *pAligned; size_t newSize; @@ -429,6 +559,12 @@ pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr + alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset; +#if 0 + printf("\nalignSize = %6x, offset=%6x, size=%8x \n", (unsigned)alignSize, (unsigned)p->offset, (unsigned)size); + PrintPtr("base", adr); + PrintPtr("alig", pAligned); +#endif + PrintLn(); Print("- Aligned: "); Print(" size="); PrintHex(size, 8); @@ -440,19 +576,25 @@ REAL_BLOCK_PTR_VAR(pAligned) = adr; return pAligned; +#endif } static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address) { +#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) + UNUSED_VAR(pp) + z7_AlignedFree(address); +#else if (address) { - CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); PrintLn(); Print("- Aligned Free: "); PrintLn(); ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address)); } +#endif } diff -Nru 7zip-22.01+dfsg/C/Alloc.h 7zip-22.01+really25.01+dfsg/C/Alloc.h --- 7zip-22.01+dfsg/C/Alloc.h 2021-07-13 09:19:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Alloc.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,31 +1,49 @@ /* Alloc.h -- Memory allocation functions -2021-07-13 : Igor Pavlov : Public domain */ +2024-01-22 : Igor Pavlov : Public domain */ -#ifndef __COMMON_ALLOC_H -#define __COMMON_ALLOC_H +#ifndef ZIP7_INC_ALLOC_H +#define ZIP7_INC_ALLOC_H #include "7zTypes.h" EXTERN_C_BEGIN +/* + MyFree(NULL) : is allowed, as free(NULL) + MyAlloc(0) : returns NULL : but malloc(0) is allowed to return NULL or non_NULL + MyRealloc(NULL, 0) : returns NULL : but realloc(NULL, 0) is allowed to return NULL or non_NULL +MyRealloc() is similar to realloc() for the following cases: + MyRealloc(non_NULL, 0) : returns NULL and always calls MyFree(ptr) + MyRealloc(NULL, non_ZERO) : returns NULL, if allocation failed + MyRealloc(non_NULL, non_ZERO) : returns NULL, if reallocation failed +*/ + void *MyAlloc(size_t size); void MyFree(void *address); +void *MyRealloc(void *address, size_t size); + +void *z7_AlignedAlloc(size_t size); +void z7_AlignedFree(void *p); #ifdef _WIN32 +#ifdef Z7_LARGE_PAGES void SetLargePageSize(void); +#endif void *MidAlloc(size_t size); void MidFree(void *address); void *BigAlloc(size_t size); void BigFree(void *address); +/* #define Z7_BIG_ALLOC_IS_ZERO_FILLED */ + #else -#define MidAlloc(size) MyAlloc(size) -#define MidFree(address) MyFree(address) -#define BigAlloc(size) MyAlloc(size) -#define BigFree(address) MyFree(address) +#define MidAlloc(size) z7_AlignedAlloc(size) +#define MidFree(address) z7_AlignedFree(address) +#define BigAlloc(size) z7_AlignedAlloc(size) +#define BigFree(address) z7_AlignedFree(address) #endif diff -Nru 7zip-22.01+dfsg/C/Asm_c.mak 7zip-22.01+really25.01+dfsg/C/Asm_c.mak --- 7zip-22.01+dfsg/C/Asm_c.mak 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Asm_c.mak 2024-03-21 08:00:00.000000000 +0000 @@ -0,0 +1,12 @@ +!IFDEF ASM_OBJS +!IF "$(PLATFORM)" == "arm64" +$(ASM_OBJS): ../../../Asm/arm64/$(*B).S + $(COMPL_ASM_CLANG) +!ELSEIF "$(PLATFORM)" == "arm" +$(ASM_OBJS): ../../../Asm/arm/$(*B).asm + $(COMPL_ASM) +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" +$(ASM_OBJS): ../../../Asm/x86/$(*B).asm + $(COMPL_ASM) +!ENDIF +!ENDIF diff -Nru 7zip-22.01+dfsg/C/Bcj2.c 7zip-22.01+really25.01+dfsg/C/Bcj2.c --- 7zip-22.01+dfsg/C/Bcj2.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bcj2.c 2023-03-01 12:00:00.000000000 +0000 @@ -1,29 +1,24 @@ /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) -2021-02-09 : Igor Pavlov : Public domain */ +2023-03-01 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "Bcj2.h" #include "CpuArch.h" -#define CProb UInt16 - #define kTopValue ((UInt32)1 << 24) -#define kNumModelBits 11 -#define kBitModelTotal (1 << kNumModelBits) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) #define kNumMoveBits 5 -#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) -#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); +// UInt32 bcj2_stats[256 + 2][2]; void Bcj2Dec_Init(CBcj2Dec *p) { unsigned i; - - p->state = BCJ2_DEC_STATE_OK; + p->state = BCJ2_STREAM_RC; // BCJ2_DEC_STATE_OK; p->ip = 0; - p->temp[3] = 0; + p->temp = 0; p->range = 0; p->code = 0; for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) @@ -32,217 +27,248 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p) { + UInt32 v = p->temp; + // const Byte *src; if (p->range <= 5) { - p->state = BCJ2_DEC_STATE_OK; + UInt32 code = p->code; + p->state = BCJ2_DEC_STATE_ERROR; /* for case if we return SZ_ERROR_DATA; */ for (; p->range != 5; p->range++) { - if (p->range == 1 && p->code != 0) + if (p->range == 1 && code != 0) return SZ_ERROR_DATA; - if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; return SZ_OK; } - - p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + code = (code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + p->code = code; } - - if (p->code == 0xFFFFFFFF) + if (code == 0xffffffff) return SZ_ERROR_DATA; - - p->range = 0xFFFFFFFF; + p->range = 0xffffffff; } - else if (p->state >= BCJ2_DEC_STATE_ORIG_0) + // else { - while (p->state <= BCJ2_DEC_STATE_ORIG_3) + unsigned state = p->state; + // we check BCJ2_IS_32BIT_STREAM() here instead of check in the main loop + if (BCJ2_IS_32BIT_STREAM(state)) { - Byte *dest = p->dest; - if (dest == p->destLim) + const Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) return SZ_OK; - *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; - p->state++; - p->dest = dest + 1; + p->bufs[state] = cur + 4; + { + const UInt32 ip = p->ip + 4; + v = GetBe32a(cur) - ip; + p->ip = ip; + } + state = BCJ2_DEC_STATE_ORIG_0; } - } - - /* - if (BCJ2_IS_32BIT_STREAM(p->state)) - { - const Byte *cur = p->bufs[p->state]; - if (cur == p->lims[p->state]) - return SZ_OK; - p->bufs[p->state] = cur + 4; - + if ((unsigned)(state - BCJ2_DEC_STATE_ORIG_0) < 4) { - UInt32 val; - Byte *dest; - SizeT rem; - - p->ip += 4; - val = GetBe32(cur) - p->ip; - dest = p->dest; - rem = p->destLim - dest; - if (rem < 4) + Byte *dest = p->dest; + for (;;) { - SizeT i; - SetUi32(p->temp, val); - for (i = 0; i < rem; i++) - dest[i] = p->temp[i]; - p->dest = dest + rem; - p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; - return SZ_OK; + if (dest == p->destLim) + { + p->state = state; + p->temp = v; + return SZ_OK; + } + *dest++ = (Byte)v; + p->dest = dest; + if (++state == BCJ2_DEC_STATE_ORIG_3 + 1) + break; + v >>= 8; } - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); - p->dest = dest + 4; - p->state = BCJ2_DEC_STATE_OK; } } - */ + // src = p->bufs[BCJ2_STREAM_MAIN]; for (;;) { + /* if (BCJ2_IS_32BIT_STREAM(p->state)) p->state = BCJ2_DEC_STATE_OK; else + */ { if (p->range < kTopValue) { if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; + p->temp = v; return SZ_OK; } p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } - { const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; const Byte *srcLim; - Byte *dest; - SizeT num = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src); - - if (num == 0) + Byte *dest = p->dest; { - p->state = BCJ2_STREAM_MAIN; - return SZ_OK; + const SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src); + SizeT num = (SizeT)(p->destLim - dest); + if (num >= rem) + num = rem; + #define NUM_ITERS 4 + #if (NUM_ITERS & (NUM_ITERS - 1)) == 0 + num &= ~((SizeT)NUM_ITERS - 1); // if (NUM_ITERS == (1 << x)) + #else + num -= num % NUM_ITERS; // if (NUM_ITERS != (1 << x)) + #endif + srcLim = src + num; } - - dest = p->dest; - if (num > (SizeT)(p->destLim - dest)) + + #define NUM_SHIFT_BITS 24 + #define ONE_ITER(indx) { \ + const unsigned b = src[indx]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + /* ++dest */; /* v = b; */ } + + if (src != srcLim) + for (;;) { - num = (SizeT)(p->destLim - dest); - if (num == 0) - { - p->state = BCJ2_DEC_STATE_ORIG; - return SZ_OK; - } + /* The dependency chain of 2-cycle for (v) calculation is not big problem here. + But we can remove dependency chain with v = b in the end of loop. */ + ONE_ITER(0) + #if (NUM_ITERS > 1) + ONE_ITER(1) + #if (NUM_ITERS > 2) + ONE_ITER(2) + #if (NUM_ITERS > 3) + ONE_ITER(3) + #if (NUM_ITERS > 4) + ONE_ITER(4) + #if (NUM_ITERS > 5) + ONE_ITER(5) + #if (NUM_ITERS > 6) + ONE_ITER(6) + #if (NUM_ITERS > 7) + ONE_ITER(7) + #endif + #endif + #endif + #endif + #endif + #endif + #endif + + src += NUM_ITERS; + if (src == srcLim) + break; } - - srcLim = src + num; - if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) - *dest = src[0]; - else for (;;) + if (src == srcLim) + #if (NUM_ITERS > 1) + for (;;) + #endif { - Byte b = *src; - *dest = b; - if (b != 0x0F) + #if (NUM_ITERS > 1) + if (src == p->lims[BCJ2_STREAM_MAIN] || dest == p->destLim) + #endif { - if ((b & 0xFE) == 0xE8) - break; - dest++; - if (++src != srcLim) - continue; - break; + const SizeT num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = src; + p->dest = dest; + p->ip += (UInt32)num; + /* state BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ + p->state = + src == p->lims[BCJ2_STREAM_MAIN] ? + (unsigned)BCJ2_STREAM_MAIN : + (unsigned)BCJ2_DEC_STATE_ORIG; + p->temp = v; + return SZ_OK; } - dest++; - if (++src == srcLim) - break; - if ((*src & 0xF0) != 0x80) - continue; - *dest = *src; - break; + #if (NUM_ITERS > 1) + ONE_ITER(0) + src++; + #endif } - - num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]); - - if (src == srcLim) + { - p->temp[3] = src[-1]; - p->bufs[BCJ2_STREAM_MAIN] = src; + const SizeT num = (SizeT)(dest - p->dest); + p->dest = dest; // p->dest += num; + p->bufs[BCJ2_STREAM_MAIN] += num; // = src; p->ip += (UInt32)num; - p->dest += num; - p->state = - p->bufs[BCJ2_STREAM_MAIN] == - p->lims[BCJ2_STREAM_MAIN] ? - (unsigned)BCJ2_STREAM_MAIN : - (unsigned)BCJ2_DEC_STATE_ORIG; - return SZ_OK; } - { UInt32 bound, ttt; - CProb *prob; - Byte b = src[0]; - Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); - - p->temp[3] = b; - p->bufs[BCJ2_STREAM_MAIN] = src + 1; - num++; - p->ip += (UInt32)num; - p->dest += num; - - prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); - - _IF_BIT_0 + CBcj2Prob *prob; // unsigned index; + /* + prob = p->probs + (unsigned)((Byte)v == 0xe8 ? + 2 + (Byte)(v >> 8) : + ((v >> 5) & 1)); // ((Byte)v < 0xe8 ? 0 : 1)); + */ { - _UPDATE_0 + const unsigned c = ((v + 0x17) >> 6) & 1; + prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + // (Byte) + // 8x->0 : e9->1 : xxe8->xx+2 + // 8x->0x100 : e9->0x101 : xxe8->xx + // (((0x100 - (e & ~v)) & (0x100 | (v >> 8))) + (e & v)); + // (((0x101 + (~e | v)) & (0x100 | (v >> 8))) + (e & v)); + } + ttt = *prob; + bound = (p->range >> kNumBitModelTotalBits) * ttt; + if (p->code < bound) + { + // bcj2_stats[prob - p->probs][0]++; + p->range = bound; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); continue; } - _UPDATE_1 - + { + // bcj2_stats[prob - p->probs][1]++; + p->range -= bound; + p->code -= bound; + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } } } } - { - UInt32 val; - unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + /* (v == 0xe8 ? 0 : 1) uses setcc instruction with additional zero register usage in x64 MSVC. */ + // const unsigned cj = ((Byte)v == 0xe8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; const Byte *cur = p->bufs[cj]; Byte *dest; SizeT rem; - if (cur == p->lims[cj]) { p->state = cj; break; } - - val = GetBe32(cur); + v = GetBe32a(cur); p->bufs[cj] = cur + 4; - - p->ip += 4; - val -= p->ip; + { + const UInt32 ip = p->ip + 4; + v -= ip; + p->ip = ip; + } dest = p->dest; rem = (SizeT)(p->destLim - dest); - if (rem < 4) { - p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; - p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; - p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; - p->temp[3] = (Byte)val; + if ((unsigned)rem > 0) { dest[0] = (Byte)v; v >>= 8; + if ((unsigned)rem > 1) { dest[1] = (Byte)v; v >>= 8; + if ((unsigned)rem > 2) { dest[2] = (Byte)v; v >>= 8; }}} + p->temp = v; p->dest = dest + rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; break; } - - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); + SetUi32(dest, v) + v >>= 24; p->dest = dest + 4; } } @@ -252,6 +278,13 @@ p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } - return SZ_OK; } + +#undef NUM_ITERS +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff -Nru 7zip-22.01+dfsg/C/Bcj2.h 7zip-22.01+really25.01+dfsg/C/Bcj2.h --- 7zip-22.01+dfsg/C/Bcj2.h 2014-11-10 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bcj2.h 2023-03-02 17:00:00.000000000 +0000 @@ -1,8 +1,8 @@ -/* Bcj2.h -- BCJ2 Converter for x86 code -2014-11-10 : Igor Pavlov : Public domain */ +/* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2) +2023-03-02 : Igor Pavlov : Public domain */ -#ifndef __BCJ2_H -#define __BCJ2_H +#ifndef ZIP7_INC_BCJ2_H +#define ZIP7_INC_BCJ2_H #include "7zTypes.h" @@ -26,37 +26,68 @@ BCJ2_DEC_STATE_ORIG_3, BCJ2_DEC_STATE_ORIG, - BCJ2_DEC_STATE_OK + BCJ2_DEC_STATE_ERROR /* after detected data error */ }; enum { BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, - BCJ2_ENC_STATE_OK + BCJ2_ENC_STATE_FINISHED /* it's state after fully encoded stream */ }; -#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) +/* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */ +#define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2) /* CBcj2Dec / CBcj2Enc bufs sizes: BUF_SIZE(n) = lims[n] - bufs[n] -bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: +bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4: (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 */ +// typedef UInt32 CBcj2Prob; +typedef UInt16 CBcj2Prob; + +/* +BCJ2 encoder / decoder internal requirements: + - If last bytes of stream contain marker (e8/e8/0f8x), then + there is also encoded symbol (0 : no conversion) in RC stream. + - One case of overlapped instructions is supported, + if last byte of converted instruction is (0f) and next byte is (8x): + marker [xx xx xx 0f] 8x + then the pair (0f 8x) is treated as marker. +*/ + +/* ---------- BCJ2 Decoder ---------- */ + /* CBcj2Dec: -dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: +(dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: bufs[BCJ2_STREAM_MAIN] >= dest && - bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + + bufs[BCJ2_STREAM_MAIN] - dest >= BUF_SIZE(BCJ2_STREAM_CALL) + BUF_SIZE(BCJ2_STREAM_JUMP) - tempReserv = 0 : for first call of Bcj2Dec_Decode - tempReserv = 4 : for any other calls of Bcj2Dec_Decode - overlap with offset = 1 is not allowed + reserve = bufs[BCJ2_STREAM_MAIN] - dest - + ( BUF_SIZE(BCJ2_STREAM_CALL) + + BUF_SIZE(BCJ2_STREAM_JUMP) ) + and additional conditions: + if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve != 1) : if (ver < v23.00) + } + else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve >= 6) : if (ver < v23.00) + (reserve >= 4) : if (ver >= v23.00) + We need that (reserve) because after first call of Bcj2Dec_Decode(), + CBcj2Dec::temp can contain up to 4 bytes for writing to (dest). + } + (reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode(). + (reserve == 0) also is allowed in case of multi-call, if we use fixed buffers, + and (reserve) is calculated from full (final) sizes of all streams before first call. */ typedef struct @@ -68,21 +99,65 @@ unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ - UInt32 ip; - Byte temp[4]; + UInt32 ip; /* property of starting base for decoding */ + UInt32 temp; /* Byte temp[4]; */ UInt32 range; UInt32 code; - UInt16 probs[2 + 256]; + CBcj2Prob probs[2 + 256]; } CBcj2Dec; + +/* Note: + Bcj2Dec_Init() sets (CBcj2Dec::ip = 0) + if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init() +*/ void Bcj2Dec_Init(CBcj2Dec *p); -/* Returns: SZ_OK or SZ_ERROR_DATA */ + +/* Bcj2Dec_Decode(): + returns: + SZ_OK + SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct +*/ SRes Bcj2Dec_Decode(CBcj2Dec *p); -#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) +/* To check that decoding was finished you can compare + sizes of processed streams with sizes known from another sources. + You must do at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. + additional optional checks: + - the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC) + - the checks Bcj2Dec_IsMaybeFinished*() + also before actual decoding you can check that the + following condition is met for stream sizes: + ( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) ) +*/ + +/* (state == BCJ2_STREAM_MAIN) means that decoder is ready for + additional input data in BCJ2_STREAM_MAIN stream. + Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN) + +/* if the stream decoding was finished correctly, then range decoder + part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0). + Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0) + +/* use Bcj2Dec_IsMaybeFinished() only as additional check + after at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. +*/ +#define Bcj2Dec_IsMaybeFinished(_p_) ( \ + Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \ + Bcj2Dec_IsMaybeFinished_code(_p_)) + +/* ---------- BCJ2 Encoder ---------- */ typedef enum { @@ -91,6 +166,91 @@ BCJ2_ENC_FINISH_MODE_END_STREAM } EBcj2Enc_FinishMode; +/* + BCJ2_ENC_FINISH_MODE_CONTINUE: + process non finished encoding. + It notifies the encoder that additional further calls + can provide more input data (src) than provided by current call. + In that case the CBcj2Enc encoder still can move (src) pointer + up to (srcLim), but CBcj2Enc encoder can store some of the last + processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer. + at return: + (CBcj2Enc::src will point to position that includes + processed data and data copied to (temp[]) buffer) + That data from (temp[]) buffer will be used in further calls. + + BCJ2_ENC_FINISH_MODE_END_BLOCK: + finish encoding of current block (ended at srcLim) without RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) && + CBcj2Enc::src == CBcj2Enc::srcLim) + : it shows that block encoding was finished. And the encoder is + ready for new (src) data or for stream finish operation. + finished block means + { + CBcj2Enc has completed block encoding up to (srcLim). + (1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will + not cross block boundary at (srcLim). + temporary CBcj2Enc buffer for (ORIG) src data is empty. + 3 output uncompressed streams (MAIN, CALL, JUMP) were flushed. + RC stream was not flushed. And RC stream will cross block boundary. + } + Note: some possible implementation of BCJ2 encoder could + write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(), + and it could calculate symbol for RC in another call of Bcj2Enc_Encode(). + BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol. + And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls. + So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK + to ensure that RC symbol is calculated and written in proper block. + + BCJ2_ENC_FINISH_MODE_END_STREAM + finish encoding of stream (ended at srcLim) fully including RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED) + : it shows that stream encoding was finished fully, + and all output streams were flushed fully. + also Bcj2Enc_IsFinished() can be called. +*/ + + +/* + 32-bit relative offset in JUMP/CALL commands is + - (mod 4 GiB) for 32-bit x86 code + - signed Int32 for 64-bit x86-64 code + BCJ2 encoder also does internal relative to absolute address conversions. + And there are 2 possible ways to do it: + before v23: we used 32-bit variables and (mod 4 GiB) conversion + since v23: we use 64-bit variables and (signed Int32 offset) conversion. + The absolute address condition for conversion in v23: + ((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64) + note that if (fileSize64 > 2 GiB). there is difference between + old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23). + And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases. +*/ + +/* +// for old (v22) way for conversion: +typedef UInt32 CBcj2Enc_ip_unsigned; +typedef Int32 CBcj2Enc_ip_signed; +#define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31) +*/ +typedef UInt64 CBcj2Enc_ip_unsigned; +typedef Int64 CBcj2Enc_ip_signed; + +/* maximum size of file that can be used for conversion condition */ +#define BCJ2_ENC_FileSize_MAX ((CBcj2Enc_ip_unsigned)0 - 2) + +/* default value of fileSize64_minus1 variable that means + that absolute address limitation will not be used */ +#define BCJ2_ENC_FileSizeField_UNLIMITED ((CBcj2Enc_ip_unsigned)0 - 1) + +/* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */ +#define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \ + ((CBcj2Enc_ip_unsigned)(fileSize) - 1) + +/* set CBcj2Enc::fileSize64_minus1 variable from size of file */ +#define Bcj2Enc_SET_FileSize(p, fileSize) \ + (p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize); + + typedef struct { Byte *bufs[BCJ2_NUM_STREAMS]; @@ -101,45 +261,71 @@ unsigned state; EBcj2Enc_FinishMode finishMode; - Byte prevByte; + Byte context; + Byte flushRem; + Byte isFlushState; Byte cache; UInt32 range; UInt64 low; UInt64 cacheSize; + + // UInt32 context; // for marker version, it can include marker flag. - UInt32 ip; - - /* 32-bit ralative offset in JUMP/CALL commands is - - (mod 4 GB) in 32-bit mode - - signed Int32 in 64-bit mode - We use (mod 4 GB) check for fileSize. - Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ - UInt32 fileIp; - UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ - UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ + /* (ip64) and (fileIp64) correspond to virtual source stream position + that doesn't include data in temp[] */ + CBcj2Enc_ip_unsigned ip64; /* current (ip) position */ + CBcj2Enc_ip_unsigned fileIp64; /* start (ip) position of current file */ + CBcj2Enc_ip_unsigned fileSize64_minus1; /* size of current file (for conversion limitation) */ + UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */ + // UInt32 relatExcludeBits; UInt32 tempTarget; - unsigned tempPos; - Byte temp[4 * 2]; - - unsigned flushPos; - - UInt16 probs[2 + 256]; + unsigned tempPos; /* the number of bytes that were copied to temp[] buffer + (tempPos <= 4) outside of Bcj2Enc_Encode() */ + // Byte temp[4]; // for marker version + Byte temp[8]; + CBcj2Prob probs[2 + 256]; } CBcj2Enc; void Bcj2Enc_Init(CBcj2Enc *p); -void Bcj2Enc_Encode(CBcj2Enc *p); -#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) -#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) +/* +Bcj2Enc_Encode(): at exit: + p->State < BCJ2_NUM_STREAMS : we need more buffer space for output stream + (bufs[p->State] == lims[p->State]) + p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream + (src == srcLim) + p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream +*/ +void Bcj2Enc_Encode(CBcj2Enc *p); + +/* Bcj2Enc encoder can look ahead for up 4 bytes of source stream. + CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer. + (CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after + fully processed data and after data copied to temp buffer. + So if the caller needs to get real number of fully processed input + bytes (without look ahead data in temp buffer), + the caller must subtruct (CBcj2Enc::tempPos) value from processed size + value that is calculated based on current (CBcj2Enc::src): + cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) - + Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); +*/ +/* get the size of input data that was stored in temp[] buffer: */ +#define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos) -#define BCJ2_RELAT_LIMIT_NUM_BITS 26 -#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) +#define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0) -/* limit for CBcj2Enc::fileSize variable */ -#define BCJ2_FileSize_MAX ((UInt32)1 << 31) +/* Note : the decoder supports overlapping of marker (0f 80). + But we can eliminate such overlapping cases by setting + the limit for relative offset conversion as + CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB) +*/ +/* default value for CBcj2Enc::relatLimit */ +#define BCJ2_ENC_RELAT_LIMIT_DEFAULT ((UInt32)0x0f << 24) +#define BCJ2_ENC_RELAT_LIMIT_MAX ((UInt32)1 << 31) +// #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5 EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Bcj2Enc.c 7zip-22.01+really25.01+dfsg/C/Bcj2Enc.c --- 7zip-22.01+dfsg/C/Bcj2Enc.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bcj2Enc.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,60 +1,62 @@ -/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code) -2021-02-09 : Igor Pavlov : Public domain */ +/* Bcj2Enc.c -- BCJ2 Encoder converter for x86 code (Branch CALL/JUMP variant2) +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" /* #define SHOW_STAT */ - #ifdef SHOW_STAT #include -#define PRF(x) x +#define PRF2(s) printf("%s ip=%8x tempPos=%d src= %8x\n", s, (unsigned)p->ip64, p->tempPos, (unsigned)(p->srcLim - p->src)); #else -#define PRF(x) +#define PRF2(s) #endif -#include - #include "Bcj2.h" #include "CpuArch.h" -#define CProb UInt16 - #define kTopValue ((UInt32)1 << 24) -#define kNumModelBits 11 -#define kBitModelTotal (1 << kNumModelBits) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) #define kNumMoveBits 5 void Bcj2Enc_Init(CBcj2Enc *p) { unsigned i; - - p->state = BCJ2_ENC_STATE_OK; + p->state = BCJ2_ENC_STATE_ORIG; p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - p->prevByte = 0; - + p->context = 0; + p->flushRem = 5; + p->isFlushState = 0; p->cache = 0; - p->range = 0xFFFFFFFF; + p->range = 0xffffffff; p->low = 0; p->cacheSize = 1; - - p->ip = 0; - - p->fileIp = 0; - p->fileSize = 0; - p->relatLimit = BCJ2_RELAT_LIMIT; - + p->ip64 = 0; + p->fileIp64 = 0; + p->fileSize64_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; + p->relatLimit = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // p->relatExcludeBits = 0; p->tempPos = 0; - - p->flushPos = 0; - for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) p->probs[i] = kBitModelTotal >> 1; } -static BoolInt MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p) +// Z7_NO_INLINE +Z7_FORCE_INLINE +static BoolInt Bcj2_RangeEnc_ShiftLow(CBcj2Enc *p) { - if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0) + const UInt32 low = (UInt32)p->low; + const unsigned high = (unsigned) + #if defined(Z7_MSC_VER_ORIGINAL) \ + && defined(MY_CPU_X86) \ + && defined(MY_CPU_LE) \ + && !defined(MY_CPU_64BIT) + // we try to rid of __aullshr() call in MSVS-x86 + (((const UInt32 *)&p->low)[1]); // [1] : for little-endian only + #else + (p->low >> 32); + #endif + if (low < (UInt32)0xff000000 || high != 0) { Byte *buf = p->bufs[BCJ2_STREAM_RC]; do @@ -65,247 +67,440 @@ p->bufs[BCJ2_STREAM_RC] = buf; return True; } - *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32)); - p->cache = 0xFF; + *buf++ = (Byte)(p->cache + high); + p->cache = 0xff; } while (--p->cacheSize); p->bufs[BCJ2_STREAM_RC] = buf; - p->cache = (Byte)((UInt32)p->low >> 24); + p->cache = (Byte)(low >> 24); } p->cacheSize++; - p->low = (UInt32)p->low << 8; + p->low = low << 8; return False; } -static void Bcj2Enc_Encode_2(CBcj2Enc *p) -{ - if (BCJ2_IS_32BIT_STREAM(p->state)) + +/* +We can use 2 alternative versions of code: +1) non-marker version: + Byte CBcj2Enc::context + Byte temp[8]; + Last byte of marker (e8/e9/[0f]8x) can be written to temp[] buffer. + Encoder writes last byte of marker (e8/e9/[0f]8x) to dest, only in conjunction + with writing branch symbol to range coder in same Bcj2Enc_Encode_2() call. + +2) marker version: + UInt32 CBcj2Enc::context + Byte CBcj2Enc::temp[4]; + MARKER_FLAG in CBcj2Enc::context shows that CBcj2Enc::context contains finded marker. + it's allowed that + one call of Bcj2Enc_Encode_2() writes last byte of marker (e8/e9/[0f]8x) to dest, + and another call of Bcj2Enc_Encode_2() does offset conversion. + So different values of (fileIp) and (fileSize) are possible + in these different Bcj2Enc_Encode_2() calls. + +Also marker version requires additional if((v & MARKER_FLAG) == 0) check in main loop. +So we use non-marker version. +*/ + +/* + Corner cases with overlap in multi-block. + before v23: there was one corner case, where converted instruction + could start in one sub-stream and finish in next sub-stream. + If multi-block (solid) encoding is used, + and BCJ2_ENC_FINISH_MODE_END_BLOCK is used for each sub-stream. + and (0f) is last byte of previous sub-stream + and (8x) is first byte of current sub-stream + then (0f 8x) pair is treated as marker by BCJ2 encoder and decoder. + BCJ2 encoder can converts 32-bit offset for that (0f 8x) cortage, + if that offset meets limit requirements. + If encoder allows 32-bit offset conversion for such overlap case, + then the data in 3 uncompressed BCJ2 streams for some sub-stream + can depend from data of previous sub-stream. + That corner case is not big problem, and it's rare case. + Since v23.00 we do additional check to prevent conversions in such overlap cases. +*/ + +/* + Bcj2Enc_Encode_2() output variables at exit: { - Byte *cur = p->bufs[p->state]; - if (cur == p->lims[p->state]) - return; - SetBe32(cur, p->tempTarget); - p->bufs[p->state] = cur + 4; + if (Bcj2Enc_Encode_2() exits with (p->state == BCJ2_ENC_STATE_ORIG)) + { + it means that encoder needs more input data. + if (p->srcLim == p->src) at exit, then + { + (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + all input data were read and processed, and we are ready for + new input data. + } + else + { + (p->srcLim != p->src) + (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + The encoder have found e8/e9/0f_8x marker, + and p->src points to last byte of that marker, + Bcj2Enc_Encode_2() needs more input data to get totally + 5 bytes (last byte of marker and 32-bit branch offset) + as continuous array starting from p->src. + (p->srcLim - p->src < 5) requirement is met after exit. + So non-processed resedue from p->src to p->srcLim is always less than 5 bytes. + } + } } +*/ - p->state = BCJ2_ENC_STATE_ORIG; - - for (;;) +Z7_NO_INLINE +static void Bcj2Enc_Encode_2(CBcj2Enc *p) +{ + if (!p->isFlushState) { - if (p->range < kTopValue) + const Byte *src; + UInt32 v; { - if (RangeEnc_ShiftLow(p)) - return; - p->range <<= 8; + const unsigned state = p->state; + if (BCJ2_IS_32BIT_STREAM(state)) + { + Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) + return; + SetBe32a(cur, p->tempTarget) + p->bufs[state] = cur + 4; + } } + p->state = BCJ2_ENC_STATE_ORIG; // for main reason of exit + src = p->src; + v = p->context; + + // #define WRITE_CONTEXT p->context = v; // for marker version + #define WRITE_CONTEXT p->context = (Byte)v; + #define WRITE_CONTEXT_AND_SRC p->src = src; WRITE_CONTEXT + for (;;) { + // const Byte *src; + // UInt32 v; + CBcj2Enc_ip_unsigned ip; + if (p->range < kTopValue) + { + // to reduce register pressure and code size: we save and restore local variables. + WRITE_CONTEXT_AND_SRC + if (Bcj2_RangeEnc_ShiftLow(p)) + return; + p->range <<= 8; + src = p->src; + v = p->context; + } + // src = p->src; + // #define MARKER_FLAG ((UInt32)1 << 17) + // if ((v & MARKER_FLAG) == 0) // for marker version { - const Byte *src = p->src; const Byte *srcLim; - Byte *dest; - SizeT num = (SizeT)(p->srcLim - src); - - if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + Byte *dest = p->bufs[BCJ2_STREAM_MAIN]; { - if (num <= 4) - return; - num -= 4; + const SizeT remSrc = (SizeT)(p->srcLim - src); + SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest); + if (rem >= remSrc) + rem = remSrc; + srcLim = src + rem; } - else if (num == 0) - break; + /* p->context contains context of previous byte: + bits [0 : 7] : src[-1], if (src) was changed in this call + bits [8 : 31] : are undefined for non-marker version + */ + // v = p->context; + #define NUM_SHIFT_BITS 24 + #define CONV_FLAG ((UInt32)1 << 16) + #define ONE_ITER { \ + b = src[0]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + src++; if (src == srcLim) { break; } } - dest = p->bufs[BCJ2_STREAM_MAIN]; - if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest)) + if (src != srcLim) + for (;;) { - num = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest); - if (num == 0) - { - p->state = BCJ2_STREAM_MAIN; - return; - } + /* clang can generate ineffective code with setne instead of two jcc instructions. + we can use 2 iterations and external (unsigned b) to avoid that ineffective code genaration. */ + unsigned b; + ONE_ITER + ONE_ITER } - - srcLim = src + num; + + ip = p->ip64 + (CBcj2Enc_ip_unsigned)(SizeT)(dest - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = dest; + p->ip64 = ip; - if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80) - *dest = src[0]; - else for (;;) + if (src == srcLim) { - Byte b = *src; - *dest = b; - if (b != 0x0F) + WRITE_CONTEXT_AND_SRC + if (src != p->srcLim) { - if ((b & 0xFE) == 0xE8) - break; - dest++; - if (++src != srcLim) - continue; - break; + p->state = BCJ2_STREAM_MAIN; + return; } - dest++; - if (++src == srcLim) - break; - if ((*src & 0xF0) != 0x80) - continue; - *dest = *src; + /* (p->src == p->srcLim) + (p->state == BCJ2_ENC_STATE_ORIG) */ + if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + return; + /* (p->finishMode == BCJ2_ENC_FINISH_MODE_END_STREAM */ + // (p->flushRem == 5); + p->isFlushState = 1; break; } - - num = (SizeT)(src - p->src); - - if (src == srcLim) - { - p->prevByte = src[-1]; - p->bufs[BCJ2_STREAM_MAIN] = dest; - p->src = src; - p->ip += (UInt32)num; - continue; - } - + src++; + // p->src = src; + } + // ip = p->ip; // for marker version + /* marker was found */ + /* (v) contains marker that was found: + bits [NUM_SHIFT_BITS : NUM_SHIFT_BITS + 7] + : value of src[-2] : xx/xx/0f + bits [0 : 7] : value of src[-1] : e8/e9/8x + */ + { { - Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]); - BoolInt needConvert; - - p->bufs[BCJ2_STREAM_MAIN] = dest + 1; - p->ip += (UInt32)num + 1; - src++; - - needConvert = False; - + #if NUM_SHIFT_BITS != 24 + v &= ~(UInt32)CONV_FLAG; + #endif + // UInt32 relat = 0; if ((SizeT)(p->srcLim - src) >= 4) { - UInt32 relatVal = GetUi32(src); - if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize) - && ((relatVal + p->relatLimit) >> 1) < p->relatLimit) - needConvert = True; + /* + if (relat != 0 || (Byte)v != 0xe8) + BoolInt isBigOffset = True; + */ + const UInt32 relat = GetUi32(src); + /* + #define EXCLUDE_FLAG ((UInt32)1 << 4) + #define NEED_CONVERT(rel) ((((rel) + EXCLUDE_FLAG) & (0 - EXCLUDE_FLAG * 2)) != 0) + if (p->relatExcludeBits != 0) + { + const UInt32 flag = (UInt32)1 << (p->relatExcludeBits - 1); + isBigOffset = (((relat + flag) & (0 - flag * 2)) != 0); + } + // isBigOffset = False; // for debug + */ + ip -= p->fileIp64; + // Use the following if check, if (ip) is 64-bit: + if (ip > (((v + 0x20) >> 5) & 1)) // 23.00 : we eliminate milti-block overlap for (Of 80) and (e8/e9) + if ((CBcj2Enc_ip_unsigned)((CBcj2Enc_ip_signed)ip + 4 + (Int32)relat) <= p->fileSize64_minus1) + if (((UInt32)(relat + p->relatLimit) >> 1) < p->relatLimit) + v |= CONV_FLAG; } - + else if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) { - UInt32 bound; - unsigned ttt; - Byte b = src[-1]; - CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0)); - - ttt = *prob; - bound = (p->range >> kNumModelBits) * ttt; - - if (!needConvert) + // (p->srcLim - src < 4) + // /* + // for non-marker version + p->ip64--; // p->ip = ip - 1; + p->bufs[BCJ2_STREAM_MAIN]--; + src--; + v >>= NUM_SHIFT_BITS; + // (0 < p->srcLim - p->src <= 4) + // */ + // v |= MARKER_FLAG; // for marker version + /* (p->state == BCJ2_ENC_STATE_ORIG) */ + WRITE_CONTEXT_AND_SRC + return; + } + { + const unsigned c = ((v + 0x17) >> 6) & 1; + CBcj2Prob *prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + /* + ((Byte)v == 0xe8 ? 2 + ((Byte)(v >> 8)) : + ((Byte)v < 0xe8 ? 0 : 1)); // ((v >> 5) & 1)); + */ + const unsigned ttt = *prob; + const UInt32 bound = (p->range >> kNumBitModelTotalBits) * ttt; + if ((v & CONV_FLAG) == 0) { + // static int yyy = 0; yyy++; printf("\n!needConvert = %d\n", yyy); + // v = (Byte)v; // for marker version p->range = bound; - *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); - p->src = src; - p->prevByte = b; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + // WRITE_CONTEXT_AND_SRC continue; } - p->low += bound; p->range -= bound; - *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); - + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } + // p->context = src[3]; + { + // const unsigned cj = ((Byte)v == 0xe8 ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP); + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; + ip = p->ip64; + v = GetUi32(src); // relat + ip += 4; + p->ip64 = ip; + src += 4; + // p->src = src; { - UInt32 relatVal = GetUi32(src); - UInt32 absVal; - p->ip += 4; - absVal = p->ip + relatVal; - p->prevByte = src[3]; - src += 4; - p->src = src; + const UInt32 absol = (UInt32)ip + v; + Byte *cur = p->bufs[cj]; + v >>= 24; + // WRITE_CONTEXT + if (cur == p->lims[cj]) { - unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; - Byte *cur = p->bufs[cj]; - if (cur == p->lims[cj]) - { - p->state = cj; - p->tempTarget = absVal; - return; - } - SetBe32(cur, absVal); - p->bufs[cj] = cur + 4; + p->state = cj; + p->tempTarget = absol; + WRITE_CONTEXT_AND_SRC + return; } + SetBe32a(cur, absol) + p->bufs[cj] = cur + 4; } } } } - } + } // end of loop } - if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) - return; - - for (; p->flushPos < 5; p->flushPos++) - if (RangeEnc_ShiftLow(p)) + for (; p->flushRem != 0; p->flushRem--) + if (Bcj2_RangeEnc_ShiftLow(p)) return; - p->state = BCJ2_ENC_STATE_OK; + p->state = BCJ2_ENC_STATE_FINISHED; } +/* +BCJ2 encoder needs look ahead for up to 4 bytes in (src) buffer. +So base function Bcj2Enc_Encode_2() + in BCJ2_ENC_FINISH_MODE_CONTINUE mode can return with + (p->state == BCJ2_ENC_STATE_ORIG && p->src < p->srcLim) +Bcj2Enc_Encode() solves that look ahead problem by using p->temp[] buffer. + so if (p->state == BCJ2_ENC_STATE_ORIG) after Bcj2Enc_Encode(), + then (p->src == p->srcLim). + And the caller's code is simpler with Bcj2Enc_Encode(). +*/ + +Z7_NO_INLINE void Bcj2Enc_Encode(CBcj2Enc *p) { - PRF(printf("\n")); - PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - + PRF2("\n----") if (p->tempPos != 0) { + /* extra: number of bytes that were copied from (src) to (temp) buffer in this call */ unsigned extra = 0; - + /* We will touch only minimal required number of bytes in input (src) stream. + So we will add input bytes from (src) stream to temp[] with step of 1 byte. + We don't add new bytes to temp[] before Bcj2Enc_Encode_2() call + in first loop iteration because + - previous call of Bcj2Enc_Encode() could use another (finishMode), + - previous call could finish with (p->state != BCJ2_ENC_STATE_ORIG). + the case with full temp[] buffer (p->tempPos == 4) is possible here. + */ for (;;) { + // (0 < p->tempPos <= 5) // in non-marker version + /* p->src : the current src data position including extra bytes + that were copied to temp[] buffer in this call */ const Byte *src = p->src; const Byte *srcLim = p->srcLim; - EBcj2Enc_FinishMode finishMode = p->finishMode; - - p->src = p->temp; - p->srcLim = p->temp + p->tempPos; + const EBcj2Enc_FinishMode finishMode = p->finishMode; if (src != srcLim) + { + /* if there are some src data after the data copied to temp[], + then we use MODE_CONTINUE for temp data */ p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - + } + p->src = p->temp; + p->srcLim = p->temp + p->tempPos; + PRF2(" ") Bcj2Enc_Encode_2(p); - { - unsigned num = (unsigned)(p->src - p->temp); - unsigned tempPos = p->tempPos - num; + const unsigned num = (unsigned)(p->src - p->temp); + const unsigned tempPos = p->tempPos - num; unsigned i; p->tempPos = tempPos; for (i = 0; i < tempPos; i++) - p->temp[i] = p->temp[(size_t)i + num]; - + p->temp[i] = p->temp[(SizeT)i + num]; + // tempPos : number of bytes in temp buffer p->src = src; p->srcLim = srcLim; p->finishMode = finishMode; - - if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim) + if (p->state != BCJ2_ENC_STATE_ORIG) + { + // (p->tempPos <= 4) // in non-marker version + /* if (the reason of exit from Bcj2Enc_Encode_2() + is not BCJ2_ENC_STATE_ORIG), + then we exit from Bcj2Enc_Encode() with same reason */ + // optional code begin : we rollback (src) and tempPos, if it's possible: + if (extra >= tempPos) + extra = tempPos; + p->src = src - extra; + p->tempPos = tempPos - extra; + // optional code end : rollback of (src) and tempPos return; - + } + /* (p->tempPos <= 4) + (p->state == BCJ2_ENC_STATE_ORIG) + so encoder needs more data than in temp[] */ + if (src == srcLim) + return; // src buffer has no more input data. + /* (src != srcLim) + so we can provide more input data from src for Bcj2Enc_Encode_2() */ if (extra >= tempPos) { - p->src = src - tempPos; + /* (extra >= tempPos) means that temp buffer contains + only data from src buffer of this call. + So now we can encode without temp buffer */ + p->src = src - tempPos; // rollback (src) p->tempPos = 0; break; } - - p->temp[tempPos] = src[0]; + // we append one additional extra byte from (src) to temp[] buffer: + p->temp[tempPos] = *src; p->tempPos = tempPos + 1; + // (0 < p->tempPos <= 5) // in non-marker version p->src = src + 1; extra++; } } } - PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - + PRF2("++++") + // (p->tempPos == 0) Bcj2Enc_Encode_2(p); + PRF2("====") if (p->state == BCJ2_ENC_STATE_ORIG) { const Byte *src = p->src; - unsigned rem = (unsigned)(p->srcLim - src); - unsigned i; - for (i = 0; i < rem; i++) - p->temp[i] = src[i]; - p->tempPos = rem; - p->src = src + rem; + const Byte *srcLim = p->srcLim; + const unsigned rem = (unsigned)(srcLim - src); + /* (rem <= 4) here. + if (p->src != p->srcLim), then + - we copy non-processed bytes from (p->src) to temp[] buffer, + - we set p->src equal to p->srcLim. + */ + if (rem) + { + unsigned i = 0; + p->src = srcLim; + p->tempPos = rem; + // (0 < p->tempPos <= 4) + do + p->temp[i] = src[i]; + while (++i != rem); + } + // (p->tempPos <= 4) + // (p->src == p->srcLim) } } + +#undef PRF2 +#undef CONV_FLAG +#undef MARKER_FLAG +#undef WRITE_CONTEXT +#undef WRITE_CONTEXT_AND_SRC +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff -Nru 7zip-22.01+dfsg/C/Blake2.h 7zip-22.01+really25.01+dfsg/C/Blake2.h --- 7zip-22.01+dfsg/C/Blake2.h 2015-06-30 16:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Blake2.h 2024-01-17 11:00:00.000000000 +0000 @@ -1,47 +1,104 @@ -/* Blake2.h -- BLAKE2 Hash -2015-06-30 : Igor Pavlov : Public domain -2015 : Samuel Neves : Public domain */ +/* Blake2.h -- BLAKE2sp Hash +2024-01-17 : Igor Pavlov : Public domain */ -#ifndef __BLAKE2_H -#define __BLAKE2_H +#ifndef ZIP7_INC_BLAKE2_H +#define ZIP7_INC_BLAKE2_H #include "7zTypes.h" -EXTERN_C_BEGIN - -#define BLAKE2S_BLOCK_SIZE 64 -#define BLAKE2S_DIGEST_SIZE 32 -#define BLAKE2SP_PARALLEL_DEGREE 8 - -typedef struct -{ - UInt32 h[8]; - UInt32 t[2]; - UInt32 f[2]; - Byte buf[BLAKE2S_BLOCK_SIZE]; - UInt32 bufPos; - UInt32 lastNode_f1; - UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */ -} CBlake2s; - -/* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ -/* -void Blake2s_Init0(CBlake2s *p); -void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size); -void Blake2s_Final(CBlake2s *p, Byte *digest); -*/ +#if 0 +#include "Compiler.h" +#include "CpuArch.h" +#if defined(MY_CPU_X86_OR_AMD64) +#if defined(__SSE2__) \ + || defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) +#include // SSE2 +#endif + +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) +#include +#if defined(__clang__) +#include +#include +#endif +#endif // avx2 +#endif // MY_CPU_X86_OR_AMD64 +#endif // 0 +EXTERN_C_BEGIN +#define Z7_BLAKE2S_BLOCK_SIZE 64 +#define Z7_BLAKE2S_DIGEST_SIZE 32 +#define Z7_BLAKE2SP_PARALLEL_DEGREE 8 +#define Z7_BLAKE2SP_NUM_STRUCT_WORDS 16 + +#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS) +typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_COMPRESS)(UInt32 *states, const Byte *data, const Byte *end); +typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_INIT)(UInt32 *states); +#endif + +// it's required that CBlake2sp is aligned for 32-bytes, +// because the code can use unaligned access with sse and avx256. +// but 64-bytes alignment can be better. +MY_ALIGN(64) typedef struct { - CBlake2s S[BLAKE2SP_PARALLEL_DEGREE]; - unsigned bufPos; + union + { +#if 0 +#if defined(MY_CPU_X86_OR_AMD64) +#if defined(__SSE2__) \ + || defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) + __m128i _pad_align_128bit[4]; +#endif // sse2 +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + __m256i _pad_align_256bit[2]; +#endif // avx2 +#endif // x86 +#endif // 0 + + void * _pad_align_ptr[8]; + UInt32 _pad_align_32bit[16]; + struct + { + unsigned cycPos; + unsigned _pad_unused; +#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS) + Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Fast; + Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Single; + Z7_BLAKE2SP_FUNC_INIT func_Init; + Z7_BLAKE2SP_FUNC_INIT func_Final; +#endif + } header; + } u; + // MY_ALIGN(64) + UInt32 states[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS]; + // MY_ALIGN(64) + UInt32 buf32[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS * 2]; } CBlake2sp; - +BoolInt Blake2sp_SetFunction(CBlake2sp *p, unsigned algo); void Blake2sp_Init(CBlake2sp *p); +void Blake2sp_InitState(CBlake2sp *p); void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size); void Blake2sp_Final(CBlake2sp *p, Byte *digest); +void z7_Black2sp_Prepare(void); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Blake2s.c 7zip-22.01+really25.01+dfsg/C/Blake2s.c --- 7zip-22.01+dfsg/C/Blake2s.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Blake2s.c 2024-05-18 11:00:00.000000000 +0000 @@ -1,244 +1,2672 @@ -/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash -2021-02-09 : Igor Pavlov : Public domain -2015 : Samuel Neves : Public domain */ +/* Blake2s.c -- BLAKE2sp Hash +2024-05-18 : Igor Pavlov : Public domain +2015-2019 : Samuel Neves : original code : CC0 1.0 Universal (CC0 1.0). */ +#include "Precomp.h" + +// #include #include #include "Blake2.h" -#include "CpuArch.h" #include "RotateDefs.h" +#include "Compiler.h" +#include "CpuArch.h" -#define rotr32 rotrFixed +/* + if defined(__AVX512F__) && defined(__AVX512VL__) + { + we define Z7_BLAKE2S_USE_AVX512_ALWAYS, + but the compiler can use avx512 for any code. + } + else if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + { we use avx512 only for sse* and avx* branches of code. } +*/ +// #define Z7_BLAKE2S_USE_AVX512_ALWAYS // for debug + +#if defined(__SSE2__) + #define Z7_BLAKE2S_USE_VECTORS +#elif defined(MY_CPU_X86_OR_AMD64) + #if defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) + #define Z7_BLAKE2S_USE_VECTORS + #endif +#endif + +#ifdef Z7_BLAKE2S_USE_VECTORS + +#define Z7_BLAKE2SP_USE_FUNCTIONS + +// define Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED, if CBlake2sp can be non aligned for 32-bytes. +// #define Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + +// SSSE3 : for _mm_shuffle_epi8 (pshufb) that improves the performance for 5-15%. +#if defined(__SSSE3__) + #define Z7_BLAKE2S_USE_SSSE3 +#elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1500) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40300) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40000) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 20300) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1000) + #define Z7_BLAKE2S_USE_SSSE3 +#endif + +#ifdef Z7_BLAKE2S_USE_SSSE3 +/* SSE41 : for _mm_insert_epi32 (pinsrd) + it can slightly reduce code size and improves the performance in some cases. + it's used only for last 512-1024 bytes, if FAST versions (2 or 3) of vector algos are used. + it can be used for all blocks in another algos (4+). +*/ +#if defined(__SSE4_1__) + #define Z7_BLAKE2S_USE_SSE41 +#elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1500) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40300) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40000) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 20300) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1000) + #define Z7_BLAKE2S_USE_SSE41 +#endif +#endif // SSSE3 + +#if defined(__GNUC__) || defined(__clang__) +#if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) && !(defined(__AVX512F__) && defined(__AVX512VL__)) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("avx512vl,avx512f"))) +#else + #if defined(Z7_BLAKE2S_USE_SSE41) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("sse4.1"))) + #elif defined(Z7_BLAKE2S_USE_SSSE3) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("ssse3"))) + #else + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("sse2"))) + #endif +#endif +#endif + + +#if defined(__AVX2__) + #define Z7_BLAKE2S_USE_AVX2 +#else + #if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) + #define Z7_BLAKE2S_USE_AVX2 + #ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) && !(defined(__AVX512F__) && defined(__AVX512VL__)) + #define BLAKE2S_ATTRIB_AVX2 __attribute__((__target__("avx512vl,avx512f"))) +#else + #define BLAKE2S_ATTRIB_AVX2 __attribute__((__target__("avx2"))) +#endif + #endif + #elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #if (Z7_MSC_VER_ORIGINAL == 1900) + #pragma warning(disable : 4752) // found Intel(R) Advanced Vector Extensions; consider using /arch:AVX + #endif + #define Z7_BLAKE2S_USE_AVX2 + #endif +#endif + +#ifdef Z7_BLAKE2S_USE_SSE41 +#include // SSE4.1 +#elif defined(Z7_BLAKE2S_USE_SSSE3) +#include // SSSE3 +#else +#include // SSE2 +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2 +#include +#if defined(__clang__) +#include +#include +#endif +#endif // avx2 + + +#if defined(__AVX512F__) && defined(__AVX512VL__) + // && defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL > 1930) + #ifndef Z7_BLAKE2S_USE_AVX512_ALWAYS + #define Z7_BLAKE2S_USE_AVX512_ALWAYS + #endif + // #pragma message ("=== Blake2s AVX512") +#endif + + +#define Z7_BLAKE2S_USE_V128_FAST +// for speed optimization for small messages: +// #define Z7_BLAKE2S_USE_V128_WAY2 + +#ifdef Z7_BLAKE2S_USE_AVX2 + +// for debug: +// gather is slow +// #define Z7_BLAKE2S_USE_GATHER + + #define Z7_BLAKE2S_USE_AVX2_FAST +// for speed optimization for small messages: +// #define Z7_BLAKE2S_USE_AVX2_WAY2 +// #define Z7_BLAKE2S_USE_AVX2_WAY4 +#if defined(Z7_BLAKE2S_USE_AVX2_WAY2) || \ + defined(Z7_BLAKE2S_USE_AVX2_WAY4) + #define Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#endif +#endif + + #define Z7_BLAKE2SP_ALGO_DEFAULT 0 + #define Z7_BLAKE2SP_ALGO_SCALAR 1 +#ifdef Z7_BLAKE2S_USE_V128_FAST + #define Z7_BLAKE2SP_ALGO_V128_FAST 2 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + #define Z7_BLAKE2SP_ALGO_V256_FAST 3 +#endif + #define Z7_BLAKE2SP_ALGO_V128_WAY1 4 +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + #define Z7_BLAKE2SP_ALGO_V128_WAY2 5 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define Z7_BLAKE2SP_ALGO_V256_WAY2 6 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + #define Z7_BLAKE2SP_ALGO_V256_WAY4 7 +#endif + +#endif // Z7_BLAKE2S_USE_VECTORS + + + + +#define BLAKE2S_FINAL_FLAG (~(UInt32)0) +#define NSW Z7_BLAKE2SP_NUM_STRUCT_WORDS +#define SUPER_BLOCK_SIZE (Z7_BLAKE2S_BLOCK_SIZE * Z7_BLAKE2SP_PARALLEL_DEGREE) +#define SUPER_BLOCK_MASK (SUPER_BLOCK_SIZE - 1) + +#define V_INDEX_0_0 0 +#define V_INDEX_1_0 1 +#define V_INDEX_2_0 2 +#define V_INDEX_3_0 3 +#define V_INDEX_0_1 4 +#define V_INDEX_1_1 5 +#define V_INDEX_2_1 6 +#define V_INDEX_3_1 7 +#define V_INDEX_0_2 8 +#define V_INDEX_1_2 9 +#define V_INDEX_2_2 10 +#define V_INDEX_3_2 11 +#define V_INDEX_0_3 12 +#define V_INDEX_1_3 13 +#define V_INDEX_2_3 14 +#define V_INDEX_3_3 15 +#define V_INDEX_4_0 0 +#define V_INDEX_5_0 1 +#define V_INDEX_6_0 2 +#define V_INDEX_7_0 3 +#define V_INDEX_7_1 4 +#define V_INDEX_4_1 5 +#define V_INDEX_5_1 6 +#define V_INDEX_6_1 7 +#define V_INDEX_6_2 8 +#define V_INDEX_7_2 9 +#define V_INDEX_4_2 10 +#define V_INDEX_5_2 11 +#define V_INDEX_5_3 12 +#define V_INDEX_6_3 13 +#define V_INDEX_7_3 14 +#define V_INDEX_4_3 15 + +#define V(row, col) v[V_INDEX_ ## row ## _ ## col] + +#define k_Blake2s_IV_0 0x6A09E667UL +#define k_Blake2s_IV_1 0xBB67AE85UL +#define k_Blake2s_IV_2 0x3C6EF372UL +#define k_Blake2s_IV_3 0xA54FF53AUL +#define k_Blake2s_IV_4 0x510E527FUL +#define k_Blake2s_IV_5 0x9B05688CUL +#define k_Blake2s_IV_6 0x1F83D9ABUL +#define k_Blake2s_IV_7 0x5BE0CD19UL -#define BLAKE2S_NUM_ROUNDS 10 -#define BLAKE2S_FINAL_FLAG (~(UInt32)0) +#define KIV(n) (k_Blake2s_IV_## n) +#ifdef Z7_BLAKE2S_USE_VECTORS +MY_ALIGN(16) static const UInt32 k_Blake2s_IV[8] = { - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL + KIV(0), KIV(1), KIV(2), KIV(3), KIV(4), KIV(5), KIV(6), KIV(7) +}; +#endif + +#define STATE_T(s) ((s) + 8) +#define STATE_F(s) ((s) + 10) + +#ifdef Z7_BLAKE2S_USE_VECTORS + +#define LOAD_128(p) _mm_load_si128 ((const __m128i *)(const void *)(p)) +#define LOADU_128(p) _mm_loadu_si128((const __m128i *)(const void *)(p)) +#ifdef Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + // here we use unaligned load and stores + // use this branch if CBlake2sp can be unaligned for 16 bytes + #define STOREU_128(p, r) _mm_storeu_si128((__m128i *)(void *)(p), r) + #define LOAD_128_FROM_STRUCT(p) LOADU_128(p) + #define STORE_128_TO_STRUCT(p, r) STOREU_128(p, r) +#else + // here we use aligned load and stores + // use this branch if CBlake2sp is aligned for 16 bytes + #define STORE_128(p, r) _mm_store_si128((__m128i *)(void *)(p), r) + #define LOAD_128_FROM_STRUCT(p) LOAD_128(p) + #define STORE_128_TO_STRUCT(p, r) STORE_128(p, r) +#endif + +#endif // Z7_BLAKE2S_USE_VECTORS + + +#if 0 +static void PrintState(const UInt32 *s, unsigned num) +{ + unsigned i; + printf("\n"); + for (i = 0; i < num; i++) + printf(" %08x", (unsigned)s[i]); +} +static void PrintStates2(const UInt32 *s, unsigned x, unsigned y) +{ + unsigned i; + for (i = 0; i < y; i++) + PrintState(s + i * x, x); + printf("\n"); +} +#endif + + +#define REP8_MACRO(m) { m(0) m(1) m(2) m(3) m(4) m(5) m(6) m(7) } + +#define BLAKE2S_NUM_ROUNDS 10 + +#if defined(Z7_BLAKE2S_USE_VECTORS) +#define ROUNDS_LOOP(mac) \ + { unsigned r; for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++) mac(r) } +#endif +/* +#define ROUNDS_LOOP_2(mac) \ + { unsigned r; for (r = 0; r < BLAKE2S_NUM_ROUNDS; r += 2) { mac(r) mac(r + 1) } } +*/ +#if 0 || 1 && !defined(Z7_BLAKE2S_USE_VECTORS) +#define ROUNDS_LOOP_UNROLLED(m) \ + { m(0) m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) } +#endif + +#define SIGMA_TABLE(M) \ + M( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ), \ + M( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ), \ + M( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ), \ + M( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ), \ + M( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ), \ + M( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ), \ + M( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ), \ + M( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ), \ + M( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ), \ + M( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ) + +#define SIGMA_TABLE_MULT(m, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + { a0*m,a1*m,a2*m,a3*m,a4*m,a5*m,a6*m,a7*m,a8*m,a9*m,a10*m,a11*m,a12*m,a13*m,a14*m,a15*m } +#define SIGMA_TABLE_MULT_4( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(4, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) + +// MY_ALIGN(32) +MY_ALIGN(16) +static const Byte k_Blake2s_Sigma_4[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_4) }; + +#define GET_SIGMA_PTR(p, index) \ + ((const void *)((const Byte *)(const void *)(p) + (index))) + +#define GET_STATE_TABLE_PTR_FROM_BYTE_POS(s, pos) \ + ((UInt32 *)(void *)((Byte *)(void *)(s) + (pos))) + + +#ifdef Z7_BLAKE2S_USE_VECTORS + + +#if 0 + // use loading constants from memory + // is faster for some compilers. + #define KK4(n) KIV(n), KIV(n), KIV(n), KIV(n) +MY_ALIGN(64) +static const UInt32 k_Blake2s_IV_WAY4[]= +{ + KK4(0), KK4(1), KK4(2), KK4(3), KK4(4), KK4(5), KK4(6), KK4(7) }; + #define GET_128_IV_WAY4(i) LOAD_128(k_Blake2s_IV_WAY4 + 4 * (i)) +#else + // use constant generation: + #define GET_128_IV_WAY4(i) _mm_set1_epi32((Int32)KIV(i)) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#define GET_CONST_128_FROM_ARRAY32(k) \ + _mm_set_epi32((Int32)(k)[3], (Int32)(k)[2], (Int32)(k)[1], (Int32)(k)[0]) +#endif + + +#if 0 +#define k_r8 _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1) +#define k_r16 _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2) +#define k_inc _mm_set_epi32(0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE) +#define k_iv0_128 GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 0) +#define k_iv4_128 GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 4) +#else +#if defined(Z7_BLAKE2S_USE_SSSE3) && \ + !defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) +MY_ALIGN(16) static const Byte k_r8_arr [16] = { 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12 }; +MY_ALIGN(16) static const Byte k_r16_arr[16] = { 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 }; +#define k_r8 LOAD_128(k_r8_arr) +#define k_r16 LOAD_128(k_r16_arr) +#endif +MY_ALIGN(16) static const UInt32 k_inc_arr[4] = { Z7_BLAKE2S_BLOCK_SIZE, 0, 0, 0 }; +#define k_inc LOAD_128(k_inc_arr) +#define k_iv0_128 LOAD_128(k_Blake2s_IV + 0) +#define k_iv4_128 LOAD_128(k_Blake2s_IV + 4) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW + +#ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 80000) + #define MY_mm256_set_m128i(hi, lo) _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1) +#else + #define MY_mm256_set_m128i _mm256_set_m128i +#endif + +#define SET_FROM_128(a) MY_mm256_set_m128i(a, a) -static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] = +#ifndef Z7_BLAKE2S_USE_AVX512_ALWAYS +MY_ALIGN(32) static const Byte k_r8_arr_256 [32] = +{ + 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12, + 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12 +}; +MY_ALIGN(32) static const Byte k_r16_arr_256[32] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13, + 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 }; +#define k_r8_256 LOAD_256(k_r8_arr_256) +#define k_r16_256 LOAD_256(k_r16_arr_256) +#endif + +// #define k_r8_256 SET_FROM_128(_mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)) +// #define k_r16_256 SET_FROM_128(_mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)) +// #define k_inc_256 SET_FROM_128(_mm_set_epi32(0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE)) +// #define k_iv0_256 SET_FROM_128(GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 0)) +#define k_iv4_256 SET_FROM_128(GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 4)) +#endif // Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#endif -static void Blake2s_Init0(CBlake2s *p) +/* +IPC(TP) ports: +1 p__5 : skl- : SSE : shufps : _mm_shuffle_ps +2 p_15 : icl+ +1 p__5 : nhm-bdw : SSE : xorps : _mm_xor_ps +3 p015 : skl+ + +3 p015 : SSE2 : pxor : _mm_xor_si128 +2 p_15: snb-bdw : SSE2 : padd : _mm_add_epi32 +2 p0_5: mrm-wsm : +3 p015 : skl+ + +2 p_15 : ivb-,icl+ : SSE2 : punpcklqdq, punpckhqdq, punpckldq, punpckhdq +2 p_15 : : SSE2 : pshufd : _mm_shuffle_epi32 +2 p_15 : : SSE2 : pshuflw : _mm_shufflelo_epi16 +2 p_15 : : SSE2 : psrldq : +2 p_15 : : SSE3 : pshufb : _mm_shuffle_epi8 +2 p_15 : : SSE4 : pblendw : _mm_blend_epi16 +1 p__5 : hsw-skl : * + +1 p0 : SSE2 : pslld (i8) : _mm_slli_si128 +2 p01 : skl+ : + +2 p_15 : ivb- : SSE3 : palignr +1 p__5 : hsw+ + +2 p_15 + p23 : ivb-, icl+ : SSE4 : pinsrd : _mm_insert_epi32(xmm, m32, i8) +1 p__5 + p23 : hsw-skl +1 p_15 + p5 : ivb-, ice+ : SSE4 : pinsrd : _mm_insert_epi32(xmm, r32, i8) +0.5 2*p5 : hsw-skl + +2 p23 : SSE2 : movd (m32) +3 p23A : adl : +1 p5: : SSE2 : movd (r32) +*/ + +#if 0 && defined(__XOP__) +// we must debug and test __XOP__ instruction +#include +#include + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) _mm_roti_epi32(r, -(c)) + #define Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED +#elif 1 && defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) _mm_ror_epi32(r, c) + #define Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED +#else + +// MSVC_1937+ uses "orps" instruction for _mm_or_si128(). +// But "orps" has low throughput: TP=1 for bdw-nhm. +// So it can be better to use _mm_add_epi32()/"paddd" (TP=2 for bdw-nhm) instead of "xorps". +// But "orps" is fast for modern cpus (skl+). +// So we are default with "or" version: +#if 0 || 0 && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL > 1937 + // minor optimization for some old cpus, if "xorps" is slow. + #define MM128_EPI32_OR_or_ADD _mm_add_epi32 +#else + #define MM128_EPI32_OR_or_ADD _mm_or_si128 +#endif + + #define MM_ROR_EPI32_VIA_SHIFT(r, c)( \ + MM128_EPI32_OR_or_ADD( \ + _mm_srli_epi32((r), (c)), \ + _mm_slli_epi32((r), 32-(c)))) + #if defined(Z7_BLAKE2S_USE_SSSE3) || defined(Z7_BLAKE2S_USE_SSE41) + #define LOAD_ROTATE_CONSTS \ + const __m128i r8 = k_r8; \ + const __m128i r16 = k_r16; + #define MM_ROR_EPI32(r, c) ( \ + ( 8==(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==(c)) ? _mm_shuffle_epi8(r,r16) \ + : MM_ROR_EPI32_VIA_SHIFT(r, c)) + #else + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) ( \ + (16==(c)) ? _mm_shufflehi_epi16(_mm_shufflelo_epi16(r, 0xb1), 0xb1) \ + : MM_ROR_EPI32_VIA_SHIFT(r, c)) + #endif +#endif + +/* +we have 3 main ways to load 4 32-bit integers to __m128i: + 1) SSE2: _mm_set_epi32() + 2) SSE2: _mm_unpacklo_epi64() / _mm_unpacklo_epi32 / _mm_cvtsi32_si128() + 3) SSE41: _mm_insert_epi32() and _mm_cvtsi32_si128() +good compiler for _mm_set_epi32() generates these instructions: { - unsigned i; - for (i = 0; i < 8; i++) - p->h[i] = k_Blake2s_IV[i]; - p->t[0] = 0; - p->t[1] = 0; - p->f[0] = 0; - p->f[1] = 0; - p->bufPos = 0; - p->lastNode_f1 = 0; + movd xmm, [m32]; vpunpckldq; vpunpckldq; vpunpcklqdq; +} +good new compiler generates one instruction +{ + for _mm_insert_epi32() : { pinsrd xmm, [m32], i } + for _mm_cvtsi32_si128() : { movd xmm, [m32] } +} +but vc2010 generates slow pair of instructions: +{ + for _mm_insert_epi32() : { mov r32, [m32]; pinsrd xmm, r32, i } + for _mm_cvtsi32_si128() : { mov r32, [m32]; movd xmm, r32 } } +_mm_insert_epi32() (pinsrd) code reduces xmm register pressure +in comparison with _mm_set_epi32() (movd + vpunpckld) code. +Note that variant with "movd xmm, r32" can be more slow, +but register pressure can be more important. +So we can force to "pinsrd" always. +*/ +// #if !defined(Z7_MSC_VER_ORIGINAL) || Z7_MSC_VER_ORIGINAL > 1600 || defined(MY_CPU_X86) +#ifdef Z7_BLAKE2S_USE_SSE41 + /* _mm_set_epi32() can be more effective for GCC and CLANG + _mm_insert_epi32() is more effective for MSVC */ + #if 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) + #define Z7_BLAKE2S_USE_INSERT_INSTRUCTION + #endif +#endif // USE_SSE41 +// #endif + +#ifdef Z7_BLAKE2S_USE_INSERT_INSTRUCTION + // for SSE4.1 +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_insert_epi32( \ + _mm_insert_epi32( \ + _mm_insert_epi32( \ + _mm_cvtsi32_si128( \ + *(const Int32 *)p0), \ + *(const Int32 *)p1, 1), \ + *(const Int32 *)p2, 2), \ + *(const Int32 *)p3, 3) +#elif 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) +/* MSVC 1400 implements _mm_set_epi32() via slow memory write/read. + Also _mm_unpacklo_epi32 is more effective for another MSVC compilers. + But _mm_set_epi32() is more effective for GCC and CLANG. + So we use _mm_unpacklo_epi32 for MSVC only */ +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_unpacklo_epi64( \ + _mm_unpacklo_epi32( _mm_cvtsi32_si128(*(const Int32 *)p0), \ + _mm_cvtsi32_si128(*(const Int32 *)p1)), \ + _mm_unpacklo_epi32( _mm_cvtsi32_si128(*(const Int32 *)p2), \ + _mm_cvtsi32_si128(*(const Int32 *)p3))) +#else +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_set_epi32( \ + *(const Int32 *)p3, \ + *(const Int32 *)p2, \ + *(const Int32 *)p1, \ + *(const Int32 *)p0) +#endif + +#define SET_ROW_FROM_SIGMA_BASE(input, i0, i1, i2, i3) \ + MM_LOAD_EPI32_FROM_4_POINTERS( \ + GET_SIGMA_PTR(input, i0), \ + GET_SIGMA_PTR(input, i1), \ + GET_SIGMA_PTR(input, i2), \ + GET_SIGMA_PTR(input, i3)) + +#define SET_ROW_FROM_SIGMA(input, sigma_index) \ + SET_ROW_FROM_SIGMA_BASE(input, \ + sigma[(sigma_index) ], \ + sigma[(sigma_index) + 2 * 1], \ + sigma[(sigma_index) + 2 * 2], \ + sigma[(sigma_index) + 2 * 3]) \ + + +#define ADD_128(a, b) _mm_add_epi32(a, b) +#define XOR_128(a, b) _mm_xor_si128(a, b) + +#define D_ADD_128(dest, src) dest = ADD_128(dest, src) +#define D_XOR_128(dest, src) dest = XOR_128(dest, src) +#define D_ROR_128(dest, shift) dest = MM_ROR_EPI32(dest, shift) +#define D_ADD_EPI64_128(dest, src) dest = _mm_add_epi64(dest, src) + + +#define AXR(a, b, d, shift) \ + D_ADD_128(a, b); \ + D_XOR_128(d, a); \ + D_ROR_128(d, shift); + +#define AXR2(a, b, c, d, input, sigma_index, shift1, shift2) \ + a = _mm_add_epi32 (a, SET_ROW_FROM_SIGMA(input, sigma_index)); \ + AXR(a, b, d, shift1) \ + AXR(c, d, b, shift2) + +#define ROTATE_WORDS_TO_RIGHT(a, n) \ + a = _mm_shuffle_epi32(a, _MM_SHUFFLE((3+n)&3, (2+n)&3, (1+n)&3, (0+n)&3)); + +#define AXR4(a, b, c, d, input, sigma_index) \ + AXR2(a, b, c, d, input, sigma_index, 16, 12) \ + AXR2(a, b, c, d, input, sigma_index + 1, 8, 7) \ + +#define RR2(a, b, c, d, input) \ + { \ + AXR4(a, b, c, d, input, 0) \ + ROTATE_WORDS_TO_RIGHT(b, 1) \ + ROTATE_WORDS_TO_RIGHT(c, 2) \ + ROTATE_WORDS_TO_RIGHT(d, 3) \ + AXR4(a, b, c, d, input, 8) \ + ROTATE_WORDS_TO_RIGHT(b, 3) \ + ROTATE_WORDS_TO_RIGHT(c, 2) \ + ROTATE_WORDS_TO_RIGHT(d, 1) \ + } + +/* +Way1: +per 64 bytes block: +10 rounds * 4 iters * (7 + 2) = 360 cycles = if pslld TP=1 + * (7 + 1) = 320 cycles = if pslld TP=2 (skl+) +additional operations per 7_op_iter : +4 movzx byte mem +1 movd mem +3 pinsrd mem +1.5 pshufd +*/ -static void Blake2s_Compress(CBlake2s *p) +static +#if 0 || 0 && (defined(Z7_BLAKE2S_USE_V128_WAY2) || \ + defined(Z7_BLAKE2S_USE_V256_WAY2)) + Z7_NO_INLINE +#else + Z7_FORCE_INLINE +#endif +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2s_Compress_V128_Way1(UInt32 * const s, const Byte * const input) { - UInt32 m[16]; - UInt32 v[16]; - + __m128i a, b, c, d; + __m128i f0, f1; + + LOAD_ROTATE_CONSTS + d = LOAD_128_FROM_STRUCT(STATE_T(s)); + c = k_iv0_128; + a = f0 = LOAD_128_FROM_STRUCT(s); + b = f1 = LOAD_128_FROM_STRUCT(s + 4); + D_ADD_EPI64_128(d, k_inc); + STORE_128_TO_STRUCT (STATE_T(s), d); + D_XOR_128(d, k_iv4_128); + +#define RR(r) { const Byte * const sigma = k_Blake2s_Sigma_4[r]; \ + RR2(a, b, c, d, input) } + + ROUNDS_LOOP(RR) +#undef RR + + STORE_128_TO_STRUCT(s , XOR_128(f0, XOR_128(a, c))); + STORE_128_TO_STRUCT(s + 4, XOR_128(f1, XOR_128(b, d))); +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Way1(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + do { - unsigned i; + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Blake2s_Compress_V128_Way1(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + + +#if defined(Z7_BLAKE2S_USE_V128_WAY2) || \ + defined(Z7_BLAKE2S_USE_AVX2_WAY2) +#if 1 + #define Z7_BLAKE2S_CompressSingleBlock(s, data) \ + Blake2sp_Compress2_V128_Way1(s, data, \ + (const Byte *)(const void *)(data) + Z7_BLAKE2S_BLOCK_SIZE) +#else + #define Z7_BLAKE2S_CompressSingleBlock Blake2s_Compress_V128_Way1 +#endif +#endif + + +#if (defined(Z7_BLAKE2S_USE_AVX2_WAY_SLOW) || \ + defined(Z7_BLAKE2S_USE_V128_WAY2)) && \ + !defined(Z7_BLAKE2S_USE_GATHER) +#define AXR2_LOAD_INDEXES(sigma_index) \ + const unsigned i0 = sigma[(sigma_index)]; \ + const unsigned i1 = sigma[(sigma_index) + 2 * 1]; \ + const unsigned i2 = sigma[(sigma_index) + 2 * 2]; \ + const unsigned i3 = sigma[(sigma_index) + 2 * 3]; \ + +#define SET_ROW_FROM_SIGMA_W(input) \ + SET_ROW_FROM_SIGMA_BASE(input, i0, i1, i2, i3) +#endif + + +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + +#if 1 || !defined(Z7_BLAKE2S_USE_SSE41) +/* we use SET_ROW_FROM_SIGMA_BASE, that uses + (SSE4) _mm_insert_epi32(), if Z7_BLAKE2S_USE_INSERT_INSTRUCTION is defined + (SSE2) _mm_set_epi32() + MSVC can be faster for this branch: +*/ +#define AXR2_W(sigma_index, shift1, shift2) \ + { \ + AXR2_LOAD_INDEXES(sigma_index) \ + a0 = _mm_add_epi32(a0, SET_ROW_FROM_SIGMA_W(data)); \ + a1 = _mm_add_epi32(a1, SET_ROW_FROM_SIGMA_W(data + Z7_BLAKE2S_BLOCK_SIZE)); \ + AXR(a0, b0, d0, shift1) \ + AXR(a1, b1, d1, shift1) \ + AXR(c0, d0, b0, shift2) \ + AXR(c1, d1, b1, shift2) \ + } +#else +/* we use interleaved _mm_insert_epi32(): + GCC can be faster for this branch: +*/ +#define AXR2_W_PRE_INSERT(sigma_index, i) \ + { const unsigned ii = sigma[(sigma_index) + i * 2]; \ + t0 = _mm_insert_epi32(t0, *(const Int32 *)GET_SIGMA_PTR(data, ii), i); \ + t1 = _mm_insert_epi32(t1, *(const Int32 *)GET_SIGMA_PTR(data, Z7_BLAKE2S_BLOCK_SIZE + ii), i); \ + } +#define AXR2_W(sigma_index, shift1, shift2) \ + { __m128i t0, t1; \ + { const unsigned ii = sigma[sigma_index]; \ + t0 = _mm_cvtsi32_si128(*(const Int32 *)GET_SIGMA_PTR(data, ii)); \ + t1 = _mm_cvtsi32_si128(*(const Int32 *)GET_SIGMA_PTR(data, Z7_BLAKE2S_BLOCK_SIZE + ii)); \ + } \ + AXR2_W_PRE_INSERT(sigma_index, 1) \ + AXR2_W_PRE_INSERT(sigma_index, 2) \ + AXR2_W_PRE_INSERT(sigma_index, 3) \ + a0 = _mm_add_epi32(a0, t0); \ + a1 = _mm_add_epi32(a1, t1); \ + AXR(a0, b0, d0, shift1) \ + AXR(a1, b1, d1, shift1) \ + AXR(c0, d0, b0, shift2) \ + AXR(c1, d1, b1, shift2) \ + } +#endif + + +#define AXR4_W(sigma_index) \ + AXR2_W(sigma_index, 16, 12) \ + AXR2_W(sigma_index + 1, 8, 7) \ + +#define WW(r) \ + { const Byte * const sigma = k_Blake2s_Sigma_4[r]; \ + AXR4_W(0) \ + ROTATE_WORDS_TO_RIGHT(b0, 1) \ + ROTATE_WORDS_TO_RIGHT(b1, 1) \ + ROTATE_WORDS_TO_RIGHT(c0, 2) \ + ROTATE_WORDS_TO_RIGHT(c1, 2) \ + ROTATE_WORDS_TO_RIGHT(d0, 3) \ + ROTATE_WORDS_TO_RIGHT(d1, 3) \ + AXR4_W(8) \ + ROTATE_WORDS_TO_RIGHT(b0, 3) \ + ROTATE_WORDS_TO_RIGHT(b1, 3) \ + ROTATE_WORDS_TO_RIGHT(c0, 2) \ + ROTATE_WORDS_TO_RIGHT(c1, 2) \ + ROTATE_WORDS_TO_RIGHT(d0, 1) \ + ROTATE_WORDS_TO_RIGHT(d1, 1) \ + } + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Way2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + end -= Z7_BLAKE2S_BLOCK_SIZE; + + if (data != end) + { + LOAD_ROTATE_CONSTS + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m128i a0, b0, c0, d0; + __m128i a1, b1, c1, d1; + { + const __m128i inc = k_inc; + const __m128i temp = k_iv4_128; + d0 = LOAD_128_FROM_STRUCT (STATE_T(s)); + d1 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + D_ADD_EPI64_128(d0, inc); + D_ADD_EPI64_128(d1, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0); + STORE_128_TO_STRUCT (STATE_T(s + NSW), d1); + D_XOR_128(d0, temp); + D_XOR_128(d1, temp); + } + c1 = c0 = k_iv0_128; + a0 = LOAD_128_FROM_STRUCT(s); + b0 = LOAD_128_FROM_STRUCT(s + 4); + a1 = LOAD_128_FROM_STRUCT(s + NSW); + b1 = LOAD_128_FROM_STRUCT(s + NSW + 4); + + ROUNDS_LOOP (WW) + +#undef WW + + D_XOR_128(a0, c0); + D_XOR_128(b0, d0); + D_XOR_128(a1, c1); + D_XOR_128(b1, d1); + + D_XOR_128(a0, LOAD_128_FROM_STRUCT(s)); + D_XOR_128(b0, LOAD_128_FROM_STRUCT(s + 4)); + D_XOR_128(a1, LOAD_128_FROM_STRUCT(s + NSW)); + D_XOR_128(b1, LOAD_128_FROM_STRUCT(s + NSW + 4)); + + STORE_128_TO_STRUCT(s, a0); + STORE_128_TO_STRUCT(s + 4, b0); + STORE_128_TO_STRUCT(s + NSW, a1); + STORE_128_TO_STRUCT(s + NSW + 4, b1); + + data += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + if (data != end) + return; + } + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); + } +} +#endif // Z7_BLAKE2S_USE_V128_WAY2 + + +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + #define Z7_BLAKE2S_Compress2_V128 Blake2sp_Compress2_V128_Way2 +#else + #define Z7_BLAKE2S_Compress2_V128 Blake2sp_Compress2_V128_Way1 +#endif + + + +#ifdef Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED + #define ROT_128_8(x) MM_ROR_EPI32(x, 8) + #define ROT_128_16(x) MM_ROR_EPI32(x, 16) + #define ROT_128_7(x) MM_ROR_EPI32(x, 7) + #define ROT_128_12(x) MM_ROR_EPI32(x, 12) +#else +#if defined(Z7_BLAKE2S_USE_SSSE3) || defined(Z7_BLAKE2S_USE_SSE41) + #define ROT_128_8(x) _mm_shuffle_epi8(x, r8) // k_r8 + #define ROT_128_16(x) _mm_shuffle_epi8(x, r16) // k_r16 +#else + #define ROT_128_8(x) MM_ROR_EPI32_VIA_SHIFT(x, 8) + #define ROT_128_16(x) MM_ROR_EPI32_VIA_SHIFT(x, 16) +#endif + #define ROT_128_7(x) MM_ROR_EPI32_VIA_SHIFT(x, 7) + #define ROT_128_12(x) MM_ROR_EPI32_VIA_SHIFT(x, 12) +#endif + + +#if 1 +// this branch can provide similar speed on x86* in most cases, +// because [base + index*4] provides same speed as [base + index]. +// but some compilers can generate different code with this branch, that can be faster sometimes. +// this branch uses additional table of 10*16=160 bytes. +#define SIGMA_TABLE_MULT_16( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(16, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) +MY_ALIGN(16) +static const Byte k_Blake2s_Sigma_16[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_16) }; +#define GET_SIGMA_PTR_128(r) const Byte * const sigma = k_Blake2s_Sigma_16[r]; +#define GET_SIGMA_VAL_128(n) (sigma[n]) +#else +#define GET_SIGMA_PTR_128(r) const Byte * const sigma = k_Blake2s_Sigma_4[r]; +#define GET_SIGMA_VAL_128(n) (4 * (size_t)sigma[n]) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST +#if 1 +#define SIGMA_TABLE_MULT_32( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(32, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) +MY_ALIGN(64) +static const UInt16 k_Blake2s_Sigma_32[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_32) }; +#define GET_SIGMA_PTR_256(r) const UInt16 * const sigma = k_Blake2s_Sigma_32[r]; +#define GET_SIGMA_VAL_256(n) (sigma[n]) +#else +#define GET_SIGMA_PTR_256(r) const Byte * const sigma = k_Blake2s_Sigma_4[r]; +#define GET_SIGMA_VAL_256(n) (8 * (size_t)sigma[n]) +#endif +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + +#define D_ROT_128_7(dest) dest = ROT_128_7(dest) +#define D_ROT_128_8(dest) dest = ROT_128_8(dest) +#define D_ROT_128_12(dest) dest = ROT_128_12(dest) +#define D_ROT_128_16(dest) dest = ROT_128_16(dest) + +#define OP_L(a, i) D_ADD_128 (V(a, 0), \ + LOAD_128((const Byte *)(w) + GET_SIGMA_VAL_128(2*(a)+(i)))); + +#define OP_0(a) OP_L(a, 0) +#define OP_7(a) OP_L(a, 1) + +#define OP_1(a) D_ADD_128 (V(a, 0), V(a, 1)); +#define OP_2(a) D_XOR_128 (V(a, 3), V(a, 0)); +#define OP_4(a) D_ADD_128 (V(a, 2), V(a, 3)); +#define OP_5(a) D_XOR_128 (V(a, 1), V(a, 2)); + +#define OP_3(a) D_ROT_128_16 (V(a, 3)); +#define OP_6(a) D_ROT_128_12 (V(a, 1)); +#define OP_8(a) D_ROT_128_8 (V(a, 3)); +#define OP_9(a) D_ROT_128_7 (V(a, 1)); + + +// for 32-bit x86 : interleave mode works slower, because of register pressure. + +#if 0 || 1 && (defined(MY_CPU_X86) \ + || defined(__GNUC__) && !defined(__clang__)) +// non-inteleaved version: +// is fast for x86 32-bit. +// is fast for GCC x86-64. + +#define V4G(a) \ + OP_0 (a) \ + OP_1 (a) \ + OP_2 (a) \ + OP_3 (a) \ + OP_4 (a) \ + OP_5 (a) \ + OP_6 (a) \ + OP_7 (a) \ + OP_1 (a) \ + OP_2 (a) \ + OP_8 (a) \ + OP_4 (a) \ + OP_5 (a) \ + OP_9 (a) \ + +#define V4R \ +{ \ + V4G (0) \ + V4G (1) \ + V4G (2) \ + V4G (3) \ + V4G (4) \ + V4G (5) \ + V4G (6) \ + V4G (7) \ +} + +#elif 0 || 1 && defined(MY_CPU_X86) + +#define OP_INTER_2(op, a,b) \ + op (a) \ + op (b) \ + +#define V4G(a,b) \ + OP_INTER_2 (OP_0, a,b) \ + OP_INTER_2 (OP_1, a,b) \ + OP_INTER_2 (OP_2, a,b) \ + OP_INTER_2 (OP_3, a,b) \ + OP_INTER_2 (OP_4, a,b) \ + OP_INTER_2 (OP_5, a,b) \ + OP_INTER_2 (OP_6, a,b) \ + OP_INTER_2 (OP_7, a,b) \ + OP_INTER_2 (OP_1, a,b) \ + OP_INTER_2 (OP_2, a,b) \ + OP_INTER_2 (OP_8, a,b) \ + OP_INTER_2 (OP_4, a,b) \ + OP_INTER_2 (OP_5, a,b) \ + OP_INTER_2 (OP_9, a,b) \ + +#define V4R \ +{ \ + V4G (0, 1) \ + V4G (2, 3) \ + V4G (4, 5) \ + V4G (6, 7) \ +} + +#else +// iterleave-4 version is fast for x64 (MSVC/CLANG) + +#define OP_INTER_4(op, a,b,c,d) \ + op (a) \ + op (b) \ + op (c) \ + op (d) \ + +#define V4G(a,b,c,d) \ + OP_INTER_4 (OP_0, a,b,c,d) \ + OP_INTER_4 (OP_1, a,b,c,d) \ + OP_INTER_4 (OP_2, a,b,c,d) \ + OP_INTER_4 (OP_3, a,b,c,d) \ + OP_INTER_4 (OP_4, a,b,c,d) \ + OP_INTER_4 (OP_5, a,b,c,d) \ + OP_INTER_4 (OP_6, a,b,c,d) \ + OP_INTER_4 (OP_7, a,b,c,d) \ + OP_INTER_4 (OP_1, a,b,c,d) \ + OP_INTER_4 (OP_2, a,b,c,d) \ + OP_INTER_4 (OP_8, a,b,c,d) \ + OP_INTER_4 (OP_4, a,b,c,d) \ + OP_INTER_4 (OP_5, a,b,c,d) \ + OP_INTER_4 (OP_9, a,b,c,d) \ + +#define V4R \ +{ \ + V4G (0, 1, 2, 3) \ + V4G (4, 5, 6, 7) \ +} + +#endif + +#define V4_ROUND(r) { GET_SIGMA_PTR_128(r); V4R } + + +#define V4_LOAD_MSG_1(w, m, i) \ +{ \ + __m128i m0, m1, m2, m3; \ + __m128i t0, t1, t2, t3; \ + m0 = LOADU_128((m) + ((i) + 0 * 4) * 16); \ + m1 = LOADU_128((m) + ((i) + 1 * 4) * 16); \ + m2 = LOADU_128((m) + ((i) + 2 * 4) * 16); \ + m3 = LOADU_128((m) + ((i) + 3 * 4) * 16); \ + t0 = _mm_unpacklo_epi32(m0, m1); \ + t1 = _mm_unpackhi_epi32(m0, m1); \ + t2 = _mm_unpacklo_epi32(m2, m3); \ + t3 = _mm_unpackhi_epi32(m2, m3); \ + w[(i) * 4 + 0] = _mm_unpacklo_epi64(t0, t2); \ + w[(i) * 4 + 1] = _mm_unpackhi_epi64(t0, t2); \ + w[(i) * 4 + 2] = _mm_unpacklo_epi64(t1, t3); \ + w[(i) * 4 + 3] = _mm_unpackhi_epi64(t1, t3); \ +} + +#define V4_LOAD_MSG(w, m) \ +{ \ + V4_LOAD_MSG_1 (w, m, 0) \ + V4_LOAD_MSG_1 (w, m, 1) \ + V4_LOAD_MSG_1 (w, m, 2) \ + V4_LOAD_MSG_1 (w, m, 3) \ +} + +#define V4_LOAD_UNPACK_PAIR_128(src32, i, d0, d1) \ +{ \ + const __m128i v0 = LOAD_128_FROM_STRUCT((src32) + (i ) * 4); \ + const __m128i v1 = LOAD_128_FROM_STRUCT((src32) + (i + 1) * 4); \ + d0 = _mm_unpacklo_epi32(v0, v1); \ + d1 = _mm_unpackhi_epi32(v0, v1); \ +} + +#define V4_UNPACK_PAIR_128(dest32, i, s0, s1) \ +{ \ + STORE_128_TO_STRUCT((dest32) + i * 4 , _mm_unpacklo_epi64(s0, s1)); \ + STORE_128_TO_STRUCT((dest32) + i * 4 + 16, _mm_unpackhi_epi64(s0, s1)); \ +} + +#define V4_UNPACK_STATE(dest32, src32) \ +{ \ + __m128i t0, t1, t2, t3, t4, t5, t6, t7; \ + V4_LOAD_UNPACK_PAIR_128(src32, 0, t0, t1) \ + V4_LOAD_UNPACK_PAIR_128(src32, 2, t2, t3) \ + V4_LOAD_UNPACK_PAIR_128(src32, 4, t4, t5) \ + V4_LOAD_UNPACK_PAIR_128(src32, 6, t6, t7) \ + V4_UNPACK_PAIR_128(dest32, 0, t0, t2) \ + V4_UNPACK_PAIR_128(dest32, 8, t1, t3) \ + V4_UNPACK_PAIR_128(dest32, 1, t4, t6) \ + V4_UNPACK_PAIR_128(dest32, 9, t5, t7) \ +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Fast(UInt32 *s_items, const Byte *data, const Byte *end) +{ + // PrintStates2(s_items, 8, 16); + size_t pos = 0; + pos /= 2; + do + { +#if defined(Z7_BLAKE2S_USE_SSSE3) && \ + !defined(Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED) + const __m128i r8 = k_r8; + const __m128i r16 = k_r16; +#endif + __m128i w[16]; + __m128i v[16]; + UInt32 *s; + V4_LOAD_MSG(w, data) + s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + { + __m128i ctr = LOAD_128_FROM_STRUCT(s + 64); + D_ADD_EPI64_128 (ctr, k_inc); + STORE_128_TO_STRUCT(s + 64, ctr); + v[12] = XOR_128 (GET_128_IV_WAY4(4), _mm_shuffle_epi32(ctr, _MM_SHUFFLE(0, 0, 0, 0))); + v[13] = XOR_128 (GET_128_IV_WAY4(5), _mm_shuffle_epi32(ctr, _MM_SHUFFLE(1, 1, 1, 1))); + } + v[ 8] = GET_128_IV_WAY4(0); + v[ 9] = GET_128_IV_WAY4(1); + v[10] = GET_128_IV_WAY4(2); + v[11] = GET_128_IV_WAY4(3); + v[14] = GET_128_IV_WAY4(6); + v[15] = GET_128_IV_WAY4(7); - for (i = 0; i < 16; i++) - m[i] = GetUi32(p->buf + i * sizeof(m[i])); +#define LOAD_STATE_128_FROM_STRUCT(i) \ + v[i] = LOAD_128_FROM_STRUCT(s + (i) * 4); + +#define UPDATE_STATE_128_IN_STRUCT(i) \ + STORE_128_TO_STRUCT(s + (i) * 4, XOR_128( \ + XOR_128(v[i], v[(i) + 8]), \ + LOAD_128_FROM_STRUCT(s + (i) * 4))); - for (i = 0; i < 8; i++) - v[i] = p->h[i]; + REP8_MACRO (LOAD_STATE_128_FROM_STRUCT) + ROUNDS_LOOP (V4_ROUND) + REP8_MACRO (UPDATE_STATE_128_IN_STRUCT) + + data += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos += Z7_BLAKE2S_BLOCK_SIZE * 4 / 2; + pos &= SUPER_BLOCK_SIZE / 2 - 1; } + while (data != end); +} - v[ 8] = k_Blake2s_IV[0]; - v[ 9] = k_Blake2s_IV[1]; - v[10] = k_Blake2s_IV[2]; - v[11] = k_Blake2s_IV[3]; - - v[12] = p->t[0] ^ k_Blake2s_IV[4]; - v[13] = p->t[1] ^ k_Blake2s_IV[5]; - v[14] = p->f[0] ^ k_Blake2s_IV[6]; - v[15] = p->f[1] ^ k_Blake2s_IV[7]; - - #define G(r,i,a,b,c,d) \ - a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \ - a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \ - - #define R(r) \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Final_V128_Fast(UInt32 *states) +{ + const __m128i ctr = LOAD_128_FROM_STRUCT(states + 64); + // printf("\nBlake2sp_Compress2_V128_Fast_Final4\n"); + // PrintStates2(states, 8, 16); + { + ptrdiff_t pos = 8 * 4; + do + { + UInt32 *src32 = states + (size_t)(pos * 1); + UInt32 *dest32 = states + (size_t)(pos * 2); + V4_UNPACK_STATE(dest32, src32) + pos -= 8 * 4; + } + while (pos >= 0); + } { - unsigned r; - for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++) + unsigned k; + for (k = 0; k < 8; k++) { - const Byte *sigma = k_Blake2s_Sigma[r]; - R(r); + UInt32 *s = states + (size_t)k * 16; + STORE_128_TO_STRUCT (STATE_T(s), ctr); } - /* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */ } + // PrintStates2(states, 8, 16); +} + - #undef G - #undef R +#ifdef Z7_BLAKE2S_USE_AVX2 + +#define ADD_256(a, b) _mm256_add_epi32(a, b) +#define XOR_256(a, b) _mm256_xor_si256(a, b) + +#if 1 && defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #define MM256_ROR_EPI32 _mm256_ror_epi32 + #define Z7_MM256_ROR_EPI32_IS_SUPPORTED +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define LOAD_ROTATE_CONSTS_256 +#endif +#else +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define LOAD_ROTATE_CONSTS_256 \ + const __m256i r8 = k_r8_256; \ + const __m256i r16 = k_r16_256; +#endif // AVX2_WAY2 + + #define MM256_ROR_EPI32(r, c) ( \ + ( 8==(c)) ? _mm256_shuffle_epi8(r,r8) \ + : (16==(c)) ? _mm256_shuffle_epi8(r,r16) \ + : _mm256_or_si256( \ + _mm256_srli_epi32((r), (c)), \ + _mm256_slli_epi32((r), 32-(c)))) +#endif // WAY_SLOW +#endif + + +#define D_ADD_256(dest, src) dest = ADD_256(dest, src) +#define D_XOR_256(dest, src) dest = XOR_256(dest, src) + +#define LOADU_256(p) _mm256_loadu_si256((const __m256i *)(const void *)(p)) + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +#ifdef Z7_MM256_ROR_EPI32_IS_SUPPORTED +#define ROT_256_16(x) MM256_ROR_EPI32((x), 16) +#define ROT_256_12(x) MM256_ROR_EPI32((x), 12) +#define ROT_256_8(x) MM256_ROR_EPI32((x), 8) +#define ROT_256_7(x) MM256_ROR_EPI32((x), 7) +#else +#define ROTATE8 _mm256_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, \ + 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1) +#define ROTATE16 _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, \ + 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2) +#define ROT_256_16(x) _mm256_shuffle_epi8((x), ROTATE16) +#define ROT_256_12(x) _mm256_or_si256(_mm256_srli_epi32((x), 12), _mm256_slli_epi32((x), 20)) +#define ROT_256_8(x) _mm256_shuffle_epi8((x), ROTATE8) +#define ROT_256_7(x) _mm256_or_si256(_mm256_srli_epi32((x), 7), _mm256_slli_epi32((x), 25)) +#endif + +#define D_ROT_256_7(dest) dest = ROT_256_7(dest) +#define D_ROT_256_8(dest) dest = ROT_256_8(dest) +#define D_ROT_256_12(dest) dest = ROT_256_12(dest) +#define D_ROT_256_16(dest) dest = ROT_256_16(dest) + +#define LOAD_256(p) _mm256_load_si256((const __m256i *)(const void *)(p)) +#ifdef Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + #define STOREU_256(p, r) _mm256_storeu_si256((__m256i *)(void *)(p), r) + #define LOAD_256_FROM_STRUCT(p) LOADU_256(p) + #define STORE_256_TO_STRUCT(p, r) STOREU_256(p, r) +#else + // if struct is aligned for 32-bytes + #define STORE_256(p, r) _mm256_store_si256((__m256i *)(void *)(p), r) + #define LOAD_256_FROM_STRUCT(p) LOAD_256(p) + #define STORE_256_TO_STRUCT(p, r) STORE_256(p, r) +#endif + +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW + +#if 0 + #define DIAG_PERM2(s) \ + { \ + const __m256i a = LOAD_256_FROM_STRUCT((s) ); \ + const __m256i b = LOAD_256_FROM_STRUCT((s) + NSW); \ + STORE_256_TO_STRUCT((s ), _mm256_permute2x128_si256(a, b, 0x20)); \ + STORE_256_TO_STRUCT((s + NSW), _mm256_permute2x128_si256(a, b, 0x31)); \ + } +#else + #define DIAG_PERM2(s) \ + { \ + const __m128i a = LOAD_128_FROM_STRUCT((s) + 4); \ + const __m128i b = LOAD_128_FROM_STRUCT((s) + NSW); \ + STORE_128_TO_STRUCT((s) + NSW, a); \ + STORE_128_TO_STRUCT((s) + 4 , b); \ + } +#endif + #define DIAG_PERM8(s_items) \ + { \ + DIAG_PERM2(s_items) \ + DIAG_PERM2(s_items + NSW * 2) \ + DIAG_PERM2(s_items + NSW * 4) \ + DIAG_PERM2(s_items + NSW * 6) \ + } + + +#define AXR256(a, b, d, shift) \ + D_ADD_256(a, b); \ + D_XOR_256(d, a); \ + d = MM256_ROR_EPI32(d, shift); \ + + + +#ifdef Z7_BLAKE2S_USE_GATHER + + #define TABLE_GATHER_256_4(a0,a1,a2,a3) \ + a0,a1,a2,a3, a0+16,a1+16,a2+16,a3+16 + #define TABLE_GATHER_256( \ + a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + { TABLE_GATHER_256_4(a0,a2,a4,a6), \ + TABLE_GATHER_256_4(a1,a3,a5,a7), \ + TABLE_GATHER_256_4(a8,a10,a12,a14), \ + TABLE_GATHER_256_4(a9,a11,a13,a15) } +MY_ALIGN(64) +static const UInt32 k_Blake2s_Sigma_gather256[BLAKE2S_NUM_ROUNDS][16 * 2] = + { SIGMA_TABLE(TABLE_GATHER_256) }; + #define GET_SIGMA(r) \ + const UInt32 * const sigma = k_Blake2s_Sigma_gather256[r]; + #define AXR2_LOAD_INDEXES_AVX(sigma_index) \ + const __m256i i01234567 = LOAD_256(sigma + (sigma_index)); + #define SET_ROW_FROM_SIGMA_AVX(in) \ + _mm256_i32gather_epi32((const void *)(in), i01234567, 4) + #define SIGMA_INTERLEAVE 8 + #define SIGMA_HALF_ROW_SIZE 16 + +#else // !Z7_BLAKE2S_USE_GATHER + + #define GET_SIGMA(r) \ + const Byte * const sigma = k_Blake2s_Sigma_4[r]; + #define AXR2_LOAD_INDEXES_AVX(sigma_index) \ + AXR2_LOAD_INDEXES(sigma_index) + #define SET_ROW_FROM_SIGMA_AVX(in) \ + MY_mm256_set_m128i( \ + SET_ROW_FROM_SIGMA_W((in) + Z7_BLAKE2S_BLOCK_SIZE), \ + SET_ROW_FROM_SIGMA_W(in)) + #define SIGMA_INTERLEAVE 1 + #define SIGMA_HALF_ROW_SIZE 8 +#endif // !Z7_BLAKE2S_USE_GATHER + + +#define ROTATE_WORDS_TO_RIGHT_256(a, n) \ + a = _mm256_shuffle_epi32(a, _MM_SHUFFLE((3+n)&3, (2+n)&3, (1+n)&3, (0+n)&3)); + + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + +#define AXR2_A(sigma_index, shift1, shift2) \ + AXR2_LOAD_INDEXES_AVX(sigma_index) \ + D_ADD_256( a0, SET_ROW_FROM_SIGMA_AVX(data)); \ + AXR256(a0, b0, d0, shift1) \ + AXR256(c0, d0, b0, shift2) \ + +#define AXR4_A(sigma_index) \ + { AXR2_A(sigma_index, 16, 12) } \ + { AXR2_A(sigma_index + SIGMA_INTERLEAVE, 8, 7) } + +#define EE1(r) \ + { GET_SIGMA(r) \ + AXR4_A(0) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 3) \ + AXR4_A(SIGMA_HALF_ROW_SIZE) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 1) \ + } + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Way2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + end -= Z7_BLAKE2S_BLOCK_SIZE; + + if (data != end) { - unsigned i; - for (i = 0; i < 8; i++) - p->h[i] ^= v[i] ^ v[i + 8]; + LOAD_ROTATE_CONSTS_256 + DIAG_PERM8(s_items) + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m256i a0, b0, c0, d0; + { + const __m128i inc = k_inc; + __m128i d0_128 = LOAD_128_FROM_STRUCT (STATE_T(s)); + __m128i d1_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + D_ADD_EPI64_128(d0_128, inc); + D_ADD_EPI64_128(d1_128, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW), d1_128); + d0 = MY_mm256_set_m128i(d1_128, d0_128); + D_XOR_256(d0, k_iv4_256); + } + c0 = SET_FROM_128(k_iv0_128); + a0 = LOAD_256_FROM_STRUCT(s + NSW * 0); + b0 = LOAD_256_FROM_STRUCT(s + NSW * 1); + + ROUNDS_LOOP (EE1) + + D_XOR_256(a0, c0); + D_XOR_256(b0, d0); + + D_XOR_256(a0, LOAD_256_FROM_STRUCT(s + NSW * 0)); + D_XOR_256(b0, LOAD_256_FROM_STRUCT(s + NSW * 1)); + + STORE_256_TO_STRUCT(s + NSW * 0, a0); + STORE_256_TO_STRUCT(s + NSW * 1, b0); + + data += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + DIAG_PERM8(s_items) + if (data != end) + return; + } + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); } } +#endif // Z7_BLAKE2S_USE_AVX2_WAY2 + -#define Blake2s_Increment_Counter(S, inc) \ - { p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); } -#define Blake2s_Set_LastBlock(p) \ - { p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; } +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 +#define AXR2_X(sigma_index, shift1, shift2) \ + AXR2_LOAD_INDEXES_AVX(sigma_index) \ + D_ADD_256( a0, SET_ROW_FROM_SIGMA_AVX(data)); \ + D_ADD_256( a1, SET_ROW_FROM_SIGMA_AVX((data) + Z7_BLAKE2S_BLOCK_SIZE * 2)); \ + AXR256(a0, b0, d0, shift1) \ + AXR256(a1, b1, d1, shift1) \ + AXR256(c0, d0, b0, shift2) \ + AXR256(c1, d1, b1, shift2) \ + +#define AXR4_X(sigma_index) \ + { AXR2_X(sigma_index, 16, 12) } \ + { AXR2_X(sigma_index + SIGMA_INTERLEAVE, 8, 7) } + +#define EE2(r) \ + { GET_SIGMA(r) \ + AXR4_X(0) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(b1, 1) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(c1, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(d1, 3) \ + AXR4_X(SIGMA_HALF_ROW_SIZE) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(b1, 3) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(c1, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(d1, 1) \ + } -static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size) +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Way4(UInt32 *s_items, const Byte *data, const Byte *end) { - while (size != 0) + size_t pos = 0; + + if ((size_t)(end - data) >= Z7_BLAKE2S_BLOCK_SIZE * 4) { - unsigned pos = (unsigned)p->bufPos; - unsigned rem = BLAKE2S_BLOCK_SIZE - pos; +#ifndef Z7_MM256_ROR_EPI32_IS_SUPPORTED + const __m256i r8 = k_r8_256; + const __m256i r16 = k_r16_256; +#endif + end -= Z7_BLAKE2S_BLOCK_SIZE * 3; + DIAG_PERM8(s_items) + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m256i a0, b0, c0, d0; + __m256i a1, b1, c1, d1; + { + const __m128i inc = k_inc; + __m128i d0_128 = LOAD_128_FROM_STRUCT (STATE_T(s)); + __m128i d1_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + __m128i d2_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW * 2)); + __m128i d3_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW * 3)); + D_ADD_EPI64_128(d0_128, inc); + D_ADD_EPI64_128(d1_128, inc); + D_ADD_EPI64_128(d2_128, inc); + D_ADD_EPI64_128(d3_128, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 1), d1_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 2), d2_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 3), d3_128); + d0 = MY_mm256_set_m128i(d1_128, d0_128); + d1 = MY_mm256_set_m128i(d3_128, d2_128); + D_XOR_256(d0, k_iv4_256); + D_XOR_256(d1, k_iv4_256); + } + c1 = c0 = SET_FROM_128(k_iv0_128); + a0 = LOAD_256_FROM_STRUCT(s + NSW * 0); + b0 = LOAD_256_FROM_STRUCT(s + NSW * 1); + a1 = LOAD_256_FROM_STRUCT(s + NSW * 2); + b1 = LOAD_256_FROM_STRUCT(s + NSW * 3); + + ROUNDS_LOOP (EE2) + + D_XOR_256(a0, c0); + D_XOR_256(b0, d0); + D_XOR_256(a1, c1); + D_XOR_256(b1, d1); + + D_XOR_256(a0, LOAD_256_FROM_STRUCT(s + NSW * 0)); + D_XOR_256(b0, LOAD_256_FROM_STRUCT(s + NSW * 1)); + D_XOR_256(a1, LOAD_256_FROM_STRUCT(s + NSW * 2)); + D_XOR_256(b1, LOAD_256_FROM_STRUCT(s + NSW * 3)); + + STORE_256_TO_STRUCT(s + NSW * 0, a0); + STORE_256_TO_STRUCT(s + NSW * 1, b0); + STORE_256_TO_STRUCT(s + NSW * 2, a1); + STORE_256_TO_STRUCT(s + NSW * 3, b1); + + data += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + DIAG_PERM8(s_items) + end += Z7_BLAKE2S_BLOCK_SIZE * 3; + } + if (data == end) + return; + // Z7_BLAKE2S_Compress2_V128(s_items, data, end, pos); + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + +#endif // Z7_BLAKE2S_USE_AVX2_WAY4 +#endif // Z7_BLAKE2S_USE_AVX2_WAY_SLOW + + +// --------------------------------------------------------- + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +#define OP256_L(a, i) D_ADD_256 (V(a, 0), \ + LOAD_256((const Byte *)(w) + GET_SIGMA_VAL_256(2*(a)+(i)))); + +#define OP256_0(a) OP256_L(a, 0) +#define OP256_7(a) OP256_L(a, 1) + +#define OP256_1(a) D_ADD_256 (V(a, 0), V(a, 1)); +#define OP256_2(a) D_XOR_256 (V(a, 3), V(a, 0)); +#define OP256_4(a) D_ADD_256 (V(a, 2), V(a, 3)); +#define OP256_5(a) D_XOR_256 (V(a, 1), V(a, 2)); + +#define OP256_3(a) D_ROT_256_16 (V(a, 3)); +#define OP256_6(a) D_ROT_256_12 (V(a, 1)); +#define OP256_8(a) D_ROT_256_8 (V(a, 3)); +#define OP256_9(a) D_ROT_256_7 (V(a, 1)); + + +#if 0 || 1 && defined(MY_CPU_X86) + +#define V8_G(a) \ + OP256_0 (a) \ + OP256_1 (a) \ + OP256_2 (a) \ + OP256_3 (a) \ + OP256_4 (a) \ + OP256_5 (a) \ + OP256_6 (a) \ + OP256_7 (a) \ + OP256_1 (a) \ + OP256_2 (a) \ + OP256_8 (a) \ + OP256_4 (a) \ + OP256_5 (a) \ + OP256_9 (a) \ + +#define V8R { \ + V8_G (0); \ + V8_G (1); \ + V8_G (2); \ + V8_G (3); \ + V8_G (4); \ + V8_G (5); \ + V8_G (6); \ + V8_G (7); \ +} + +#else + +#define OP256_INTER_4(op, a,b,c,d) \ + op (a) \ + op (b) \ + op (c) \ + op (d) \ + +#define V8_G(a,b,c,d) \ + OP256_INTER_4 (OP256_0, a,b,c,d) \ + OP256_INTER_4 (OP256_1, a,b,c,d) \ + OP256_INTER_4 (OP256_2, a,b,c,d) \ + OP256_INTER_4 (OP256_3, a,b,c,d) \ + OP256_INTER_4 (OP256_4, a,b,c,d) \ + OP256_INTER_4 (OP256_5, a,b,c,d) \ + OP256_INTER_4 (OP256_6, a,b,c,d) \ + OP256_INTER_4 (OP256_7, a,b,c,d) \ + OP256_INTER_4 (OP256_1, a,b,c,d) \ + OP256_INTER_4 (OP256_2, a,b,c,d) \ + OP256_INTER_4 (OP256_8, a,b,c,d) \ + OP256_INTER_4 (OP256_4, a,b,c,d) \ + OP256_INTER_4 (OP256_5, a,b,c,d) \ + OP256_INTER_4 (OP256_9, a,b,c,d) \ + +#define V8R { \ + V8_G (0, 1, 2, 3) \ + V8_G (4, 5, 6, 7) \ +} +#endif + +#define V8_ROUND(r) { GET_SIGMA_PTR_256(r); V8R } + + +// for debug: +// #define Z7_BLAKE2S_PERMUTE_WITH_GATHER +#if defined(Z7_BLAKE2S_PERMUTE_WITH_GATHER) +// gather instruction is slow. +#define V8_LOAD_MSG(w, m) \ +{ \ + unsigned i; \ + for (i = 0; i < 16; ++i) { \ + w[i] = _mm256_i32gather_epi32( \ + (const void *)((m) + i * sizeof(UInt32)),\ + _mm256_set_epi32(0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00), \ + sizeof(UInt32)); \ + } \ +} +#else // !Z7_BLAKE2S_PERMUTE_WITH_GATHER + +#define V8_LOAD_MSG_2(w, a0, a1) \ +{ \ + (w)[0] = _mm256_permute2x128_si256(a0, a1, 0x20); \ + (w)[4] = _mm256_permute2x128_si256(a0, a1, 0x31); \ +} - if (size <= rem) +#define V8_LOAD_MSG_4(w, z0, z1, z2, z3) \ +{ \ + __m256i s0, s1, s2, s3; \ + s0 = _mm256_unpacklo_epi64(z0, z1); \ + s1 = _mm256_unpackhi_epi64(z0, z1); \ + s2 = _mm256_unpacklo_epi64(z2, z3); \ + s3 = _mm256_unpackhi_epi64(z2, z3); \ + V8_LOAD_MSG_2((w) + 0, s0, s2) \ + V8_LOAD_MSG_2((w) + 1, s1, s3) \ +} + +#define V8_LOAD_MSG_0(t0, t1, m) \ +{ \ + __m256i m0, m1; \ + m0 = LOADU_256(m); \ + m1 = LOADU_256((m) + 2 * 32); \ + t0 = _mm256_unpacklo_epi32(m0, m1); \ + t1 = _mm256_unpackhi_epi32(m0, m1); \ +} + +#define V8_LOAD_MSG_8(w, m) \ +{ \ + __m256i t0, t1, t2, t3, t4, t5, t6, t7; \ + V8_LOAD_MSG_0(t0, t4, (m) + 0 * 4 * 32) \ + V8_LOAD_MSG_0(t1, t5, (m) + 1 * 4 * 32) \ + V8_LOAD_MSG_0(t2, t6, (m) + 2 * 4 * 32) \ + V8_LOAD_MSG_0(t3, t7, (m) + 3 * 4 * 32) \ + V8_LOAD_MSG_4((w) , t0, t1, t2, t3) \ + V8_LOAD_MSG_4((w) + 2, t4, t5, t6, t7) \ +} + +#define V8_LOAD_MSG(w, m) \ +{ \ + V8_LOAD_MSG_8(w, m) \ + V8_LOAD_MSG_8((w) + 8, (m) + 32) \ +} + +#endif // !Z7_BLAKE2S_PERMUTE_WITH_GATHER + + +#define V8_PERM_PAIR_STORE(u, a0, a2) \ +{ \ + STORE_256_TO_STRUCT((u), _mm256_permute2x128_si256(a0, a2, 0x20)); \ + STORE_256_TO_STRUCT((u) + 8, _mm256_permute2x128_si256(a0, a2, 0x31)); \ +} + +#define V8_UNPACK_STORE_4(u, z0, z1, z2, z3) \ +{ \ + __m256i s0, s1, s2, s3; \ + s0 = _mm256_unpacklo_epi64(z0, z1); \ + s1 = _mm256_unpackhi_epi64(z0, z1); \ + s2 = _mm256_unpacklo_epi64(z2, z3); \ + s3 = _mm256_unpackhi_epi64(z2, z3); \ + V8_PERM_PAIR_STORE(u + 0, s0, s2) \ + V8_PERM_PAIR_STORE(u + 2, s1, s3) \ +} + +#define V8_UNPACK_STORE_0(src32, d0, d1) \ +{ \ + const __m256i v0 = LOAD_256_FROM_STRUCT ((src32) ); \ + const __m256i v1 = LOAD_256_FROM_STRUCT ((src32) + 8); \ + d0 = _mm256_unpacklo_epi32(v0, v1); \ + d1 = _mm256_unpackhi_epi32(v0, v1); \ +} + +#define V8_UNPACK_STATE(dest32, src32) \ +{ \ + __m256i t0, t1, t2, t3, t4, t5, t6, t7; \ + V8_UNPACK_STORE_0 ((src32) + 16 * 0, t0, t4) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 1, t1, t5) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 2, t2, t6) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 3, t3, t7) \ + V8_UNPACK_STORE_4 ((__m256i *)(void *)(dest32) , t0, t1, t2, t3) \ + V8_UNPACK_STORE_4 ((__m256i *)(void *)(dest32) + 4, t4, t5, t6, t7) \ +} + + + +#define V8_LOAD_STATE_256_FROM_STRUCT(i) \ + v[i] = LOAD_256_FROM_STRUCT(s_items + (i) * 8); + +#if 0 || 0 && defined(MY_CPU_X86) +#define Z7_BLAKE2S_AVX2_FAST_USE_STRUCT +#endif + +#ifdef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT +// this branch doesn't use (iv) array +// so register pressure can be lower. +// it can be faster sometimes +#define V8_LOAD_STATE_256(i) V8_LOAD_STATE_256_FROM_STRUCT(i) +#define V8_UPDATE_STATE_256(i) \ +{ \ + STORE_256_TO_STRUCT(s_items + (i) * 8, XOR_256( \ + XOR_256(v[i], v[(i) + 8]), \ + LOAD_256_FROM_STRUCT(s_items + (i) * 8))); \ +} +#else +// it uses more variables (iv) registers +// it's better for gcc +// maybe that branch is better, if register pressure will be lower (avx512) +#define V8_LOAD_STATE_256(i) { iv[i] = v[i]; } +#define V8_UPDATE_STATE_256(i) { v[i] = XOR_256(XOR_256(v[i], v[i + 8]), iv[i]); } +#define V8_STORE_STATE_256(i) { STORE_256_TO_STRUCT(s_items + (i) * 8, v[i]); } +#endif + + +#if 0 + // use loading constants from memory + #define KK8(n) KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n) +MY_ALIGN(64) +static const UInt32 k_Blake2s_IV_WAY8[]= +{ + KK8(0), KK8(1), KK8(2), KK8(3), KK8(4), KK8(5), KK8(6), KK8(7) +}; + #define GET_256_IV_WAY8(i) LOAD_256(k_Blake2s_IV_WAY8 + 8 * (i)) +#else + // use constant generation: + #define GET_256_IV_WAY8(i) _mm256_set1_epi32((Int32)KIV(i)) +#endif + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Fast(UInt32 *s_items, const Byte *data, const Byte *end) +{ +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + __m256i v[16]; +#endif + + // PrintStates2(s_items, 8, 16); + +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + REP8_MACRO (V8_LOAD_STATE_256_FROM_STRUCT) +#endif + + do + { + __m256i w[16]; +#ifdef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + __m256i v[16]; +#else + __m256i iv[8]; +#endif + V8_LOAD_MSG(w, data) { - memcpy(p->buf + pos, data, size); - p->bufPos += (UInt32)size; - return; + // we use load/store ctr inside loop to reduce register pressure: +#if 1 || 1 && defined(MY_CPU_X86) + const __m256i ctr = _mm256_add_epi64( + LOAD_256_FROM_STRUCT(s_items + 64), + _mm256_set_epi32( + 0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE, + 0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE)); + STORE_256_TO_STRUCT(s_items + 64, ctr); +#else + const UInt64 ctr64 = *(const UInt64 *)(const void *)(s_items + 64) + + Z7_BLAKE2S_BLOCK_SIZE; + const __m256i ctr = _mm256_set_epi64x(0, (Int64)ctr64, 0, (Int64)ctr64); + *(UInt64 *)(void *)(s_items + 64) = ctr64; +#endif + v[12] = XOR_256 (GET_256_IV_WAY8(4), _mm256_shuffle_epi32(ctr, _MM_SHUFFLE(0, 0, 0, 0))); + v[13] = XOR_256 (GET_256_IV_WAY8(5), _mm256_shuffle_epi32(ctr, _MM_SHUFFLE(1, 1, 1, 1))); } + v[ 8] = GET_256_IV_WAY8(0); + v[ 9] = GET_256_IV_WAY8(1); + v[10] = GET_256_IV_WAY8(2); + v[11] = GET_256_IV_WAY8(3); + v[14] = GET_256_IV_WAY8(6); + v[15] = GET_256_IV_WAY8(7); + + REP8_MACRO (V8_LOAD_STATE_256) + ROUNDS_LOOP (V8_ROUND) + REP8_MACRO (V8_UPDATE_STATE_256) + data += SUPER_BLOCK_SIZE; + } + while (data != end); + +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + REP8_MACRO (V8_STORE_STATE_256) +#endif +} - memcpy(p->buf + pos, data, rem); - Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE); - Blake2s_Compress(p); - p->bufPos = 0; - data += rem; - size -= rem; + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Final_AVX2_Fast(UInt32 *states) +{ + const __m128i ctr = LOAD_128_FROM_STRUCT(states + 64); + // PrintStates2(states, 8, 16); + V8_UNPACK_STATE(states, states) + // PrintStates2(states, 8, 16); + { + unsigned k; + for (k = 0; k < 8; k++) + { + UInt32 *s = states + (size_t)k * 16; + STORE_128_TO_STRUCT (STATE_T(s), ctr); + } } + // PrintStates2(states, 8, 16); + // printf("\nafter V8_UNPACK_STATE \n"); } +#endif // Z7_BLAKE2S_USE_AVX2_FAST +#endif // avx2 +#endif // vector -static void Blake2s_Final(CBlake2s *p, Byte *digest) + +/* +#define Blake2s_Increment_Counter(s, inc) \ + { STATE_T(s)[0] += (inc); STATE_T(s)[1] += (STATE_T(s)[0] < (inc)); } +#define Blake2s_Increment_Counter_Small(s, inc) \ + { STATE_T(s)[0] += (inc); } +*/ + +#define Blake2s_Set_LastBlock(s) \ + { STATE_F(s)[0] = BLAKE2S_FINAL_FLAG; /* STATE_F(s)[1] = p->u.header.lastNode_f1; */ } + + +#if 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL >= 1600 + // good for vs2022 + #define LOOP_8(mac) { unsigned kkk; for (kkk = 0; kkk < 8; kkk++) mac(kkk) } +#else + // good for Z7_BLAKE2S_UNROLL for GCC9 (arm*/x86*) and MSC_VER_1400-x64. + #define LOOP_8(mac) { REP8_MACRO(mac) } +#endif + + +static +Z7_FORCE_INLINE +// Z7_NO_INLINE +void +Z7_FASTCALL +Blake2s_Compress(UInt32 *s, const Byte *input) { - unsigned i; + UInt32 m[16]; + UInt32 v[16]; + { + unsigned i; + for (i = 0; i < 16; i++) + m[i] = GetUi32(input + i * 4); + } - Blake2s_Increment_Counter(S, (UInt32)p->bufPos); - Blake2s_Set_LastBlock(p); - memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos); - Blake2s_Compress(p); +#define INIT_v_FROM_s(i) v[i] = s[i]; + + LOOP_8(INIT_v_FROM_s) + + // Blake2s_Increment_Counter(s, Z7_BLAKE2S_BLOCK_SIZE) + { + const UInt32 t0 = STATE_T(s)[0] + Z7_BLAKE2S_BLOCK_SIZE; + const UInt32 t1 = STATE_T(s)[1] + (t0 < Z7_BLAKE2S_BLOCK_SIZE); + STATE_T(s)[0] = t0; + STATE_T(s)[1] = t1; + v[12] = t0 ^ KIV(4); + v[13] = t1 ^ KIV(5); + } + // v[12] = STATE_T(s)[0] ^ KIV(4); + // v[13] = STATE_T(s)[1] ^ KIV(5); + v[14] = STATE_F(s)[0] ^ KIV(6); + v[15] = STATE_F(s)[1] ^ KIV(7); + + v[ 8] = KIV(0); + v[ 9] = KIV(1); + v[10] = KIV(2); + v[11] = KIV(3); + // PrintStates2((const UInt32 *)v, 1, 16); + + #define ADD_SIGMA(a, index) V(a, 0) += *(const UInt32 *)GET_SIGMA_PTR(m, sigma[index]); + #define ADD32M(dest, src, a) V(a, dest) += V(a, src); + #define XOR32M(dest, src, a) V(a, dest) ^= V(a, src); + #define RTR32M(dest, shift, a) V(a, dest) = rotrFixed(V(a, dest), shift); + +// big interleaving can provides big performance gain, if scheduler queues are small. +#if 0 || 1 && defined(MY_CPU_X86) + // interleave-1: for small register number (x86-32bit) + #define G2(index, a, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD32M (0, 1, a) \ + XOR32M (3, 0, a) \ + RTR32M (3, x, a) \ + ADD32M (2, 3, a) \ + XOR32M (1, 2, a) \ + RTR32M (1, y, a) \ + + #define G(a) \ + G2(a * 2 , a, 16, 12) \ + G2(a * 2 + 1, a, 8, 7) \ + + #define R2 \ + G(0) \ + G(1) \ + G(2) \ + G(3) \ + G(4) \ + G(5) \ + G(6) \ + G(7) \ + +#elif 0 || 1 && defined(MY_CPU_X86_OR_AMD64) + // interleave-2: is good if the number of registers is not big (x86-64). + + #define REP2(mac, dest, src, a, b) \ + mac(dest, src, a) \ + mac(dest, src, b) + + #define G2(index, a, b, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD_SIGMA (b, (index) + 2 * 1) \ + REP2 (ADD32M, 0, 1, a, b) \ + REP2 (XOR32M, 3, 0, a, b) \ + REP2 (RTR32M, 3, x, a, b) \ + REP2 (ADD32M, 2, 3, a, b) \ + REP2 (XOR32M, 1, 2, a, b) \ + REP2 (RTR32M, 1, y, a, b) \ + + #define G(a, b) \ + G2(a * 2 , a, b, 16, 12) \ + G2(a * 2 + 1, a, b, 8, 7) \ + + #define R2 \ + G(0, 1) \ + G(2, 3) \ + G(4, 5) \ + G(6, 7) \ + +#else + // interleave-4: + // it has big register pressure for x86/x64. + // and MSVC compilers for x86/x64 are slow for this branch. + // but if we have big number of registers, this branch can be faster. + + #define REP4(mac, dest, src, a, b, c, d) \ + mac(dest, src, a) \ + mac(dest, src, b) \ + mac(dest, src, c) \ + mac(dest, src, d) + + #define G2(index, a, b, c, d, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD_SIGMA (b, (index) + 2 * 1) \ + ADD_SIGMA (c, (index) + 2 * 2) \ + ADD_SIGMA (d, (index) + 2 * 3) \ + REP4 (ADD32M, 0, 1, a, b, c, d) \ + REP4 (XOR32M, 3, 0, a, b, c, d) \ + REP4 (RTR32M, 3, x, a, b, c, d) \ + REP4 (ADD32M, 2, 3, a, b, c, d) \ + REP4 (XOR32M, 1, 2, a, b, c, d) \ + REP4 (RTR32M, 1, y, a, b, c, d) \ + + #define G(a, b, c, d) \ + G2(a * 2 , a, b, c, d, 16, 12) \ + G2(a * 2 + 1, a, b, c, d, 8, 7) \ + + #define R2 \ + G(0, 1, 2, 3) \ + G(4, 5, 6, 7) \ + +#endif + + #define R(r) { const Byte *sigma = k_Blake2s_Sigma_4[r]; R2 } + + // Z7_BLAKE2S_UNROLL gives 5-6 KB larger code, but faster: + // 20-40% faster for (x86/x64) VC2010+/GCC/CLANG. + // 30-60% faster for (arm64-arm32) GCC. + // 5-11% faster for (arm64) CLANG-MAC. + // so Z7_BLAKE2S_UNROLL is good optimization, if there is no vector branch. + // But if there is vectors branch (for x86*), this scalar code will be unused mostly. + // So we want smaller code (without unrolling) in that case (x86*). +#if 0 || 1 && !defined(Z7_BLAKE2S_USE_VECTORS) + #define Z7_BLAKE2S_UNROLL +#endif + +#ifdef Z7_BLAKE2S_UNROLL + ROUNDS_LOOP_UNROLLED (R) +#else + ROUNDS_LOOP (R) +#endif + + #undef G + #undef G2 + #undef R + #undef R2 - for (i = 0; i < 8; i++) - SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]); + // printf("\n v after: \n"); + // PrintStates2((const UInt32 *)v, 1, 16); +#define XOR_s_PAIR_v(i) s[i] ^= v[i] ^ v[i + 8]; + + LOOP_8(XOR_s_PAIR_v) + // printf("\n s after:\n"); + // PrintStates2((const UInt32 *)s, 1, 16); } -/* ---------- BLAKE2s ---------- */ +static +Z7_NO_INLINE +void +Z7_FASTCALL +Blake2sp_Compress2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + // PrintStates2(s_items, 8, 16); + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Blake2s_Compress(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + + +#ifdef Z7_BLAKE2S_USE_VECTORS -/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ +static Z7_BLAKE2SP_FUNC_COMPRESS g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast = Blake2sp_Compress2; +static Z7_BLAKE2SP_FUNC_COMPRESS g_Z7_BLAKE2SP_FUNC_COMPRESS_Single = Blake2sp_Compress2; +static Z7_BLAKE2SP_FUNC_INIT g_Z7_BLAKE2SP_FUNC_INIT_Init; +static Z7_BLAKE2SP_FUNC_INIT g_Z7_BLAKE2SP_FUNC_INIT_Final; +static unsigned g_z7_Blake2sp_SupportedFlags; + + #define Z7_BLAKE2SP_Compress_Fast(p) (p)->u.header.func_Compress_Fast + #define Z7_BLAKE2SP_Compress_Single(p) (p)->u.header.func_Compress_Single +#else + #define Z7_BLAKE2SP_Compress_Fast(p) Blake2sp_Compress2 + #define Z7_BLAKE2SP_Compress_Single(p) Blake2sp_Compress2 +#endif // Z7_BLAKE2S_USE_VECTORS + + +#if 1 && defined(MY_CPU_LE) + #define GET_DIGEST(_s, _digest) \ + { memcpy(_digest, _s, Z7_BLAKE2S_DIGEST_SIZE); } +#else + #define GET_DIGEST(_s, _digest) \ + { unsigned _i; for (_i = 0; _i < 8; _i++) \ + { SetUi32((_digest) + 4 * _i, (_s)[_i]) } \ + } +#endif + + +/* ---------- BLAKE2s ---------- */ /* +// we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() typedef struct { Byte digest_length; Byte key_length; - Byte fanout; - Byte depth; + Byte fanout; // = 1 : in sequential mode + Byte depth; // = 1 : in sequential mode UInt32 leaf_length; - Byte node_offset[6]; - Byte node_depth; - Byte inner_length; + Byte node_offset[6]; // 0 for the first, leftmost, leaf, or in sequential mode + Byte node_depth; // 0 for the leaves, or in sequential mode + Byte inner_length; // [0, 32], 0 in sequential mode Byte salt[BLAKE2S_SALTBYTES]; Byte personal[BLAKE2S_PERSONALBYTES]; } CBlake2sParam; */ +#define k_Blake2sp_IV_0 \ + (KIV(0) ^ (Z7_BLAKE2S_DIGEST_SIZE | ((UInt32)Z7_BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24))) +#define k_Blake2sp_IV_3_FROM_NODE_DEPTH(node_depth) \ + (KIV(3) ^ ((UInt32)(node_depth) << 16) ^ ((UInt32)Z7_BLAKE2S_DIGEST_SIZE << 24)) -static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth) +Z7_FORCE_INLINE +static void Blake2sp_Init_Spec(UInt32 *s, unsigned node_offset, unsigned node_depth) { - Blake2s_Init0(p); - - p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24)); - p->h[2] ^= ((UInt32)node_offset); - p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24); - /* - P->digest_length = BLAKE2S_DIGEST_SIZE; - P->key_length = 0; - P->fanout = BLAKE2SP_PARALLEL_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48(P->node_offset, node_offset); - P->node_depth = node_depth; - P->inner_length = BLAKE2S_DIGEST_SIZE; - */ + s[0] = k_Blake2sp_IV_0; + s[1] = KIV(1); + s[2] = KIV(2) ^ (UInt32)node_offset; + s[3] = k_Blake2sp_IV_3_FROM_NODE_DEPTH(node_depth); + s[4] = KIV(4); + s[5] = KIV(5); + s[6] = KIV(6); + s[7] = KIV(7); + + STATE_T(s)[0] = 0; + STATE_T(s)[1] = 0; + STATE_F(s)[0] = 0; + STATE_F(s)[1] = 0; } -void Blake2sp_Init(CBlake2sp *p) +#ifdef Z7_BLAKE2S_USE_V128_FAST + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_InitState_V128_Fast(UInt32 *states) { - unsigned i; - - p->bufPos = 0; +#define STORE_128_PAIR_INIT_STATES_2(i, t0, t1) \ + { STORE_128_TO_STRUCT(states + 0 + 4 * (i), (t0)); \ + STORE_128_TO_STRUCT(states + 32 + 4 * (i), (t1)); \ + } +#define STORE_128_PAIR_INIT_STATES_1(i, mac) \ + { const __m128i t = mac; \ + STORE_128_PAIR_INIT_STATES_2(i, t, t) \ + } +#define STORE_128_PAIR_INIT_STATES_IV(i) \ + STORE_128_PAIR_INIT_STATES_1(i, GET_128_IV_WAY4(i)) + + STORE_128_PAIR_INIT_STATES_1 (0, _mm_set1_epi32((Int32)k_Blake2sp_IV_0)) + STORE_128_PAIR_INIT_STATES_IV (1) + { + const __m128i t = GET_128_IV_WAY4(2); + STORE_128_PAIR_INIT_STATES_2 (2, + XOR_128(t, _mm_set_epi32(3, 2, 1, 0)), + XOR_128(t, _mm_set_epi32(7, 6, 5, 4))) + } + STORE_128_PAIR_INIT_STATES_1 (3, _mm_set1_epi32((Int32)k_Blake2sp_IV_3_FROM_NODE_DEPTH(0))) + STORE_128_PAIR_INIT_STATES_IV (4) + STORE_128_PAIR_INIT_STATES_IV (5) + STORE_128_PAIR_INIT_STATES_IV (6) + STORE_128_PAIR_INIT_STATES_IV (7) + STORE_128_PAIR_INIT_STATES_1 (16, _mm_set_epi32(0, 0, 0, 0)) + // printf("\n== exit Blake2sp_InitState_V128_Fast ctr=%d\n", states[64]); +} - for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) - Blake2sp_Init_Spec(&p->S[i], i, 0); +#endif // Z7_BLAKE2S_USE_V128_FAST - p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG; + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_InitState_AVX2_Fast(UInt32 *states) +{ +#define STORE_256_INIT_STATES(i, t) \ + STORE_256_TO_STRUCT(states + 8 * (i), t); +#define STORE_256_INIT_STATES_IV(i) \ + STORE_256_INIT_STATES(i, GET_256_IV_WAY8(i)) + + STORE_256_INIT_STATES (0, _mm256_set1_epi32((Int32)k_Blake2sp_IV_0)) + STORE_256_INIT_STATES_IV (1) + STORE_256_INIT_STATES (2, XOR_256( GET_256_IV_WAY8(2), + _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0))) + STORE_256_INIT_STATES (3, _mm256_set1_epi32((Int32)k_Blake2sp_IV_3_FROM_NODE_DEPTH(0))) + STORE_256_INIT_STATES_IV (4) + STORE_256_INIT_STATES_IV (5) + STORE_256_INIT_STATES_IV (6) + STORE_256_INIT_STATES_IV (7) + STORE_256_INIT_STATES (8, _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0)) + // printf("\n== exit Blake2sp_InitState_AVX2_Fast\n"); +} + +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + + +Z7_NO_INLINE +void Blake2sp_InitState(CBlake2sp *p) +{ + size_t i; + // memset(p->states, 0, sizeof(p->states)); // for debug + p->u.header.cycPos = 0; +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + if (p->u.header.func_Init) + { + p->u.header.func_Init(p->states); + return; + } +#endif + for (i = 0; i < Z7_BLAKE2SP_PARALLEL_DEGREE; i++) + Blake2sp_Init_Spec(p->states + i * NSW, (unsigned)i, 0); +} + +void Blake2sp_Init(CBlake2sp *p) +{ +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + p->u.header.func_Compress_Fast = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast; +#else + NULL; +#endif + + p->u.header.func_Compress_Single = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_COMPRESS_Single; +#else + NULL; +#endif + + p->u.header.func_Init = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_INIT_Init; +#else + NULL; +#endif + + p->u.header.func_Final = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_INIT_Final; +#else + NULL; +#endif +#endif + + Blake2sp_InitState(p); } void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size) { - unsigned pos = p->bufPos; - while (size != 0) + size_t pos; + // printf("\nsize = 0x%6x, cycPos = %5u data = %p\n", (unsigned)size, (unsigned)p->u.header.cycPos, data); + if (size == 0) + return; + pos = p->u.header.cycPos; + // pos < SUPER_BLOCK_SIZE * 2 : is expected + // pos == SUPER_BLOCK_SIZE * 2 : is not expected, but is supported also { - unsigned index = pos / BLAKE2S_BLOCK_SIZE; - unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1)); - if (rem > size) - rem = (unsigned)size; - Blake2s_Update(&p->S[index], data, rem); - size -= rem; - data += rem; - pos += rem; - pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1); + const size_t pos2 = pos & SUPER_BLOCK_MASK; + if (pos2) + { + const size_t rem = SUPER_BLOCK_SIZE - pos2; + if (rem > size) + { + p->u.header.cycPos = (unsigned)(pos + size); + // cycPos < SUPER_BLOCK_SIZE * 2 + memcpy((Byte *)(void *)p->buf32 + pos, data, size); + /* to simpilify the code here we don't try to process first superblock, + if (cycPos > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) */ + return; + } + // (rem <= size) + memcpy((Byte *)(void *)p->buf32 + pos, data, rem); + pos += rem; + data += rem; + size -= rem; + } } - p->bufPos = pos; + + // pos <= SUPER_BLOCK_SIZE * 2 + // pos % SUPER_BLOCK_SIZE == 0 + if (pos) + { + /* pos == SUPER_BLOCK_SIZE || + pos == SUPER_BLOCK_SIZE * 2 */ + size_t end = pos; + if (size > SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE + || (end -= SUPER_BLOCK_SIZE)) + { + Z7_BLAKE2SP_Compress_Fast(p)(p->states, + (const Byte *)(const void *)p->buf32, + (const Byte *)(const void *)p->buf32 + end); + if (pos -= end) + memcpy(p->buf32, (const Byte *)(const void *)p->buf32 + + SUPER_BLOCK_SIZE, SUPER_BLOCK_SIZE); + } + } + + // pos == 0 || (pos == SUPER_BLOCK_SIZE && size <= SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE) + if (size > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) + { + // pos == 0 + const Byte *end; + const size_t size2 = (size - (SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE + 1)) + & ~(size_t)SUPER_BLOCK_MASK; + size -= size2; + // size < SUPER_BLOCK_SIZE * 2 + end = data + size2; + Z7_BLAKE2SP_Compress_Fast(p)(p->states, data, end); + data = end; + } + + if (size != 0) + { + memcpy((Byte *)(void *)p->buf32 + pos, data, size); + pos += size; + } + p->u.header.cycPos = (unsigned)pos; + // cycPos < SUPER_BLOCK_SIZE * 2 } void Blake2sp_Final(CBlake2sp *p, Byte *digest) { - CBlake2s R; - unsigned i; + // UInt32 * const R_states = p->states; + // printf("\nBlake2sp_Final \n"); +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + if (p->u.header.func_Final) + p->u.header.func_Final(p->states); +#endif + // printf("\n=====\nBlake2sp_Final \n"); + // PrintStates(p->states, 32); + + // (p->u.header.cycPos == SUPER_BLOCK_SIZE) can be processed in any branch: + if (p->u.header.cycPos <= SUPER_BLOCK_SIZE) + { + unsigned pos; + memset((Byte *)(void *)p->buf32 + p->u.header.cycPos, + 0, SUPER_BLOCK_SIZE - p->u.header.cycPos); + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + for (pos = 0; pos < SUPER_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos); + Blake2s_Set_LastBlock(s) + if (pos + Z7_BLAKE2S_BLOCK_SIZE > p->u.header.cycPos) + { + UInt32 delta = Z7_BLAKE2S_BLOCK_SIZE; + if (pos < p->u.header.cycPos) + delta -= p->u.header.cycPos & (Z7_BLAKE2S_BLOCK_SIZE - 1); + // 0 < delta <= Z7_BLAKE2S_BLOCK_SIZE + { + const UInt32 v = STATE_T(s)[0]; + STATE_T(s)[1] -= v < delta; // (v < delta) is same condition here as (v == 0) + STATE_T(s)[0] = v - delta; + } + } + } + // PrintStates(p->states, 16); + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE); + // PrintStates(p->states, 16); + } + else + { + // (p->u.header.cycPos > SUPER_BLOCK_SIZE) + unsigned pos; + for (pos = 0; pos < SUPER_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos); + if (pos + SUPER_BLOCK_SIZE >= p->u.header.cycPos) + Blake2s_Set_LastBlock(s) + } + if (p->u.header.cycPos <= SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE); + + // if (p->u.header.cycPos > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE; + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + + // if (p->u.header.cycPos != SUPER_BLOCK_SIZE) + { + pos = SUPER_BLOCK_SIZE; + for (;;) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos & SUPER_BLOCK_MASK); + Blake2s_Set_LastBlock(s) + pos += Z7_BLAKE2S_BLOCK_SIZE; + if (pos >= p->u.header.cycPos) + { + if (pos != p->u.header.cycPos) + { + const UInt32 delta = pos - p->u.header.cycPos; + const UInt32 v = STATE_T(s)[0]; + STATE_T(s)[1] -= v < delta; + STATE_T(s)[0] = v - delta; + memset((Byte *)(void *)p->buf32 + p->u.header.cycPos, 0, delta); + } + break; + } + } + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE, + (Byte *)(void *)p->buf32 + pos); + } + } - Blake2sp_Init_Spec(&R, 0, 1); - R.lastNode_f1 = BLAKE2S_FINAL_FLAG; + { + size_t pos; + for (pos = 0; pos < SUPER_BLOCK_SIZE / 2; pos += Z7_BLAKE2S_BLOCK_SIZE / 2) + { + const UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, (pos * 2)); + Byte *dest = (Byte *)(void *)p->buf32 + pos; + GET_DIGEST(s, dest) + } + } + Blake2sp_Init_Spec(p->states, 0, 1); + { + size_t pos; + for (pos = 0; pos < (Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2S_DIGEST_SIZE) + - Z7_BLAKE2S_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (const Byte *)(const void *)p->buf32 + pos, + (const Byte *)(const void *)p->buf32 + pos + Z7_BLAKE2S_BLOCK_SIZE); + } + } + // Blake2s_Final(p->states, 0, digest, p, (Byte *)(void *)p->buf32 + i); + Blake2s_Set_LastBlock(p->states) + STATE_F(p->states)[1] = BLAKE2S_FINAL_FLAG; + { + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (const Byte *)(const void *)p->buf32 + Z7_BLAKE2SP_PARALLEL_DEGREE / 2 * Z7_BLAKE2S_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE, + (const Byte *)(const void *)p->buf32 + Z7_BLAKE2SP_PARALLEL_DEGREE / 2 * Z7_BLAKE2S_BLOCK_SIZE); + } + GET_DIGEST(p->states, digest) + // printf("\n Blake2sp_Final 555 numDataInBufs = %5u\n", (unsigned)p->u.header.numDataInBufs); +} + + +BoolInt Blake2sp_SetFunction(CBlake2sp *p, unsigned algo) +{ + // printf("\n========== setfunction = %d ======== \n", algo); +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + Z7_BLAKE2SP_FUNC_COMPRESS func = NULL; + Z7_BLAKE2SP_FUNC_COMPRESS func_Single = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Final = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Init = NULL; +#else + UNUSED_VAR(p) +#endif + +#ifdef Z7_BLAKE2S_USE_VECTORS + + func = func_Single = Blake2sp_Compress2; - for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) + if (algo != Z7_BLAKE2SP_ALGO_SCALAR) { - Byte hash[BLAKE2S_DIGEST_SIZE]; - Blake2s_Final(&p->S[i], hash); - Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE); + // printf("\n========== setfunction NON-SCALER ======== \n"); + if (algo == Z7_BLAKE2SP_ALGO_DEFAULT) + { + func = g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast; + func_Single = g_Z7_BLAKE2SP_FUNC_COMPRESS_Single; + func_Init = g_Z7_BLAKE2SP_FUNC_INIT_Init; + func_Final = g_Z7_BLAKE2SP_FUNC_INIT_Final; + } + else + { + if ((g_z7_Blake2sp_SupportedFlags & (1u << algo)) == 0) + return False; + +#ifdef Z7_BLAKE2S_USE_AVX2 + + func_Single = +#if defined(Z7_BLAKE2S_USE_AVX2_WAY2) + Blake2sp_Compress2_AVX2_Way2; +#else + Z7_BLAKE2S_Compress2_V128; +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + if (algo == Z7_BLAKE2SP_ALGO_V256_FAST) + { + func = Blake2sp_Compress2_AVX2_Fast; + func_Final = Blake2sp_Final_AVX2_Fast; + func_Init = Blake2sp_InitState_AVX2_Fast; + } + else +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + if (algo == Z7_BLAKE2SP_ALGO_V256_WAY2) + func = Blake2sp_Compress2_AVX2_Way2; + else +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + if (algo == Z7_BLAKE2SP_ALGO_V256_WAY4) + { + func_Single = func = Blake2sp_Compress2_AVX2_Way4; + } + else +#endif +#endif // avx2 + { + if (algo == Z7_BLAKE2SP_ALGO_V128_FAST) + { + func = Blake2sp_Compress2_V128_Fast; + func_Final = Blake2sp_Final_V128_Fast; + func_Init = Blake2sp_InitState_V128_Fast; + func_Single = Z7_BLAKE2S_Compress2_V128; + } + else +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + if (algo == Z7_BLAKE2SP_ALGO_V128_WAY2) + func = func_Single = Blake2sp_Compress2_V128_Way2; + else +#endif + { + if (algo != Z7_BLAKE2SP_ALGO_V128_WAY1) + return False; + func = func_Single = Blake2sp_Compress2_V128_Way1; + } + } + } } +#else // !VECTORS + if (algo > 1) // Z7_BLAKE2SP_ALGO_SCALAR + return False; +#endif // !VECTORS + +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + p->u.header.func_Compress_Fast = func; + p->u.header.func_Compress_Single = func_Single; + p->u.header.func_Final = func_Final; + p->u.header.func_Init = func_Init; +#endif + // printf("\n p->u.header.func_Compress = %p", p->u.header.func_Compress); + return True; +} + + +void z7_Black2sp_Prepare(void) +{ +#ifdef Z7_BLAKE2S_USE_VECTORS + unsigned flags = 0; // (1u << Z7_BLAKE2SP_ALGO_V128_SCALAR); + + Z7_BLAKE2SP_FUNC_COMPRESS func_Fast = Blake2sp_Compress2; + Z7_BLAKE2SP_FUNC_COMPRESS func_Single = Blake2sp_Compress2; + Z7_BLAKE2SP_FUNC_INIT func_Init = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Final = NULL; + +#if defined(MY_CPU_X86_OR_AMD64) + #if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + // optional check + #if 0 || !(defined(__AVX512F__) && defined(__AVX512VL__)) + if (CPU_IsSupported_AVX512F_AVX512VL()) + #endif + #elif defined(Z7_BLAKE2S_USE_SSE41) + if (CPU_IsSupported_SSE41()) + #elif defined(Z7_BLAKE2S_USE_SSSE3) + if (CPU_IsSupported_SSSE3()) + #elif !defined(MY_CPU_AMD64) + if (CPU_IsSupported_SSE2()) + #endif +#endif + { + #if defined(Z7_BLAKE2S_USE_SSE41) + // printf("\n========== Blake2s SSE41 128-bit\n"); + #elif defined(Z7_BLAKE2S_USE_SSSE3) + // printf("\n========== Blake2s SSSE3 128-bit\n"); + #else + // printf("\n========== Blake2s SSE2 128-bit\n"); + #endif + // func_Fast = f_vector = Blake2sp_Compress2_V128_Way2; + // printf("\n========== Blake2sp_Compress2_V128_Way2\n"); + func_Fast = + func_Single = Z7_BLAKE2S_Compress2_V128; + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_WAY1); +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_WAY2); +#endif +#ifdef Z7_BLAKE2S_USE_V128_FAST + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_FAST); + func_Fast = Blake2sp_Compress2_V128_Fast; + func_Init = Blake2sp_InitState_V128_Fast; + func_Final = Blake2sp_Final_V128_Fast; +#endif - Blake2s_Final(&R, digest); +#ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(MY_CPU_X86_OR_AMD64) + + #if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #if 0 + if (CPU_IsSupported_AVX512F_AVX512VL()) + #endif + #else + if (CPU_IsSupported_AVX2()) + #endif +#endif + { + // #pragma message ("=== Blake2s AVX2") + // printf("\n========== Blake2s AVX2\n"); + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + func_Single = Blake2sp_Compress2_AVX2_Way2; + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_WAY2); +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_WAY4); +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_FAST); + func_Fast = Blake2sp_Compress2_AVX2_Fast; + func_Init = Blake2sp_InitState_AVX2_Fast; + func_Final = Blake2sp_Final_AVX2_Fast; +#elif defined(Z7_BLAKE2S_USE_AVX2_WAY4) + func_Fast = Blake2sp_Compress2_AVX2_Way4; +#elif defined(Z7_BLAKE2S_USE_AVX2_WAY2) + func_Fast = Blake2sp_Compress2_AVX2_Way2; +#endif + } // avx2 +#endif // avx2 + } // sse* + g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast = func_Fast; + g_Z7_BLAKE2SP_FUNC_COMPRESS_Single = func_Single; + g_Z7_BLAKE2SP_FUNC_INIT_Init = func_Init; + g_Z7_BLAKE2SP_FUNC_INIT_Final = func_Final; + g_z7_Blake2sp_SupportedFlags = flags; + // printf("\nflags=%x\n", flags); +#endif // vectors +} + +/* +#ifdef Z7_BLAKE2S_USE_VECTORS +void align_test2(CBlake2sp *sp); +void align_test2(CBlake2sp *sp) +{ + __m128i a = LOAD_128(sp->states); + D_XOR_128(a, LOAD_128(sp->states + 4)); + STORE_128(sp->states, a); } +void align_test2(void); +void align_test2(void) +{ + CBlake2sp sp; + Blake2sp_Init(&sp); + Blake2sp_Update(&sp, NULL, 0); +} +#endif +*/ diff -Nru 7zip-22.01+dfsg/C/Bra.c 7zip-22.01+really25.01+dfsg/C/Bra.c --- 7zip-22.01+dfsg/C/Bra.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bra.c 2024-01-20 18:00:00.000000000 +0000 @@ -1,230 +1,709 @@ -/* Bra.c -- Converters for RISC code -2021-02-09 : Igor Pavlov : Public domain */ +/* Bra.c -- Branch converters for RISC code +2024-01-20 : Igor Pavlov : Public domain */ #include "Precomp.h" -#include "CpuArch.h" #include "Bra.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV(name) z7_ ## name + +#define Z7_BRANCH_FUNC_MAIN(name) \ +static \ +Z7_FORCE_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *Z7_BRANCH_CONV(name)(Byte *p, SizeT size, UInt32 pc, int encoding) + +#define Z7_BRANCH_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc) \ + { return Z7_BRANCH_CONV(name)(data, size, pc, encoding); } \ + +#ifdef Z7_EXTRACT_ONLY +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) +#else +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_ENC_2, 1) +#endif + +#if defined(__clang__) +#define BR_EXTERNAL_FOR +#define BR_NEXT_ITERATION continue; +#else +#define BR_EXTERNAL_FOR for (;;) +#define BR_NEXT_ITERATION break; +#endif + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + // GCC is not good for __builtin_expect() here + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // #define Z7_unlikely [[unlikely]] + // #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_likely [[likely]] +#else + // #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM64) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)3; - ip += 4; - p = data; - lim = data + size; + const UInt32 flag = (UInt32)1 << (24 - 4); + const UInt32 mask = ((UInt32)1 << 24) - (flag << 1); + size &= ~(SizeT)3; + // if (size == 0) return p; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + BR_EXTERNAL_FOR + { + // Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (;;) + { + UInt32 v; + if Z7_UNLIKELY(p == lim) + return p; + v = GetUi32a(p); + p += 4; + if Z7_UNLIKELY(((v - 0x94000000) & 0xfc000000) == 0) + { + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x03ffffff; + v |= 0x94000000; + SetUi32a(p - 4, v) + BR_NEXT_ITERATION + } + // v = rotlFixed(v, 8); v += (flag << 8) - 0x90; if Z7_UNLIKELY((v & ((mask << 8) + 0x9f)) == 0) + v -= 0x90000000; if Z7_UNLIKELY((v & 0x9f000000) == 0) + { + UInt32 z, c; + // v = rotrFixed(v, 8); + v += flag; if Z7_UNLIKELY(v & mask) continue; + z = (v & 0xffffffe0) | (v >> 26); + c = (BR_PC_GET >> (12 - 3)) & ~(UInt32)7; + BR_CONVERT_VAL(z, c) + v &= 0x1f; + v |= 0x90000000; + v |= z << 26; + v |= 0x00ffffe0 & ((z & (((flag << 1) - 1))) - flag); + SetUi32a(p - 4, v) + } + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM64) - if (encoding) +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to next instruction */ + pc += 8 - 4; + for (;;) { for (;;) { - if (p >= lim) - return (SizeT)(p - data); - p += 4; - if (p[-1] == 0xEB) - break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; } { - UInt32 v = GetUi32(p - 4); - v <<= 2; - v += ip + (UInt32)(p - data); - v >>= 2; - v &= 0x00FFFFFF; - v |= 0xEB000000; - SetUi32(p - 4, v); + UInt32 v = GetUi32a(p - 4); + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x00ffffff; + v |= 0xeb000000; + SetUi32a(p - 4, v) } } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM) + +Z7_BRANCH_FUNC_MAIN(BranchConv_PPC) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + for (;;) { + UInt32 v; for (;;) { - if (p >= lim) - return (SizeT)(p - data); + if Z7_UNLIKELY(p == lim) + return p; + // v = GetBe32a(p); + v = *(UInt32 *)(void *)p; p += 4; - if (p[-1] == 0xEB) - break; + // if ((v & 0xfc000003) == 0x48000001) break; + // if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) break; + if Z7_UNLIKELY( + ((v - Z7_CONV_BE_TO_NATIVE_CONST32(0x48000001)) + & Z7_CONV_BE_TO_NATIVE_CONST32(0xfc000003)) == 0) break; } { - UInt32 v = GetUi32(p - 4); - v <<= 2; - v -= ip + (UInt32)(p - data); - v >>= 2; - v &= 0x00FFFFFF; - v |= 0xEB000000; - SetUi32(p - 4, v); + v = Z7_CONV_NATIVE_TO_BE_32(v); + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= 0x03ffffff; + v |= 0x48000000; + SetBe32a(p - 4, v) } } } +Z7_BRANCH_FUNCS_IMP(BranchConv_PPC) + +#ifdef Z7_CPU_FAST_ROTATE_SUPPORTED +#define BR_SPARC_USE_ROTATE +#endif -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +Z7_BRANCH_FUNC_MAIN(BranchConv_SPARC) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)1; - p = data; - lim = data + size - 4; - - if (encoding) - + const UInt32 flag = (UInt32)1 << 22; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction for (;;) { - UInt32 b1; + UInt32 v; for (;;) { - UInt32 b3; - if (p > lim) - return (SizeT)(p - data); - b1 = p[1]; - b3 = p[3]; - p += 2; - b1 ^= 8; - if ((b3 & b1) >= 0xF8) + if Z7_UNLIKELY(p == lim) + return p; + /* // the code without GetBe32a(): + { const UInt32 v = GetUi16a(p) & 0xc0ff; p += 4; if (v == 0x40 || v == 0xc07f) break; } + */ + v = GetBe32a(p); + p += 4; + #ifdef BR_SPARC_USE_ROTATE + v = rotlFixed(v, 2); + v += (flag << 2) - 1; + if Z7_UNLIKELY((v & (3 - (flag << 3))) == 0) + #else + v += (UInt32)5 << 29; + v ^= (UInt32)7 << 29; + v += flag; + if Z7_UNLIKELY((v & (0 - (flag << 1))) == 0) + #endif break; } { - UInt32 v = - ((UInt32)b1 << 19) - + (((UInt32)p[1] & 0x7) << 8) - + (((UInt32)p[-2] << 11)) - + (p[0]); - - p += 2; + // UInt32 v = GetBe32a(p - 4); + #ifndef BR_SPARC_USE_ROTATE + v <<= 2; + #endif { - UInt32 cur = (ip + (UInt32)(p - data)) >> 1; - v += cur; + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) } - - p[-4] = (Byte)(v >> 11); - p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); - p[-2] = (Byte)v; - p[-1] = (Byte)(0xF8 | (v >> 8)); + v &= (flag << 3) - 1; + #ifdef BR_SPARC_USE_ROTATE + v -= (flag << 2) - 1; + v = rotrFixed(v, 2); + #else + v -= (flag << 2); + v >>= 2; + v |= (UInt32)1 << 30; + #endif + SetBe32a(p - 4, v) } } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_SPARC) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARMT) +{ + // Byte *p = data; + Byte *lim; + size &= ~(SizeT)1; + // if (size == 0) return p; + if (size <= 2) return p; + size -= 2; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to the +2 instructions from current instruction */ + // pc += 4 - 4; + // if (encoding) pc -= 0xf800 << 1; else pc += 0xf800 << 1; + // #define ARMT_TAIL_PROC { goto armt_tail; } + #define ARMT_TAIL_PROC { return p; } - for (;;) + do { - UInt32 b1; + /* in MSVC 32-bit x86 compilers: + UInt32 version : it loads value from memory with movzx + Byte version : it loads value to 8-bit register (AL/CL) + movzx version is slightly faster in some cpus + */ + unsigned b1; + // Byte / unsigned + b1 = p[1]; + // optimized version to reduce one (p >= lim) check: + // unsigned a1 = p[1]; b1 = p[3]; p += 2; if Z7_LIKELY((b1 & (a1 ^ 8)) < 0xf8) for (;;) { - UInt32 b3; - if (p > lim) - return (SizeT)(p - data); - b1 = p[1]; - b3 = p[3]; - p += 2; - b1 ^= 8; - if ((b3 & b1) >= 0xF8) - break; + unsigned b3; // Byte / UInt32 + /* (Byte)(b3) normalization can use low byte computations in MSVC. + It gives smaller code, and no loss of speed in some compilers/cpus. + But new MSVC 32-bit x86 compilers use more slow load + from memory to low byte register in that case. + So we try to use full 32-bit computations for faster code. + */ + // if (p >= lim) { ARMT_TAIL_PROC } b3 = b1 + 8; b1 = p[3]; p += 2; if ((b3 & b1) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b3 = p[3]; p += 2; if Z7_UNLIKELY((b3 & (b1 ^ 8)) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b1 = p[3]; p += 2; if Z7_UNLIKELY((b1 & (b3 ^ 8)) >= 0xf8) break; } { + /* we can adjust pc for (0xf800) to rid of (& 0x7FF) operation. + But gcc/clang for arm64 can use bfi instruction for full code here */ + UInt32 v = + ((UInt32)GetUi16a(p - 2) << 11) | + ((UInt32)GetUi16a(p) & 0x7FF); + /* UInt32 v = - ((UInt32)b1 << 19) + ((UInt32)p[1 - 2] << 19) + (((UInt32)p[1] & 0x7) << 8) + (((UInt32)p[-2] << 11)) + (p[0]); - + */ p += 2; { - UInt32 cur = (ip + (UInt32)(p - data)) >> 1; - v -= cur; + UInt32 c = BR_PC_GET >> 1; + BR_CONVERT_VAL(v, c) } - + SetUi16a(p - 4, (UInt16)(((v >> 11) & 0x7ff) | 0xf000)) + SetUi16a(p - 2, (UInt16)(v | 0xf800)) /* - SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); - SetUi16(p - 2, (UInt16)(v | 0xF800)); - */ - p[-4] = (Byte)(v >> 11); - p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); + p[-3] = (Byte)(0xf0 | ((v >> 19) & 0x7)); p[-2] = (Byte)v; - p[-1] = (Byte)(0xF8 | (v >> 8)); + p[-1] = (Byte)(0xf8 | (v >> 8)); + */ } } + while (p < lim); + return p; + // armt_tail: + // if ((Byte)((lim[1] & 0xf8)) != 0xf0) { lim += 2; } return lim; + // return (Byte *)(lim + ((Byte)((lim[1] ^ 0xf0) & 0xf8) == 0 ? 0 : 2)); + // return (Byte *)(lim + (((lim[1] ^ ~0xfu) & ~7u) == 0 ? 0 : 2)); + // return (Byte *)(lim + 2 - (((((unsigned)lim[1] ^ 8) + 8) >> 7) & 2)); } +Z7_BRANCH_FUNCS_IMP(BranchConv_ARMT) -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +// #define BR_IA64_NO_INLINE + +Z7_BRANCH_FUNC_MAIN(BranchConv_IA64) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)3; - ip -= 4; - p = data; - lim = data + size; - + size &= ~(SizeT)15; + lim = p + size; + pc -= 1 << 4; + pc >>= 4 - 1; + // pc -= 1 << 1; + for (;;) { + unsigned m; for (;;) { - if (p >= lim) - return (SizeT)(p - data); - p += 4; - /* if ((v & 0xFC000003) == 0x48000001) */ - if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) + if Z7_UNLIKELY(p == lim) + return p; + m = (unsigned)((UInt32)0x334b0000 >> (*p & 0x1e)); + p += 16; + pc += 1 << 1; + if (m &= 3) break; } { - UInt32 v = GetBe32(p - 4); - if (encoding) - v += ip + (UInt32)(p - data); - else - v -= ip + (UInt32)(p - data); - v &= 0x03FFFFFF; - v |= 0x48000000; - SetBe32(p - 4, v); + p += (ptrdiff_t)m * 5 - 20; // negative value is expected here. + do + { + const UInt32 t = + #if defined(MY_CPU_X86_OR_AMD64) + // we use 32-bit load here to reduce code size on x86: + GetUi32(p); + #else + GetUi16(p); + #endif + UInt32 z = GetUi32(p + 1) >> m; + p += 5; + if (((t >> m) & (0x70 << 1)) == 0 + && ((z - (0x5000000 << 1)) & (0xf000000 << 1)) == 0) + { + UInt32 v = (UInt32)((0x8fffff << 1) | 1) & z; + z ^= v; + #ifdef BR_IA64_NO_INLINE + v |= (v & ((UInt32)1 << (23 + 1))) >> 3; + { + UInt32 c = pc; + BR_CONVERT_VAL(v, c) + } + v &= (0x1fffff << 1) | 1; + #else + { + if (encoding) + { + // pc &= ~(0xc00000 << 1); // we just need to clear at least 2 bits + pc &= (0x1fffff << 1) | 1; + v += pc; + } + else + { + // pc |= 0xc00000 << 1; // we need to set at least 2 bits + pc |= ~(UInt32)((0x1fffff << 1) | 1); + v -= pc; + } + } + v &= ~(UInt32)(0x600000 << 1); + #endif + v += (0x700000 << 1); + v &= (0x8fffff << 1) | 1; + z |= v; + z <<= m; + SetUi32(p + 1 - 5, z) + } + m++; + } + while (m &= 3); // while (m < 4); } } } +Z7_BRANCH_FUNCS_IMP(BranchConv_IA64) + +#define BR_CONVERT_VAL_ENC(v) v += BR_PC_GET; +#define BR_CONVERT_VAL_DEC(v) v -= BR_PC_GET; -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +#if 1 && defined(MY_CPU_LE_UNALIGN) + #define RISCV_USE_UNALIGNED_LOAD +#endif + +#ifdef RISCV_USE_UNALIGNED_LOAD + #define RISCV_GET_UI32(p) GetUi32(p) + #define RISCV_SET_UI32(p, v) { SetUi32(p, v) } +#else + #define RISCV_GET_UI32(p) \ + ((UInt32)GetUi16a(p) + \ + ((UInt32)GetUi16a((p) + 2) << 16)) + #define RISCV_SET_UI32(p, v) { \ + SetUi16a(p, (UInt16)(v)) \ + SetUi16a((p) + 2, (UInt16)(v >> 16)) } +#endif + +#if 1 && defined(MY_CPU_LE) + #define RISCV_USE_16BIT_LOAD +#endif + +#ifdef RISCV_USE_16BIT_LOAD + #define RISCV_LOAD_VAL(p) GetUi16a(p) +#else + #define RISCV_LOAD_VAL(p) (*(p)) +#endif + +#define RISCV_INSTR_SIZE 2 +#define RISCV_STEP_1 (4 + RISCV_INSTR_SIZE) +#define RISCV_STEP_2 4 +#define RISCV_REG_VAL (2 << 7) +#define RISCV_CMD_VAL 3 +#if 1 + // for code size optimization: + #define RISCV_DELTA_7F 0x7f +#else + #define RISCV_DELTA_7F 0 +#endif + +#define RISCV_CHECK_1(v, b) \ + (((((b) - RISCV_CMD_VAL) ^ ((v) << 8)) & (0xf8000 + RISCV_CMD_VAL)) == 0) + +#if 1 + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL | 8)) \ + << 18) \ + < ((r) & 0x1d)) +#else + // this branch gives larger code, because + // compilers generate larger code for big constants. + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + & ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + < ((r) & 0x1d)) +#endif + + +#define RISCV_SCAN_LOOP \ + Byte *lim; \ + size &= ~(SizeT)(RISCV_INSTR_SIZE - 1); \ + if (size <= 6) return p; \ + size -= 6; \ + lim = p + size; \ + BR_PC_INIT \ + for (;;) \ + { \ + UInt32 a, v; \ + /* Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE */ \ + for (;;) \ + { \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + a = (RISCV_LOAD_VAL(p) ^ 0x10u) + 1; \ + if ((a & 0x77) == 0) break; \ + a = (RISCV_LOAD_VAL(p + RISCV_INSTR_SIZE) ^ 0x10u) + 1; \ + p += RISCV_INSTR_SIZE * 2; \ + if ((a & 0x77) == 0) \ + { \ + p -= RISCV_INSTR_SIZE; \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + break; \ + } \ + } +// (xx6f ^ 10) + 1 = xx7f + 1 = xx80 : JAL +// (xxef ^ 10) + 1 = xxff + 1 = xx00 + 100 : JAL +// (xx17 ^ 10) + 1 = xx07 + 1 = xx08 : AUIPC +// (xx97 ^ 10) + 1 = xx87 + 1 = xx88 : AUIPC + +Byte * Z7_BRANCH_CONV_ENC(RISCV)(Byte *p, SizeT size, UInt32 pc) { - Byte *p; - const Byte *lim; - size &= ~(size_t)3; - ip -= 4; - p = data; - lim = data + size; + RISCV_SCAN_LOOP + v = a; + a = RISCV_GET_UI32(p); +#ifndef RISCV_USE_16BIT_LOAD + v += (UInt32)p[1] << 8; +#endif - for (;;) - { - for (;;) + if ((v & 8) == 0) // JAL { - if (p >= lim) - return (SizeT)(p - data); - /* - v = GetBe32(p); - p += 4; - m = v + ((UInt32)5 << 29); - m ^= (UInt32)7 << 29; - m += (UInt32)1 << 22; - if ((m & ((UInt32)0x1FF << 23)) == 0) - break; - */ + if ((v - (0x100 /* - RISCV_DELTA_7F */)) & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + v = ((a & 1u << 31) >> 11) + | ((a & 0x3ff << 21) >> 20) + | ((a & 1 << 20) >> 9) + | (a & 0xff << 12); + BR_CONVERT_VAL_ENC(v) + // ((v & 1) == 0) + // v: bits [1 : 20] contain offset bits +#if 0 && defined(RISCV_USE_UNALIGNED_LOAD) + a &= 0xfff; + a |= ((UInt32)(v << 23)) + | ((UInt32)(v << 7) & ((UInt32)0xff << 16)) + | ((UInt32)(v >> 5) & ((UInt32)0xf0 << 8)); + RISCV_SET_UI32(p, a) +#else // aligned +#if 0 + SetUi16a(p, (UInt16)(((v >> 5) & 0xf000) | (a & 0xfff))) +#else + p[1] = (Byte)(((v >> 13) & 0xf0) | ((a >> 8) & 0xf)); +#endif + +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v <<= 15; + v = Z7_BSWAP32(v); + SetUi16a(p + 2, (UInt16)v) +#else + p[2] = (Byte)(v >> 9); + p[3] = (Byte)(v >> 1); +#endif +#endif // aligned + } p += 4; - if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || - (p[-4] == 0x7F && (p[-3] >= 0xC0))) - break; + continue; + } // JAL + + { + // AUIPC + if (v & 0xe80) // (not x0) and (not x2) + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (RISCV_CHECK_1(v, b)) + { + { + const UInt32 temp = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, temp) + } + a &= 0xfffff000; + { +#if 1 + const int t = -1 >> 1; + if (t != -1) + a += (b >> 20) - ((b >> 19) & 0x1000); // arithmetic right shift emulation + else +#endif + a += (UInt32)((Int32)b >> 20); // arithmetic right shift (sign-extension). + } + BR_CONVERT_VAL_ENC(a) +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + a = Z7_BSWAP32(a); + RISCV_SET_UI32(p + 4, a) +#else + SetBe32(p + 4, a) +#endif + p += 8; + } + else + p += RISCV_STEP_1; + } + else + { + UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + v = RISCV_GET_UI32(p + 4); + r = (r << 7) + 0x17 + (v & 0xfffff000); + a = (a >> 12) | (v << 20); + RISCV_SET_UI32(p, r) + RISCV_SET_UI32(p + 4, a) + p += 8; + } + else + p += RISCV_STEP_2; + } } + } // for +} + + +Byte * Z7_BRANCH_CONV_DEC(RISCV)(Byte *p, SizeT size, UInt32 pc) +{ + RISCV_SCAN_LOOP +#ifdef RISCV_USE_16BIT_LOAD + if ((a & 8) == 0) + { +#else + v = a; + a += (UInt32)p[1] << 8; + if ((v & 8) == 0) + { +#endif + // JAL + a -= 0x100 - RISCV_DELTA_7F; + if (a & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + const UInt32 a_old = (a + (0xef - RISCV_DELTA_7F)) & 0xfff; +#if 0 // unaligned + a = GetUi32(p); + v = (UInt32)(a >> 23) & ((UInt32)0xff << 1) + | (UInt32)(a >> 7) & ((UInt32)0xff << 9) +#elif 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v = GetUi16a(p + 2); + v = Z7_BSWAP32(v) >> 15 +#else + v = (UInt32)p[3] << 1 + | (UInt32)p[2] << 9 +#endif + | (UInt32)((a & 0xf000) << 5); + BR_CONVERT_VAL_DEC(v) + a = a_old + | (v << 11 & 1u << 31) + | (v << 20 & 0x3ff << 21) + | (v << 9 & 1 << 20) + | (v & 0xff << 12); + RISCV_SET_UI32(p, a) + } + p += 4; + continue; + } // JAL + { - UInt32 v = GetBe32(p - 4); - v <<= 2; - if (encoding) - v += ip + (UInt32)(p - data); + // AUIPC + v = a; +#if 1 && defined(RISCV_USE_UNALIGNED_LOAD) + a = GetUi32(p); +#else + a |= (UInt32)GetUi16a(p + 2) << 16; +#endif + if ((v & 0xe80) == 0) // x0/x2 + { + const UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + UInt32 b; +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + b = RISCV_GET_UI32(p + 4); + b = Z7_BSWAP32(b); +#else + b = GetBe32(p + 4); +#endif + v = a >> 12; + BR_CONVERT_VAL_DEC(b) + a = (r << 7) + 0x17; + a += (b + 0x800) & 0xfffff000; + v |= b << 20; + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + else + p += RISCV_STEP_2; + } else - v -= ip + (UInt32)(p - data); - - v &= 0x01FFFFFF; - v -= (UInt32)1 << 24; - v ^= 0xFF000000; - v >>= 2; - v |= 0x40000000; - SetBe32(p - 4, v); + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (!RISCV_CHECK_1(v, b)) + p += RISCV_STEP_1; + else + { + v = (a & 0xfffff000) | (b >> 20); + a = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + } } - } + } // for } diff -Nru 7zip-22.01+dfsg/C/Bra.h 7zip-22.01+really25.01+dfsg/C/Bra.h --- 7zip-22.01+dfsg/C/Bra.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bra.h 2024-01-20 17:00:00.000000000 +0000 @@ -1,64 +1,105 @@ /* Bra.h -- Branch converters for executables -2013-01-18 : Igor Pavlov : Public domain */ +2024-01-20 : Igor Pavlov : Public domain */ -#ifndef __BRA_H -#define __BRA_H +#ifndef ZIP7_INC_BRA_H +#define ZIP7_INC_BRA_H #include "7zTypes.h" EXTERN_C_BEGIN -/* -These functions convert relative addresses to absolute addresses -in CALL instructions to increase the compression ratio. - - In: - data - data buffer - size - size of data - ip - current virtual Instruction Pinter (IP) value - state - state variable for x86 converter - encoding - 0 (for decoding), 1 (for encoding) - - Out: - state - state variable for x86 converter +/* #define PPC BAD_PPC_11 // for debug */ + +#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec +#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc +#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec +#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc + +#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc) +#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state) + +typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv)); +typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt)); + +#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0 +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86)); +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86)); + +#define Z7_BRANCH_FUNCS_DECL(name) \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name)); + +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT) +Z7_BRANCH_FUNCS_DECL (BranchConv_PPC) +Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC) +Z7_BRANCH_FUNCS_DECL (BranchConv_IA64) +Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV) - Returns: - The number of processed bytes. If you call these functions with multiple calls, - you must start next call with first byte after block of processed bytes. +/* +These functions convert data that contain CPU instructions. +Each such function converts relative addresses to absolute addresses in some +branch instructions: CALL (in all converters) and JUMP (X86 converter only). +Such conversion allows to increase compression ratio, if we compress that data. + +There are 2 types of converters: + Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc); + Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state); +Each Converter supports 2 versions: one for encoding +and one for decoding (_Enc/_Dec postfixes in function name). + +In params: + data : data buffer + size : size of data + pc : current virtual Program Counter (Instruction Pointer) value +In/Out param: + state : pointer to state variable (for X86 converter only) + +Return: + The pointer to position in (data) buffer after last byte that was processed. + If the caller calls converter again, it must call it starting with that position. + But the caller is allowed to move data in buffer. So pointer to + current processed position also will be changed for next call. + Also the caller must increase internal (pc) value for next call. +Each converter has some characteristics: Endian, Alignment, LookAhead. Type Endian Alignment LookAhead - x86 little 1 4 + X86 little 1 4 ARMT little 2 2 + RISCV little 2 6 ARM little 4 0 + ARM64 little 4 0 PPC big 4 0 SPARC big 4 0 IA64 little 16 0 - size must be >= Alignment + LookAhead, if it's not last block. - If (size < Alignment + LookAhead), converter returns 0. - - Example: - - UInt32 ip = 0; - for () - { - ; size must be >= Alignment + LookAhead, if it's not last block - SizeT processed = Convert(data, size, ip, 1); - data += processed; - size -= processed; - ip += processed; - } + (data) must be aligned for (Alignment). + processed size can be calculated as: + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0) + it means that converter needs more data for processing. + If (size < Alignment + LookAhead) + then (processed == 0) is allowed. + +Example code for conversion in loop: + UInt32 pc = 0; + size = 0; + for (;;) + { + size += Load_more_input_data(data + size); + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0 && no_more_input_data_after_size) + break; // we stop convert loop + data += processed; + size -= processed; + pc += processed; + } */ -#define x86_Convert_Init(state) { state = 0; } -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); - EXTERN_C_END #endif diff -Nru 7zip-22.01+dfsg/C/Bra86.c 7zip-22.01+really25.01+dfsg/C/Bra86.c --- 7zip-22.01+dfsg/C/Bra86.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Bra86.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,82 +1,187 @@ -/* Bra86.c -- Converter for x86 code (BCJ) -2021-02-09 : Igor Pavlov : Public domain */ +/* Bra86.c -- Branch converter for X86 code (BCJ) +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "Bra.h" +#include "CpuArch.h" -#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; // (MY_uintptr_t) +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV_ST(name) z7_BranchConvSt_ ## name + +#define BR86_NEED_CONV_FOR_MS_BYTE(b) ((((b) + 1) & 0xfe) == 0) + +#ifdef MY_CPU_LE_UNALIGN + #define BR86_PREPARE_BCJ_SCAN const UInt32 v = GetUi32(p) ^ 0xe8e8e8e8; + #define BR86_IS_BCJ_BYTE(n) ((v & ((UInt32)0xfe << (n) * 8)) == 0) +#else + #define BR86_PREPARE_BCJ_SCAN + // bad for MSVC X86 (partial write to byte reg): + #define BR86_IS_BCJ_BYTE(n) ((p[n - 4] & 0xfe) == 0xe8) + // bad for old MSVC (partial write to byte reg): + // #define BR86_IS_BCJ_BYTE(n) (((*p ^ 0xe8) & 0xfe) == 0) +#endif + +static +Z7_FORCE_INLINE +Z7_ATTRIB_NO_VECTOR +Byte *Z7_BRANCH_CONV_ST(X86)(Byte *p, SizeT size, UInt32 pc, UInt32 *state, int encoding) { - SizeT pos = 0; - UInt32 mask = *state & 7; if (size < 5) - return 0; - size -= 4; - ip += 5; + return p; + { + // Byte *p = data; + const Byte *lim = p + size - 4; + unsigned mask = (unsigned)*state; // & 7; +#ifdef BR_CONV_USE_OPT_PC_PTR + /* if BR_CONV_USE_OPT_PC_PTR is defined: we need to adjust (pc) for (+4), + because call/jump offset is relative to the next instruction. + if BR_CONV_USE_OPT_PC_PTR is not defined : we don't need to adjust (pc) for (+4), + because BR_PC_GET uses (pc - (lim - p)), and lim was adjusted for (-4) before. + */ + pc += 4; +#endif + BR_PC_INIT + goto start; - for (;;) + for (;; mask |= 4) { - Byte *p = data + pos; - const Byte *limit = data + size; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - + // cont: mask |= 4; + start: + if (p >= lim) + goto fin; { - SizeT d = (SizeT)(p - data) - pos; - pos = (SizeT)(p - data); - if (p >= limit) - { - *state = (d > 2 ? 0 : mask >> (unsigned)d); - return pos; - } - if (d > 2) - mask = 0; - else - { - mask >>= (unsigned)d; - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) - { - mask = (mask >> 1) | 4; - pos++; - continue; - } - } + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto m0; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(1)) { goto m1; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(2)) { goto m2; } mask = 0; + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } } + goto main_loop; - if (Test86MSByte(p[4])) + m0: p--; + m1: p--; + m2: p--; + if (mask == 0) + goto a3; + if (p > lim) + goto fin_p; + + // if (((0x17u >> mask) & 1) == 0) + if (mask > 4 || mask == 3) { - UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 cur = ip + (UInt32)pos; - pos += 5; - if (encoding) - v += cur; - else - v -= cur; - if (mask != 0) + mask >>= 1; + continue; // goto cont; + } + mask >>= 1; + if (BR86_NEED_CONV_FOR_MS_BYTE(p[mask])) + continue; // goto cont; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) { - unsigned sh = (mask & 6) << 2; - if (Test86MSByte((Byte)(v >> sh))) + mask <<= 3; + if (BR86_NEED_CONV_FOR_MS_BYTE(v >> mask)) { - v ^= (((UInt32)0x100 << sh) - 1); - if (encoding) - v += cur; - else - v -= cur; + v ^= (((UInt32)0x100 << mask) - 1); + #ifdef MY_CPU_X86 + // for X86 : we can recalculate (c) to reduce register pressure + c = BR_PC_GET; + #endif + BR_CONVERT_VAL(v, c) } mask = 0; } - p[1] = (Byte)v; - p[2] = (Byte)(v >> 8); - p[3] = (Byte)(v >> 16); - p[4] = (Byte)(0 - ((v >> 24) & 1)); + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; + } + + main_loop: + if (p >= lim) + goto fin; + for (;;) + { + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto a0; } + if (BR86_IS_BCJ_BYTE(1)) { goto a1; } + if (BR86_IS_BCJ_BYTE(2)) { goto a2; } + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } + if (p >= lim) + goto fin; } - else + + a0: p--; + a1: p--; + a2: p--; + a3: + if (p > lim) + goto fin_p; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; { - mask = (mask >> 1) | 4; - pos++; + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; } } + +fin_p: + p--; +fin: + // the following processing for tail is optional and can be commented + /* + lim += 4; + for (; p < lim; p++, mask >>= 1) + if ((*p & 0xfe) == 0xe8) + break; + */ + *state = (UInt32)mask; + return p; + } } + + +#define Z7_BRANCH_CONV_ST_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc, UInt32 *state) \ + { return Z7_BRANCH_CONV_ST(name)(data, size, pc, state, encoding); } + +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_DEC, 0) +#ifndef Z7_EXTRACT_ONLY +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_ENC, 1) +#endif diff -Nru 7zip-22.01+dfsg/C/BraIA64.c 7zip-22.01+really25.01+dfsg/C/BraIA64.c --- 7zip-22.01+dfsg/C/BraIA64.c 2017-01-28 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/BraIA64.c 2023-02-20 10:00:00.000000000 +0000 @@ -1,53 +1,14 @@ /* BraIA64.c -- Converter for IA-64 code -2017-01-26 : Igor Pavlov : Public domain */ +2023-02-20 : Igor Pavlov : Public domain */ #include "Precomp.h" -#include "CpuArch.h" -#include "Bra.h" +// the code was moved to Bra.c -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 16) - return 0; - size -= 16; - i = 0; - do - { - unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3; - if (m) - { - m++; - do - { - Byte *p = data + (i + (size_t)m * 5 - 8); - if (((p[3] >> m) & 15) == 5 - && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0) - { - unsigned raw = GetUi32(p); - unsigned v = raw >> m; - v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3); - - v <<= 4; - if (encoding) - v += ip + (UInt32)i; - else - v -= ip + (UInt32)i; - v >>= 4; - - v &= 0x1FFFFF; - v += 0x700000; - v &= 0x8FFFFF; - raw &= ~((UInt32)0x8FFFFF << m); - raw |= (v << m); - SetUi32(p, raw); - } - } - while (++m <= 4); - } - i += 16; - } - while (i <= size); - return i; -} +#ifdef _MSC_VER +#pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#endif + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wempty-translation-unit" +#endif diff -Nru 7zip-22.01+dfsg/C/BwtSort.c 7zip-22.01+really25.01+dfsg/C/BwtSort.c --- 7zip-22.01+dfsg/C/BwtSort.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/BwtSort.c 2025-01-13 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* BwtSort.c -- BWT block sorting -2021-04-01 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,8 +7,44 @@ #include "Sort.h" /* #define BLOCK_SORT_USE_HEAP_SORT */ +// #define BLOCK_SORT_USE_HEAP_SORT + +#ifdef BLOCK_SORT_USE_HEAP_SORT + +#define HeapSortRefDown(p, vals, n, size, temp) \ + { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ + size_t s = k << 1; \ + if (s > size) break; \ + if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ + if (val >= vals[p[s]]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + HeapSortRefDown(p, vals, i, size, temp); + } + while (--i != 0); + } + do + { + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortRefDown(p, vals, 1, size, temp); + } + while (size > 1); +} + +#endif // BLOCK_SORT_USE_HEAP_SORT -#define NO_INLINE MY_FAST_CALL /* Don't change it !!! */ #define kNumHashBytes 2 @@ -29,26 +65,27 @@ #else -#define kNumBitsMax 20 -#define kIndexMask ((1 << kNumBitsMax) - 1) -#define kNumExtraBits (32 - kNumBitsMax) -#define kNumExtra0Bits (kNumExtraBits - 2) -#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) +#define kNumBitsMax 20 +#define kIndexMask (((UInt32)1 << kNumBitsMax) - 1) +#define kNumExtraBits (32 - kNumBitsMax) +#define kNumExtra0Bits (kNumExtraBits - 2) +#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) #define SetFinishedGroupSize(p, size) \ - { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ + { *(p) |= ((((UInt32)(size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ if ((size) > (1 << kNumExtra0Bits)) { \ - *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \ + *(p) |= 0x40000000; \ + *((p) + 1) |= (((UInt32)(size) - 1) >> kNumExtra0Bits) << kNumBitsMax; } } \ -static void SetGroupSize(UInt32 *p, UInt32 size) +static void SetGroupSize(UInt32 *p, size_t size) { if (--size == 0) return; - *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax); + *p |= 0x80000000 | (((UInt32)size & kNumExtra0Mask) << kNumBitsMax); if (size >= (1 << kNumExtra0Bits)) { *p |= 0x40000000; - p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax); + p[1] |= (((UInt32)size >> kNumExtra0Bits) << kNumBitsMax); } } @@ -60,10 +97,15 @@ returns: 1 - if there are groups, 0 - no more groups */ -static UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices - #ifndef BLOCK_SORT_USE_HEAP_SORT - , UInt32 left, UInt32 range - #endif +static +unsigned +Z7_FASTCALL +SortGroup(size_t BlockSize, size_t NumSortedBytes, + size_t groupOffset, size_t groupSize, + unsigned NumRefBits, UInt32 *Indices +#ifndef BLOCK_SORT_USE_HEAP_SORT + , size_t left, size_t range +#endif ) { UInt32 *ind2 = Indices + groupOffset; @@ -72,96 +114,99 @@ { /* #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetFinishedGroupSize(ind2, 1); + SetFinishedGroupSize(ind2, 1) #endif */ return 0; } Groups = Indices + BlockSize + BS_TEMP_SIZE; - if (groupSize <= ((UInt32)1 << NumRefBits) - #ifndef BLOCK_SORT_USE_HEAP_SORT + if (groupSize <= ((size_t)1 << NumRefBits) +#ifndef BLOCK_SORT_USE_HEAP_SORT && groupSize <= range - #endif +#endif ) { UInt32 *temp = Indices + BlockSize; - UInt32 j; - UInt32 mask, thereAreGroups, group, cg; + size_t j, group; + UInt32 mask, cg; + unsigned thereAreGroups; { UInt32 gPrev; UInt32 gRes = 0; { - UInt32 sp = ind2[0] + NumSortedBytes; - if (sp >= BlockSize) sp -= BlockSize; + size_t sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; gPrev = Groups[sp]; - temp[0] = (gPrev << NumRefBits); + temp[0] = gPrev << NumRefBits; } for (j = 1; j < groupSize; j++) { - UInt32 sp = ind2[j] + NumSortedBytes; + size_t sp = ind2[j] + NumSortedBytes; UInt32 g; - if (sp >= BlockSize) sp -= BlockSize; + if (sp >= BlockSize) + sp -= BlockSize; g = Groups[sp]; - temp[j] = (g << NumRefBits) | j; + temp[j] = (g << NumRefBits) | (UInt32)j; gRes |= (gPrev ^ g); } if (gRes == 0) { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS SetGroupSize(ind2, groupSize); - #endif +#endif return 1; } } HeapSort(temp, groupSize); - mask = (((UInt32)1 << NumRefBits) - 1); + mask = ((UInt32)1 << NumRefBits) - 1; thereAreGroups = 0; group = groupOffset; - cg = (temp[0] >> NumRefBits); + cg = temp[0] >> NumRefBits; temp[0] = ind2[temp[0] & mask]; { - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS UInt32 *Flags = Groups + BlockSize; - #else - UInt32 prevGroupStart = 0; - #endif +#else + size_t prevGroupStart = 0; +#endif for (j = 1; j < groupSize; j++) { - UInt32 val = temp[j]; - UInt32 cgCur = (val >> NumRefBits); + const UInt32 val = temp[j]; + const UInt32 cgCur = val >> NumRefBits; if (cgCur != cg) { cg = cgCur; group = groupOffset + j; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS { - UInt32 t = group - 1; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + const size_t t = group - 1; + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); } - #else +#else SetGroupSize(temp + prevGroupStart, j - prevGroupStart); prevGroupStart = j; - #endif +#endif } else thereAreGroups = 1; { - UInt32 ind = ind2[val & mask]; - temp[j] = ind; - Groups[ind] = group; + const UInt32 ind = ind2[val & mask]; + temp[j] = ind; + Groups[ind] = (UInt32)group; } } - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS SetGroupSize(temp + prevGroupStart, j - prevGroupStart); - #endif +#endif } for (j = 0; j < groupSize; j++) @@ -171,37 +216,42 @@ /* Check that all strings are in one group (cannot sort) */ { - UInt32 group, j; - UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + UInt32 group; + size_t j; + size_t sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; group = Groups[sp]; for (j = 1; j < groupSize; j++) { - sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + sp = ind2[j] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; if (Groups[sp] != group) break; } if (j == groupSize) { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS SetGroupSize(ind2, groupSize); - #endif +#endif return 1; } } - #ifndef BLOCK_SORT_USE_HEAP_SORT +#ifndef BLOCK_SORT_USE_HEAP_SORT { /* ---------- Range Sort ---------- */ - UInt32 i; - UInt32 mid; + size_t i; + size_t mid; for (;;) { - UInt32 j; + size_t j; if (range <= 1) { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS SetGroupSize(ind2, groupSize); - #endif +#endif return 1; } mid = left + ((range + 1) >> 1); @@ -209,7 +259,7 @@ i = 0; do { - UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + size_t sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; if (Groups[sp] >= mid) { for (j--; j > i; j--) @@ -237,51 +287,53 @@ break; } - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS { - UInt32 t = (groupOffset + i - 1); + const size_t t = groupOffset + i - 1; UInt32 *Flags = Groups + BlockSize; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); } - #endif +#endif { - UInt32 j; + size_t j; for (j = i; j < groupSize; j++) - Groups[ind2[j]] = groupOffset + i; + Groups[ind2[j]] = (UInt32)(groupOffset + i); } { - UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); - return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); + unsigned res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); + return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); } } - #else +#else // BLOCK_SORT_USE_HEAP_SORT /* ---------- Heap Sort ---------- */ { - UInt32 j; + size_t j; for (j = 0; j < groupSize; j++) { - UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - ind2[j] = sp; + size_t sp = ind2[j] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; + ind2[j] = (UInt32)sp; } HeapSortRef(ind2, Groups, groupSize); /* Write Flags */ { - UInt32 sp = ind2[0]; + size_t sp = ind2[0]; UInt32 group = Groups[sp]; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS UInt32 *Flags = Groups + BlockSize; - #else - UInt32 prevGroupStart = 0; - #endif +#else + size_t prevGroupStart = 0; +#endif for (j = 1; j < groupSize; j++) { @@ -289,149 +341,210 @@ if (Groups[sp] != group) { group = Groups[sp]; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS { - UInt32 t = groupOffset + j - 1; + const size_t t = groupOffset + j - 1; Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); } - #else +#else SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); prevGroupStart = j; - #endif +#endif } } - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); - #endif +#endif } { /* Write new Groups values and Check that there are groups */ - UInt32 thereAreGroups = 0; + unsigned thereAreGroups = 0; for (j = 0; j < groupSize; j++) { - UInt32 group = groupOffset + j; - #ifndef BLOCK_SORT_EXTERNAL_FLAGS + size_t group = groupOffset + j; +#ifndef BLOCK_SORT_EXTERNAL_FLAGS UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); - if ((ind2[j] & 0x40000000) != 0) + if (ind2[j] & 0x40000000) subGroupSize += ((ind2[(size_t)j + 1] >> kNumBitsMax) << kNumExtra0Bits); subGroupSize++; for (;;) { - UInt32 original = ind2[j]; - UInt32 sp = original & kIndexMask; - if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; - ind2[j] = sp | (original & ~kIndexMask); - Groups[sp] = group; + const UInt32 original = ind2[j]; + size_t sp = original & kIndexMask; + if (sp < NumSortedBytes) + sp += BlockSize; + sp -= NumSortedBytes; + ind2[j] = (UInt32)sp | (original & ~kIndexMask); + Groups[sp] = (UInt32)group; if (--subGroupSize == 0) break; j++; thereAreGroups = 1; } - #else +#else UInt32 *Flags = Groups + BlockSize; for (;;) { - UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; - ind2[j] = sp; - Groups[sp] = group; + size_t sp = ind2[j]; + if (sp < NumSortedBytes) + sp += BlockSize; + sp -= NumSortedBytes; + ind2[j] = (UInt32)sp; + Groups[sp] = (UInt32)group; if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) break; j++; thereAreGroups = 1; } - #endif +#endif } return thereAreGroups; } } - #endif +#endif // BLOCK_SORT_USE_HEAP_SORT } + /* conditions: blockSize > 0 */ -UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize) +UInt32 BlockSort(UInt32 *Indices, const Byte *data, size_t blockSize) { UInt32 *counters = Indices + blockSize; - UInt32 i; + size_t i; UInt32 *Groups; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS UInt32 *Flags; - #endif +#endif - /* Radix-Sort for 2 bytes */ +/* Radix-Sort for 2 bytes */ +// { UInt32 yyy; for (yyy = 0; yyy < 100; yyy++) { for (i = 0; i < kNumHashValues; i++) counters[i] = 0; - for (i = 0; i < blockSize - 1; i++) - counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++; - counters[((UInt32)data[i] << 8) | data[0]]++; + { + const Byte *data2 = data; + size_t a = data[(size_t)blockSize - 1]; + const Byte *data_lim = data + blockSize; + if (blockSize >= 4) + { + data_lim -= 3; + do + { + size_t b; + b = data2[0]; counters[(a << 8) | b]++; + a = data2[1]; counters[(b << 8) | a]++; + b = data2[2]; counters[(a << 8) | b]++; + a = data2[3]; counters[(b << 8) | a]++; + data2 += 4; + } + while (data2 < data_lim); + data_lim += 3; + } + while (data2 != data_lim) + { + size_t b = *data2++; + counters[(a << 8) | b]++; + a = b; + } + } +// }} Groups = counters + BS_TEMP_SIZE; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS +#ifdef BLOCK_SORT_EXTERNAL_FLAGS Flags = Groups + blockSize; - { - UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; - for (i = 0; i < numWords; i++) - Flags[i] = kAllFlags; - } - #endif + { + const size_t numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } +#endif { UInt32 sum = 0; for (i = 0; i < kNumHashValues; i++) { - UInt32 groupSize = counters[i]; - if (groupSize > 0) + const UInt32 groupSize = counters[i]; + counters[i] = sum; + sum += groupSize; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + if (groupSize) { - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 t = sum + groupSize - 1; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); - #endif - sum += groupSize; + const UInt32 t = sum - 1; + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); } - counters[i] = sum - groupSize; +#endif } + } - for (i = 0; i < blockSize - 1; i++) - Groups[i] = counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]; - Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((unsigned)data[i] << 8) | data[(size_t)i + 1]]; + Groups[i] = counters[((unsigned)data[i] << 8) | data[0]]; + + { +#define SET_Indices(a, b, i) \ + { UInt32 c; \ + a = (a << 8) | (b); \ + c = counters[a]; \ + Indices[c] = (UInt32)i++; \ + counters[a] = c + 1; \ + } - for (i = 0; i < blockSize - 1; i++) - Indices[counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++] = i; - Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; - - #ifndef BLOCK_SORT_EXTERNAL_FLAGS + size_t a = data[0]; + const Byte *data_ptr = data + 1; + i = 0; + if (blockSize >= 3) + { + blockSize -= 2; + do + { + size_t b; + b = data_ptr[0]; SET_Indices(a, b, i) + a = data_ptr[1]; SET_Indices(b, a, i) + data_ptr += 2; + } + while (i < blockSize); + blockSize += 2; + } + if (i < blockSize - 1) { + SET_Indices(a, data[(size_t)i + 1], i) + a = (Byte)a; + } + SET_Indices(a, data[0], i) + } + +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + { UInt32 prev = 0; for (i = 0; i < kNumHashValues; i++) { - UInt32 prevGroupSize = counters[i] - prev; + const UInt32 prevGroupSize = counters[i] - prev; if (prevGroupSize == 0) continue; SetGroupSize(Indices + prev, prevGroupSize); prev = counters[i]; } - } - #endif } +#endif { - int NumRefBits; - UInt32 NumSortedBytes; - for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++); + unsigned NumRefBits; + size_t NumSortedBytes; + for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++) + {} NumRefBits = 32 - NumRefBits; if (NumRefBits > kNumRefBitsMax) - NumRefBits = kNumRefBitsMax; + NumRefBits = kNumRefBitsMax; for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 finishedGroupSize = 0; - #endif - UInt32 newLimit = 0; +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + size_t finishedGroupSize = 0; +#endif + size_t newLimit = 0; for (i = 0; i < blockSize;) { - UInt32 groupSize; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS + size_t groupSize; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) { @@ -440,56 +553,56 @@ } for (groupSize = 1; (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; - groupSize++); - + groupSize++) + {} groupSize++; - #else +#else - groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + groupSize = (Indices[i] & ~0xC0000000) >> kNumBitsMax; { - BoolInt finishedGroup = ((Indices[i] & 0x80000000) == 0); - if ((Indices[i] & 0x40000000) != 0) - { - groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits); - Indices[(size_t)i + 1] &= kIndexMask; - } - Indices[i] &= kIndexMask; - groupSize++; - if (finishedGroup || groupSize == 1) - { - Indices[i - finishedGroupSize] &= kIndexMask; - if (finishedGroupSize > 1) - Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask; + const BoolInt finishedGroup = ((Indices[i] & 0x80000000) == 0); + if (Indices[i] & 0x40000000) { - UInt32 newGroupSize = groupSize + finishedGroupSize; - SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); - finishedGroupSize = newGroupSize; + groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[(size_t)i + 1] &= kIndexMask; } - i += groupSize; - continue; - } - finishedGroupSize = 0; + Indices[i] &= kIndexMask; + groupSize++; + if (finishedGroup || groupSize == 1) + { + Indices[i - finishedGroupSize] &= kIndexMask; + if (finishedGroupSize > 1) + Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask; + { + const size_t newGroupSize = groupSize + finishedGroupSize; + SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize) + finishedGroupSize = newGroupSize; + } + i += groupSize; + continue; + } + finishedGroupSize = 0; } - #endif +#endif if (NumSortedBytes >= blockSize) { - UInt32 j; + size_t j; for (j = 0; j < groupSize; j++) { - UInt32 t = (i + j); + size_t t = i + j; /* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */ - Groups[Indices[t]] = t; + Groups[Indices[t]] = (UInt32)t; } } else if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices - #ifndef BLOCK_SORT_USE_HEAP_SORT - , 0, blockSize - #endif - ) != 0) + #ifndef BLOCK_SORT_USE_HEAP_SORT + , 0, blockSize + #endif + )) newLimit = i + groupSize; i += groupSize; } @@ -497,19 +610,19 @@ break; } } - #ifndef BLOCK_SORT_EXTERNAL_FLAGS +#ifndef BLOCK_SORT_EXTERNAL_FLAGS for (i = 0; i < blockSize;) { - UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); - if ((Indices[i] & 0x40000000) != 0) + size_t groupSize = (Indices[i] & ~0xC0000000) >> kNumBitsMax; + if (Indices[i] & 0x40000000) { - groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits); + groupSize += (Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits; Indices[(size_t)i + 1] &= kIndexMask; } Indices[i] &= kIndexMask; groupSize++; i += groupSize; } - #endif +#endif return Groups[0]; } diff -Nru 7zip-22.01+dfsg/C/BwtSort.h 7zip-22.01+really25.01+dfsg/C/BwtSort.h --- 7zip-22.01+dfsg/C/BwtSort.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/BwtSort.h 2024-12-18 18:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* BwtSort.h -- BWT block sorting -2013-01-18 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __BWT_SORT_H -#define __BWT_SORT_H +#ifndef ZIP7_INC_BWT_SORT_H +#define ZIP7_INC_BWT_SORT_H #include "7zTypes.h" @@ -10,16 +10,17 @@ /* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ /* #define BLOCK_SORT_EXTERNAL_FLAGS */ +// #define BLOCK_SORT_EXTERNAL_FLAGS #ifdef BLOCK_SORT_EXTERNAL_FLAGS -#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) (((blockSize) + 31) >> 5) #else #define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 #endif #define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) -UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); +UInt32 BlockSort(UInt32 *indices, const Byte *data, size_t blockSize); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Compiler.h 7zip-22.01+really25.01+dfsg/C/Compiler.h --- 7zip-22.01+dfsg/C/Compiler.h 2021-01-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Compiler.h 2025-06-30 17:00:00.000000000 +0000 @@ -1,12 +1,105 @@ -/* Compiler.h -2021-01-05 : Igor Pavlov : Public domain */ +/* Compiler.h : Compiler specific defines and pragmas +: Igor Pavlov : Public domain */ -#ifndef __7Z_COMPILER_H -#define __7Z_COMPILER_H +#ifndef ZIP7_INC_COMPILER_H +#define ZIP7_INC_COMPILER_H - #ifdef __clang__ - #pragma clang diagnostic ignored "-Wunused-private-field" +#if defined(__clang__) +# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif +#if defined(__clang__) && defined(__apple_build_version__) +# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__clang__) +# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__GNUC__) +# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifdef _MSC_VER +#if !defined(__clang__) && !defined(__GNUC__) +#define Z7_MSC_VER_ORIGINAL _MSC_VER +#endif +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define Z7_MINGW +#endif + +#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__)) +#define Z7_MCST_LCC +#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__) +#endif + +/* +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #define Z7_COMPILER_AVX2_SUPPORTED #endif +#endif +*/ + +// #pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#ifdef __clang__ +// padding size of '' with 4 bytes to alignment boundary +#pragma GCC diagnostic ignored "-Wpadded" + +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \ + && defined(__FreeBSD__) +// freebsd: +#pragma GCC diagnostic ignored "-Wexcess-padding" +#endif + +#if __clang_major__ >= 16 +#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" +#endif + +#if __clang_major__ == 13 +#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// cheri +#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast" +#endif +#endif + +#if __clang_major__ == 13 + // for + #pragma GCC diagnostic ignored "-Wreserved-identifier" +#endif + +#endif // __clang__ + +#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16 +// #pragma GCC diagnostic ignored "-Wcast-function-type-strict" +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + +typedef void (*Z7_void_Function)(void); +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC_C (Z7_void_Function) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define Z7_CAST_FUNC_C (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()' +#else +#define Z7_CAST_FUNC_C +#endif +/* +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +*/ +#ifdef __GNUC__ +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +#endif + #ifdef _MSC_VER @@ -17,24 +110,134 @@ #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int #endif - #if _MSC_VER >= 1300 - #pragma warning(disable : 4996) // This function or variable may be unsafe - #else - #pragma warning(disable : 4511) // copy constructor could not be generated - #pragma warning(disable : 4512) // assignment operator could not be generated - #pragma warning(disable : 4514) // unreferenced inline function has been removed - #pragma warning(disable : 4702) // unreachable code - #pragma warning(disable : 4710) // not inlined - #pragma warning(disable : 4714) // function marked as __forceinline not inlined - #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information - #endif +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif - #ifdef __clang__ - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #pragma clang diagnostic ignored "-Wmicrosoft-exception-spec" - // #pragma clang diagnostic ignored "-Wreserved-id-macro" - #endif +// == 1200 : -O1 : for __forceinline +// >= 1900 : -O1 : for printf +#pragma warning(disable : 4710) // function not inlined + +#if _MSC_VER < 1900 +// winnt.h: 'Int64ShllMod32' +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + +#if _MSC_VER < 1300 +// #pragma warning(disable : 4702) // unreachable code +// Bra.c : -O1: +#pragma warning(disable : 4714) // function marked as __forceinline not inlined +#endif + +/* +#if _MSC_VER > 1400 && _MSC_VER <= 1900 +// strcat: This function or variable may be unsafe +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif +*/ + +#if _MSC_VER > 1200 +// -Wall warnings + +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4820) // '2' bytes padding added after data member + +#if _MSC_VER >= 1400 && _MSC_VER < 1920 +// 1400: string.h: _DBG_MEMCPY_INLINE_ +// 1600 - 191x : smmintrin.h __cplusplus' +// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable : 4668) + +// 1400 - 1600 : WinDef.h : 'FARPROC' : +// 1900 - 191x : immintrin.h: _readfsbase_u32 +// no function prototype given : converting '()' to '(void)' +#pragma warning(disable : 4255) +#endif + +#if _MSC_VER >= 1914 +// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable : 5045) +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(__clang__) && (__clang_major__ >= 4) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("clang loop unroll(disable)") \ + _Pragma("clang loop vectorize(disable)") + #define Z7_ATTRIB_NO_VECTORIZE +#elif defined(__GNUC__) && (__GNUC__ >= 5) \ + && (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610)) + #define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) + // __attribute__((optimize("no-unroll-loops"))); + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#elif defined(_MSC_VER) && (_MSC_VER >= 1920) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("loop( no_vector )") + #define Z7_ATTRIB_NO_VECTORIZE +#else + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + #define Z7_ATTRIB_NO_VECTORIZE +#endif + +#if defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1920) + #define Z7_PRAGMA_OPTIMIZE_FOR_CODE_SIZE _Pragma("optimize ( \"s\", on )") + #define Z7_PRAGMA_OPTIMIZE_DEFAULT _Pragma("optimize ( \"\", on )") +#else + #define Z7_PRAGMA_OPTIMIZE_FOR_CODE_SIZE + #define Z7_PRAGMA_OPTIMIZE_DEFAULT +#endif + + + +#if defined(MY_CPU_X86_OR_AMD64) && ( \ + defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5)) + #define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse"))) +#else + #define Z7_ATTRIB_NO_SSE +#endif + +#define Z7_ATTRIB_NO_VECTOR \ + Z7_ATTRIB_NO_VECTORIZE \ + Z7_ATTRIB_NO_SSE + + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // GCC is not good for __builtin_expect() + #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_unlikely [[unlikely]] + // #define Z7_likely [[likely]] +#else + #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600)) + +#if (Z7_CLANG_VERSION < 130000) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"") +#endif +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER #endif #define UNUSED_VAR(x) (void)x; diff -Nru 7zip-22.01+dfsg/C/CpuArch.c 7zip-22.01+really25.01+dfsg/C/CpuArch.c --- 7zip-22.01+dfsg/C/CpuArch.c 2021-07-13 09:10:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/CpuArch.c 2024-11-24 05:00:00.000000000 +0000 @@ -1,187 +1,357 @@ /* CpuArch.c -- CPU specific code -2021-07-13 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ #include "Precomp.h" +// #include + #include "CpuArch.h" #ifdef MY_CPU_X86_OR_AMD64 -#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) -#define USE_ASM +#undef NEED_CHECK_FOR_CPUID +#if !defined(MY_CPU_AMD64) +#define NEED_CHECK_FOR_CPUID #endif -#if !defined(USE_ASM) && _MSC_VER >= 1500 -#include -#endif +/* + cpuid instruction supports (subFunction) parameter in ECX, + that is used only with some specific (function) parameter values. + most functions use only (subFunction==0). +*/ +/* + __cpuid(): MSVC and GCC/CLANG use same function/macro name + but parameters are different. + We use MSVC __cpuid() parameters style for our z7_x86_cpuid() function. +*/ + +#if defined(__GNUC__) /* && (__GNUC__ >= 10) */ \ + || defined(__clang__) /* && (__clang_major__ >= 10) */ + +/* there was some CLANG/GCC compilers that have issues with + rbx(ebx) handling in asm blocks in -fPIC mode (__PIC__ is defined). + compiler's contains the macro __cpuid() that is similar to our code. + The history of __cpuid() changes in CLANG/GCC: + GCC: + 2007: it preserved ebx for (__PIC__ && __i386__) + 2013: it preserved rbx and ebx for __PIC__ + 2014: it doesn't preserves rbx and ebx anymore + we suppose that (__GNUC__ >= 5) fixed that __PIC__ ebx/rbx problem. + CLANG: + 2014+: it preserves rbx, but only for 64-bit code. No __PIC__ check. + Why CLANG cares about 64-bit mode only, and doesn't care about ebx (in 32-bit)? + Do we need __PIC__ test for CLANG or we must care about rbx even if + __PIC__ is not defined? +*/ + +#define ASM_LN "\n" + +#if defined(MY_CPU_AMD64) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + + /* "=&r" selects free register. It can select even rbx, if that register is free. + "=&D" for (RDI) also works, but the code can be larger with "=&D" + "2"(subFun) : 2 is (zero-based) index in the output constraint list "=c" (ECX). */ + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%rbx, %q1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%rbx, %q1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#elif defined(MY_CPU_X86) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%ebx, %k1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%ebx, %k1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } -#if defined(USE_ASM) && !defined(MY_CPU_AMD64) -static UInt32 CheckFlag(UInt32 flag) -{ - #ifdef _MSC_VER - __asm pushfd; - __asm pop EAX; - __asm mov EDX, EAX; - __asm xor EAX, flag; - __asm push EAX; - __asm popfd; - __asm pushfd; - __asm pop EAX; - __asm xor EAX, EDX; - __asm push EDX; - __asm popfd; - __asm and flag, EAX; - #else - __asm__ __volatile__ ( - "pushf\n\t" - "pop %%EAX\n\t" - "movl %%EAX,%%EDX\n\t" - "xorl %0,%%EAX\n\t" - "push %%EAX\n\t" - "popf\n\t" - "pushf\n\t" - "pop %%EAX\n\t" - "xorl %%EDX,%%EAX\n\t" - "push %%EDX\n\t" - "popf\n\t" - "andl %%EAX, %0\n\t": - "=c" (flag) : "c" (flag) : - "%eax", "%edx"); - #endif - return flag; -} -#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; #else -#define CHECK_CPUID_IS_SUPPORTED + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "cpuid" \ + : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + #endif -#ifndef USE_ASM - #ifdef _MSC_VER - #if _MSC_VER >= 1600 - #define MY__cpuidex __cpuidex - #else +#define x86_cpuid_MACRO(p, func) x86_cpuid_MACRO_2(p, func, 0) -/* - __cpuid (function == 4) requires subfunction number in ECX. - MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. - __cpuid() in new MSVC clears ECX. - __cpuid() in old MSVC (14.00) doesn't clear ECX - We still can use __cpuid for low (function) values that don't require ECX, - but __cpuid() in old MSVC will be incorrect for some function values: (function == 4). - So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, - where ECX value is first parameter for FAST_CALL / NO_INLINE function, - So the caller of MY__cpuidex_HACK() sets ECX as subFunction, and - old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. - - DON'T remove MY_NO_INLINE and MY_FAST_CALL for MY__cpuidex_HACK() !!! -*/ +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + x86_cpuid_MACRO(p, func) +} static -MY_NO_INLINE -void MY_FAST_CALL MY__cpuidex_HACK(UInt32 subFunction, int *CPUInfo, UInt32 function) +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) { - UNUSED_VAR(subFunction); - __cpuid(CPUInfo, function); + x86_cpuid_MACRO_2(p, func, subFunc) } - #define MY__cpuidex(info, func, func2) MY__cpuidex_HACK(func2, info, func) - #pragma message("======== MY__cpuidex_HACK WAS USED ========") - #endif - #else - #define MY__cpuidex(info, func, func2) __cpuid(info, func) - #pragma message("======== (INCORRECT ?) cpuid WAS USED ========") - #endif -#endif +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + UInt32 a; + __asm__ __volatile__ ( + ASM_LN "pushf" + ASM_LN "pushf" + ASM_LN "pop %0" + // ASM_LN "movl %0, %1" + // ASM_LN "xorl $0x200000, %0" + ASM_LN "btc %1, %0" + ASM_LN "push %0" + ASM_LN "popf" + ASM_LN "pushf" + ASM_LN "pop %0" + ASM_LN "xorl (%%esp), %0" + + ASM_LN "popf" + ASM_LN + : "=&r" (a) // "=a" + : "i" (EFALGS_CPUID_BIT) + ); + if ((a & (1 << EFALGS_CPUID_BIT)) == 0) + return 0; + #endif + { + UInt32 p[4]; + x86_cpuid_MACRO(p, 0) + return p[0]; + } +} +#undef ASM_LN +#elif !defined(_MSC_VER) -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) +/* +// for gcc/clang and other: we can try to use __cpuid macro: +#include +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) { - #ifdef USE_ASM - - #ifdef _MSC_VER + __cpuid(func, p[0], p[1], p[2], p[3]); +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return (UInt32)__get_cpuid_max(0, NULL); +} +*/ +// for unsupported cpuid: +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(func) + p[0] = p[1] = p[2] = p[3] = 0; +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return 0; +} - UInt32 a2, b2, c2, d2; - __asm xor EBX, EBX; - __asm xor ECX, ECX; - __asm xor EDX, EDX; - __asm mov EAX, function; - __asm cpuid; - __asm mov a2, EAX; - __asm mov b2, EBX; - __asm mov c2, ECX; - __asm mov d2, EDX; - - *a = a2; - *b = b2; - *c = c2; - *d = d2; +#else // _MSC_VER - #else +#if !defined(MY_CPU_AMD64) - __asm__ __volatile__ ( - #if defined(MY_CPU_AMD64) && defined(__PIC__) - "mov %%rbx, %%rdi;" - "cpuid;" - "xchg %%rbx, %%rdi;" - : "=a" (*a) , - "=D" (*b) , - #elif defined(MY_CPU_X86) && defined(__PIC__) - "mov %%ebx, %%edi;" - "cpuid;" - "xchgl %%ebx, %%edi;" - : "=a" (*a) , - "=D" (*b) , - #else - "cpuid" - : "=a" (*a) , - "=b" (*b) , +UInt32 __declspec(naked) Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + __asm pushfd + __asm pushfd + /* + __asm pop eax + // __asm mov edx, eax + __asm btc eax, EFALGS_CPUID_BIT + __asm push eax + */ + __asm btc dword ptr [esp], EFALGS_CPUID_BIT + __asm popfd + __asm pushfd + __asm pop eax + // __asm xor eax, edx + __asm xor eax, [esp] + // __asm push edx + __asm popfd + __asm and eax, (1 shl EFALGS_CPUID_BIT) + __asm jz end_func #endif - "=c" (*c) , - "=d" (*d) - : "0" (function), "c"(0) ) ; - + __asm push ebx + __asm xor eax, eax // func + __asm xor ecx, ecx // subFunction (optional) for (func == 0) + __asm cpuid + __asm pop ebx + #if defined(NEED_CHECK_FOR_CPUID) + end_func: #endif - - #else + __asm ret 0 +} - int CPUInfo[4]; +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm xor ecx, ecx // subfunction (optional) for (func == 0) + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 0 +} - MY__cpuidex(CPUInfo, (int)function, 0); +static +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + UNUSED_VAR(subFunc) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm mov ecx, [esp + 12] // subFunc + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 4 +} - *a = (UInt32)CPUInfo[0]; - *b = (UInt32)CPUInfo[1]; - *c = (UInt32)CPUInfo[2]; - *d = (UInt32)CPUInfo[3]; +#else // MY_CPU_AMD64 - #endif + #if _MSC_VER >= 1600 + #include + #define MY_cpuidex __cpuidex + +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + __cpuidex((int *)p, func, subFunc); } -BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p) + #else +/* + __cpuid (func == (0 or 7)) requires subfunction number in ECX. + MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. + __cpuid() in new MSVC clears ECX. + __cpuid() in old MSVC (14.00) x64 doesn't clear ECX + We still can use __cpuid for low (func) values that don't require ECX, + but __cpuid() in old MSVC will be incorrect for some func values: (func == 7). + So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, + where ECX value is first parameter for FASTCALL / NO_INLINE func. + So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and + old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. + +DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!! +*/ +static +Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int32 *CPUInfo) +{ + UNUSED_VAR(subFunction) + __cpuid(CPUInfo, func); +} + #define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info) + #pragma message("======== MY_cpuidex_HACK WAS USED ========") +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + MY_cpuidex_HACK(subFunc, func, (Int32 *)p); +} + #endif // _MSC_VER >= 1600 + +#if !defined(MY_CPU_AMD64) +/* inlining for __cpuid() in MSVC x86 (32-bit) produces big ineffective code, + so we disable inlining here */ +Z7_NO_INLINE +#endif +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + MY_cpuidex((Int32 *)p, (Int32)func, 0); +} + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + Int32 a[4]; + MY_cpuidex(a, 0, 0); + return a[0]; +} + +#endif // MY_CPU_AMD64 +#endif // _MSC_VER + +#if defined(NEED_CHECK_FOR_CPUID) +#define CHECK_CPUID_IS_SUPPORTED { if (z7_x86_cpuid_GetMaxFunc() == 0) return 0; } +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif +#undef NEED_CHECK_FOR_CPUID + + +static +BoolInt x86cpuid_Func_1(UInt32 *p) { CHECK_CPUID_IS_SUPPORTED - MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); - MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); + z7_x86_cpuid(p, 1); return True; } -static const UInt32 kVendors[][3] = +/* +static const UInt32 kVendors[][1] = +{ + { 0x756E6547 }, // , 0x49656E69, 0x6C65746E }, + { 0x68747541 }, // , 0x69746E65, 0x444D4163 }, + { 0x746E6543 } // , 0x48727561, 0x736C7561 } +}; +*/ + +/* +typedef struct { - { 0x756E6547, 0x49656E69, 0x6C65746E}, - { 0x68747541, 0x69746E65, 0x444D4163}, - { 0x746E6543, 0x48727561, 0x736C7561} + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA }; +int x86cpuid_GetFirm(const Cx86cpuid *p); +#define x86cpuid_ver_GetFamily(ver) (((ver >> 16) & 0xff0) | ((ver >> 8) & 0xf)) +#define x86cpuid_ver_GetModel(ver) (((ver >> 12) & 0xf0) | ((ver >> 4) & 0xf)) +#define x86cpuid_ver_GetStepping(ver) (ver & 0xf) int x86cpuid_GetFirm(const Cx86cpuid *p) { unsigned i; - for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[0]); i++) { const UInt32 *v = kVendors[i]; - if (v[0] == p->vendor[0] && - v[1] == p->vendor[1] && - v[2] == p->vendor[2]) + if (v[0] == p->vendor[0] + // && v[1] == p->vendor[1] + // && v[2] == p->vendor[2] + ) return (int)i; } return -1; @@ -190,41 +360,55 @@ BoolInt CPU_Is_InOrder() { Cx86cpuid p; - int firm; UInt32 family, model; if (!x86cpuid_CheckAndRead(&p)) return True; - family = x86cpuid_GetFamily(p.ver); - model = x86cpuid_GetModel(p.ver); - - firm = x86cpuid_GetFirm(&p); + family = x86cpuid_ver_GetFamily(p.ver); + model = x86cpuid_ver_GetModel(p.ver); - switch (firm) + switch (x86cpuid_GetFirm(&p)) { case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( - /* In-Order Atom CPU */ - model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ - || model == 0x26 /* 45 nm, Z6xx */ - || model == 0x27 /* 32 nm, Z2460 */ - || model == 0x35 /* 32 nm, Z2760 */ - || model == 0x36 /* 32 nm, N2xxx, D2xxx */ + // In-Order Atom CPU + model == 0x1C // 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 + || model == 0x26 // 45 nm, Z6xx + || model == 0x27 // 32 nm, Z2460 + || model == 0x35 // 32 nm, Z2760 + || model == 0x36 // 32 nm, N2xxx, D2xxx ))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); } - return True; + return False; // v23 : unknown processors are not In-Order } +*/ + +#ifdef _WIN32 +#include "7zWindows.h" +#endif #if !defined(MY_CPU_AMD64) && defined(_WIN32) -#include -static BoolInt CPU_Sys_Is_SSE_Supported() + +/* for legacy SSE ia32: there is no user-space cpu instruction to check + that OS supports SSE register storing/restoring on context switches. + So we need some OS-specific function to check that it's safe to use SSE registers. +*/ + +Z7_FORCE_INLINE +static BoolInt CPU_Sys_Is_SSE_Supported(void) { - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi)) - return False; - return (vi.dwMajorVersion >= 5); +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4996) // `GetVersion': was declared deprecated +#endif + /* low byte is major version of Windows + We suppose that any Windows version since + Windows2000 (major == 5) supports SSE registers */ + return (Byte)GetVersion() >= 5; +#if defined(_MSC_VER) + #pragma warning(pop) +#endif } #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; #else @@ -232,117 +416,364 @@ #endif -static UInt32 X86_CPUID_ECX_Get_Flags() +#if !defined(MY_CPU_AMD64) + +BoolInt CPU_IsSupported_CMOV(void) { - Cx86cpuid p; + UInt32 a[4]; + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 15) & 1; +} + +BoolInt CPU_IsSupported_SSE(void) +{ + UInt32 a[4]; CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSE2(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 26) & 1; +} + +#endif + + +static UInt32 x86cpuid_Func_1_ECX(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) return 0; - return p.c; + return a[2]; } -BoolInt CPU_IsSupported_AES() +BoolInt CPU_IsSupported_AES(void) { - return (X86_CPUID_ECX_Get_Flags() >> 25) & 1; + return (BoolInt)(x86cpuid_Func_1_ECX() >> 25) & 1; } -BoolInt CPU_IsSupported_SSSE3() +BoolInt CPU_IsSupported_SSSE3(void) { - return (X86_CPUID_ECX_Get_Flags() >> 9) & 1; + return (BoolInt)(x86cpuid_Func_1_ECX() >> 9) & 1; } -BoolInt CPU_IsSupported_SSE41() +BoolInt CPU_IsSupported_SSE41(void) { - return (X86_CPUID_ECX_Get_Flags() >> 19) & 1; + return (BoolInt)(x86cpuid_Func_1_ECX() >> 19) & 1; } -BoolInt CPU_IsSupported_SHA() +BoolInt CPU_IsSupported_SHA(void) { - Cx86cpuid p; CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) + + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + return (BoolInt)(d[1] >> 29) & 1; + } +} - if (p.maxFunc < 7) + +BoolInt CPU_IsSupported_SHA512(void) +{ + if (!CPU_IsSupported_AVX2()) return False; // maybe CPU_IsSupported_AVX() is enough here + + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); - return (d[1] >> 29) & 1; + UInt32 d[4]; + z7_x86_cpuid_subFunc(d, 7, 0); + if (d[0] < 1) // d[0] - is max supported subleaf value + return False; + z7_x86_cpuid_subFunc(d, 7, 1); + return (BoolInt)(d[0]) & 1; } } -// #include +/* +MSVC: _xgetbv() intrinsic is available since VS2010SP1. + MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in + that we can use or check. + For any 32-bit x86 we can use asm code in MSVC, + but MSVC asm code is huge after compilation. + So _xgetbv() is better + +ICC: _xgetbv() intrinsic is available (in what version of ICC?) + ICC defines (__GNUC___) and it supports gnu assembler + also ICC supports MASM style code with -use-msasm switch. + but ICC doesn't support __attribute__((__target__)) + +GCC/CLANG 9: + _xgetbv() is macro that works via __builtin_ia32_xgetbv() + and we need __attribute__((__target__("xsave")). + But with __target__("xsave") the function will be not + inlined to function that has no __target__("xsave") attribute. + If we want _xgetbv() call inlining, then we should use asm version + instead of calling _xgetbv(). + Note:intrinsic is broke before GCC 8.2: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684 +*/ -#ifdef _WIN32 -#include +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) \ + || defined(_MSC_VER) && (_MSC_VER >= 1600) && (_MSC_FULL_VER >= 160040219) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + || defined(__clang__) && (__clang_major__ >= 9) +// we define ATTRIB_XGETBV, if we want to use predefined _xgetbv() from compiler +#if defined(__INTEL_COMPILER) +#define ATTRIB_XGETBV +#elif defined(__GNUC__) || defined(__clang__) +// we don't define ATTRIB_XGETBV here, because asm version is better for inlining. +// #define ATTRIB_XGETBV __attribute__((__target__("xsave"))) +#else +#define ATTRIB_XGETBV +#endif +#endif + +#if defined(ATTRIB_XGETBV) +#include #endif -BoolInt CPU_IsSupported_AVX2() + +// XFEATURE_ENABLED_MASK/XCR0 +#define MY_XCR_XFEATURE_ENABLED_MASK 0 + +#if defined(ATTRIB_XGETBV) +ATTRIB_XGETBV +#endif +static UInt64 x86_xgetbv_0(UInt32 num) { - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT +#if defined(ATTRIB_XGETBV) + { + return + #if (defined(_MSC_VER)) + _xgetbv(num); + #else + __builtin_ia32_xgetbv( + #if !defined(__clang__) + (int) + #endif + num); + #endif + } + +#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC) + UInt32 a, d; + #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __asm__ + ( + "xgetbv" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #else // is old gcc + __asm__ + ( + ".byte 0x0f, 0x01, 0xd0" "\n\t" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #endif + return ((UInt64)d << 32) | a; + // return a; + +#elif defined(_MSC_VER) && !defined(MY_CPU_AMD64) + + UInt32 a, d; + __asm { + push eax + push edx + push ecx + mov ecx, num; + // xor ecx, ecx // = MY_XCR_XFEATURE_ENABLED_MASK + _emit 0x0f + _emit 0x01 + _emit 0xd0 + mov a, eax + mov d, edx + pop ecx + pop edx + pop eax + } + return ((UInt64)d << 32) | a; + // return a; + +#else // it's unknown compiler + // #error "Need xgetbv function" + UNUSED_VAR(num) + // for MSVC-X64 we could call external function from external file. + /* Actually we had checked OSXSAVE/AVX in cpuid before. + So it's expected that OS supports at least AVX and below. */ + // if (num != MY_XCR_XFEATURE_ENABLED_MASK) return 0; // if not XCR0 + return + // (1 << 0) | // x87 + (1 << 1) // SSE + | (1 << 2); // AVX + +#endif +} + +#ifdef _WIN32 +/* + Windows versions do not know about new ISA extensions that + can be introduced. But we still can use new extensions, + even if Windows doesn't report about supporting them, + But we can use new extensions, only if Windows knows about new ISA extension + that changes the number or size of registers: SSE, AVX/XSAVE, AVX512 + So it's enough to check + MY_PF_AVX_INSTRUCTIONS_AVAILABLE + instead of + MY_PF_AVX2_INSTRUCTIONS_AVAILABLE +*/ +#define MY_PF_XSAVE_ENABLED 17 +// #define MY_PF_SSSE3_INSTRUCTIONS_AVAILABLE 36 +// #define MY_PF_SSE4_1_INSTRUCTIONS_AVAILABLE 37 +// #define MY_PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38 +// #define MY_PF_AVX_INSTRUCTIONS_AVAILABLE 39 +// #define MY_PF_AVX2_INSTRUCTIONS_AVAILABLE 40 +// #define MY_PF_AVX512F_INSTRUCTIONS_AVAILABLE 41 +#endif + +BoolInt CPU_IsSupported_AVX(void) +{ #ifdef _WIN32 - #define MY__PF_XSAVE_ENABLED 17 - if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED)) + if (!IsProcessorFeaturePresent(MY_PF_XSAVE_ENABLED)) + return False; + /* PF_AVX_INSTRUCTIONS_AVAILABLE probably is supported starting from + some latest Win10 revisions. But we need AVX in older Windows also. + So we don't use the following check: */ + /* + if (!IsProcessorFeaturePresent(MY_PF_AVX_INSTRUCTIONS_AVAILABLE)) return False; + */ #endif - if (!x86cpuid_CheckAndRead(&p)) + /* + OS must use new special XSAVE/XRSTOR instructions to save + AVX registers when it required for context switching. + At OS statring: + OS sets CR4.OSXSAVE flag to signal the processor that OS supports the XSAVE extensions. + Also OS sets bitmask in XCR0 register that defines what + registers will be processed by XSAVE instruction: + XCR0.SSE[bit 0] - x87 registers and state + XCR0.SSE[bit 1] - SSE registers and state + XCR0.AVX[bit 2] - AVX registers and state + CR4.OSXSAVE is reflected to CPUID.1:ECX.OSXSAVE[bit 27]. + So we can read that bit in user-space. + XCR0 is available for reading in user-space by new XGETBV instruction. + */ + { + const UInt32 c = x86cpuid_Func_1_ECX(); + if (0 == (1 + & (c >> 28) // AVX instructions are supported by hardware + & (c >> 27))) // OSXSAVE bit: XSAVE and related instructions are enabled by OS. + return False; + } + + /* also we can check + CPUID.1:ECX.XSAVE [bit 26] : that shows that + XSAVE, XRESTOR, XSETBV, XGETBV instructions are supported by hardware. + But that check is redundant, because if OSXSAVE bit is set, then XSAVE is also set */ + + /* If OS have enabled XSAVE extension instructions (OSXSAVE == 1), + in most cases we expect that OS also will support storing/restoring + for AVX and SSE states at least. + But to be ensure for that we call user-space instruction + XGETBV(0) to get XCR0 value that contains bitmask that defines + what exact states(registers) OS have enabled for storing/restoring. + */ + + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 1) // SSE state is supported (set by OS) for storing/restoring + & (BoolInt)(bm >> 2); // AVX state is supported (set by OS) for storing/restoring + } + // since Win7SP1: we can use GetEnabledXStateFeatures(); +} + + +BoolInt CPU_IsSupported_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) return False; - if (p.maxFunc < 7) + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 7); // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); return 1 - & (d[1] >> 5); // avx2 + & (BoolInt)(d[1] >> 5); // avx2 } } -BoolInt CPU_IsSupported_VAES_AVX2() +#if 0 +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void) { - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT - - #ifdef _WIN32 - #define MY__PF_XSAVE_ENABLED 17 - if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED)) + if (!CPU_IsSupported_AVX()) return False; - #endif + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + BoolInt v; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + v = 1 + & (BoolInt)(d[1] >> 16) // avx512f + & (BoolInt)(d[1] >> 31); // avx512vl + if (!v) + return False; + } + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 5) // OPMASK + & (BoolInt)(bm >> 6) // ZMM upper 256-bit + & (BoolInt)(bm >> 7); // ZMM16 ... ZMM31 + } +} +#endif - if (!x86cpuid_CheckAndRead(&p)) +BoolInt CPU_IsSupported_VAES_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) return False; - if (p.maxFunc < 7) + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 7); // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); return 1 - & (d[1] >> 5) // avx2 + & (BoolInt)(d[1] >> 5) // avx2 // & (d[1] >> 31) // avx512vl - & (d[2] >> 9); // vaes // VEX-256/EVEX + & (BoolInt)(d[2] >> 9); // vaes // VEX-256/EVEX } } -BoolInt CPU_IsSupported_PageGB() +BoolInt CPU_IsSupported_PageGB(void) { - Cx86cpuid cpuid; - if (!x86cpuid_CheckAndRead(&cpuid)) - return False; + CHECK_CPUID_IS_SUPPORTED { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 0x80000000); if (d[0] < 0x80000001) return False; - } - { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]); - return (d[3] >> 26) & 1; + z7_x86_cpuid(d, 0x80000001); + return (BoolInt)(d[3] >> 26) & 1; } } @@ -351,11 +782,11 @@ #ifdef _WIN32 -#include +#include "7zWindows.h" -BoolInt CPU_IsSupported_CRC32() { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } -BoolInt CPU_IsSupported_CRYPTO() { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } -BoolInt CPU_IsSupported_NEON() { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRC32(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRYPTO(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_NEON(void) { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } #else @@ -378,29 +809,40 @@ } } */ +/* + Print_sysctlbyname("hw.pagesize"); + Print_sysctlbyname("machdep.cpu.brand_string"); +*/ -static BoolInt My_sysctlbyname_Get_BoolInt(const char *name) +static BoolInt z7_sysctlbyname_Get_BoolInt(const char *name) { UInt32 val = 0; - if (My_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) + if (z7_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) return 1; return 0; } - /* - Print_sysctlbyname("hw.pagesize"); - Print_sysctlbyname("machdep.cpu.brand_string"); - */ - BoolInt CPU_IsSupported_CRC32(void) { - return My_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); } BoolInt CPU_IsSupported_NEON(void) { - return My_sysctlbyname_Get_BoolInt("hw.optional.neon"); + return z7_sysctlbyname_Get_BoolInt("hw.optional.neon"); +} + +BoolInt CPU_IsSupported_SHA512(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha512"); +} + +/* +BoolInt CPU_IsSupported_SHA3(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha3"); } +*/ #ifdef MY_CPU_ARM64 #define APPLE_CRYPTO_SUPPORT_VAL 1 @@ -415,33 +857,70 @@ #else // __APPLE__ -#include +#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216) + #define Z7_GETAUXV_AVAILABLE +#else +// #pragma message("=== is not NEW GLIBC === ") + #if defined __has_include + #if __has_include () +// #pragma message("=== sys/auxv.h is avail=== ") + #define Z7_GETAUXV_AVAILABLE + #endif + #endif +#endif +#ifdef Z7_GETAUXV_AVAILABLE +// #pragma message("=== Z7_GETAUXV_AVAILABLE === ") +#include #define USE_HWCAP +#endif #ifdef USE_HWCAP +#if defined(__FreeBSD__) +static unsigned long MY_getauxval(int aux) +{ + unsigned long val; + if (elf_aux_info(aux, &val, sizeof(val))) + return 0; + return val; +} +#else +#define MY_getauxval getauxval + #if defined __has_include + #if __has_include () #include + #endif + #endif +#endif #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \ - BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; } + BoolInt CPU_IsSupported_ ## name1(void) { return (MY_getauxval(AT_HWCAP) & (HWCAP_ ## name2)); } #ifdef MY_CPU_ARM64 #define MY_HWCAP_CHECK_FUNC(name) \ MY_HWCAP_CHECK_FUNC_2(name, name) +#if 1 || defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD) +#endif // MY_HWCAP_CHECK_FUNC (ASIMD) #elif defined(MY_CPU_ARM) #define MY_HWCAP_CHECK_FUNC(name) \ - BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; } + BoolInt CPU_IsSupported_ ## name(void) { return (MY_getauxval(AT_HWCAP2) & (HWCAP2_ ## name)); } MY_HWCAP_CHECK_FUNC_2(NEON, NEON) #endif #else // USE_HWCAP #define MY_HWCAP_CHECK_FUNC(name) \ - BoolInt CPU_IsSupported_ ## name() { return 0; } + BoolInt CPU_IsSupported_ ## name(void) { return 0; } +#if defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else MY_HWCAP_CHECK_FUNC(NEON) +#endif #endif // USE_HWCAP @@ -449,6 +928,19 @@ MY_HWCAP_CHECK_FUNC (SHA1) MY_HWCAP_CHECK_FUNC (SHA2) MY_HWCAP_CHECK_FUNC (AES) +#ifdef MY_CPU_ARM64 +// supports HWCAP_SHA512 and HWCAP_SHA3 since 2017. +// we define them here, if they are not defined +#ifndef HWCAP_SHA3 +// #define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SHA512 +// #pragma message("=== HWCAP_SHA512 define === ") +#define HWCAP_SHA512 (1 << 21) +#endif +MY_HWCAP_CHECK_FUNC (SHA512) +// MY_HWCAP_CHECK_FUNC (SHA3) +#endif #endif // __APPLE__ #endif // _WIN32 @@ -461,15 +953,15 @@ #include -int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) { return sysctlbyname(name, buf, bufSize, NULL, 0); } -int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) { size_t bufSize = sizeof(*val); - int res = My_sysctlbyname_Get(name, val, &bufSize); + const int res = z7_sysctlbyname_Get(name, val, &bufSize); if (res == 0 && bufSize != sizeof(*val)) return EFAULT; return res; diff -Nru 7zip-22.01+dfsg/C/CpuArch.h 7zip-22.01+really25.01+dfsg/C/CpuArch.h --- 7zip-22.01+dfsg/C/CpuArch.h 2022-07-15 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/CpuArch.h 2025-04-05 08:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* CpuArch.h -- CPU specific code -2022-07-15 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H +#ifndef ZIP7_INC_CPU_ARCH_H +#define ZIP7_INC_CPU_ARCH_H #include "7zTypes.h" @@ -20,6 +20,7 @@ MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8) */ +#if !defined(_M_ARM64EC) #if defined(_M_X64) \ || defined(_M_AMD64) \ || defined(__x86_64__) \ @@ -35,6 +36,7 @@ #endif #define MY_CPU_64BIT #endif +#endif #if defined(_M_IX86) \ @@ -45,13 +47,34 @@ #define MY_CPU_SIZEOF_POINTER 4 #endif +#if defined(__SSE2__) \ + || defined(MY_CPU_AMD64) \ + || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) +#define MY_CPU_SSE2 +#endif + #if defined(_M_ARM64) \ + || defined(_M_ARM64EC) \ || defined(__AARCH64EL__) \ || defined(__AARCH64EB__) \ || defined(__aarch64__) #define MY_CPU_ARM64 - #define MY_CPU_NAME "arm64" +#if defined(__ILP32__) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "arm64-32" + #define MY_CPU_SIZEOF_POINTER 4 +#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) + #define MY_CPU_NAME "arm64-128" + #define MY_CPU_SIZEOF_POINTER 16 +#else +#if defined(_M_ARM64EC) + #define MY_CPU_NAME "arm64ec" +#else + #define MY_CPU_NAME "arm64" +#endif + #define MY_CPU_SIZEOF_POINTER 8 +#endif #define MY_CPU_64BIT #endif @@ -68,8 +91,10 @@ #define MY_CPU_ARM #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT) + #define MY_CPU_ARMT #define MY_CPU_NAME "armt" #else + #define MY_CPU_ARM32 #define MY_CPU_NAME "arm" #endif /* #define MY_CPU_32BIT */ @@ -103,6 +128,8 @@ || defined(__PPC__) \ || defined(_POWER) +#define MY_CPU_PPC_OR_PPC64 + #if defined(__ppc64__) \ || defined(__powerpc64__) \ || defined(_LP64) \ @@ -123,8 +150,36 @@ #endif +#if defined(__sparc__) \ + || defined(__sparc) + #define MY_CPU_SPARC + #if defined(__LP64__) \ + || defined(_LP64) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_NAME "sparcv9" + #define MY_CPU_SIZEOF_POINTER 8 + #define MY_CPU_64BIT + #elif defined(__sparc_v9__) \ + || defined(__sparcv9) + #define MY_CPU_64BIT + #if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "sparcv9-32" + #else + #define MY_CPU_NAME "sparcv9m" + #endif + #elif defined(__sparc_v8__) \ + || defined(__sparcv8) + #define MY_CPU_NAME "sparcv8" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "sparc" + #endif +#endif + + #if defined(__riscv) \ || defined(__riscv__) + #define MY_CPU_RISCV #if __riscv_xlen == 32 #define MY_CPU_NAME "riscv32" #elif __riscv_xlen == 64 @@ -135,6 +190,39 @@ #endif +#if defined(__loongarch__) + #define MY_CPU_LOONGARCH + #if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64) + #define MY_CPU_64BIT + #endif + #if defined(__loongarch64) + #define MY_CPU_NAME "loongarch64" + #define MY_CPU_LOONGARCH64 + #else + #define MY_CPU_NAME "loongarch" + #endif +#endif + + +// #undef MY_CPU_NAME +// #undef MY_CPU_SIZEOF_POINTER +// #define __e2k__ +// #define __SIZEOF_POINTER__ 4 +#if defined(__e2k__) + #define MY_CPU_E2K + #if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "e2k-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "e2k" + #if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #endif + #define MY_CPU_64BIT +#endif + + #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #define MY_CPU_X86_OR_AMD64 #endif @@ -165,6 +253,7 @@ || defined(MY_CPU_ARM_LE) \ || defined(MY_CPU_ARM64_LE) \ || defined(MY_CPU_IA64_LE) \ + || defined(_LITTLE_ENDIAN) \ || defined(__LITTLE_ENDIAN__) \ || defined(__ARMEL__) \ || defined(__THUMBEL__) \ @@ -197,6 +286,9 @@ #error Stop_Compiling_Bad_Endian #endif +#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE) + #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time +#endif #if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) #error Stop_Compiling_Bad_32_64_BIT @@ -238,6 +330,7 @@ #ifndef MY_CPU_NAME + // #define MY_CPU_IS_UNKNOWN #ifdef MY_CPU_LE #define MY_CPU_NAME "LE" #elif defined(MY_CPU_BE) @@ -253,15 +346,121 @@ +#ifdef __has_builtin + #define Z7_has_builtin(x) __has_builtin(x) +#else + #define Z7_has_builtin(x) 0 +#endif + + +#define Z7_BSWAP32_CONST(v) \ + ( (((UInt32)(v) << 24) ) \ + | (((UInt32)(v) << 8) & (UInt32)0xff0000) \ + | (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \ + | (((UInt32)(v) >> 24) )) + + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + +#include + +/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */ + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +#define Z7_BSWAP16(v) _byteswap_ushort(v) +#define Z7_BSWAP32(v) _byteswap_ulong (v) +#define Z7_BSWAP64(v) _byteswap_uint64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +/* GCC can generate slow code that calls function for __builtin_bswap32() for: + - GCC for RISCV, if Zbb/XTHeadBb extension is not used. + - GCC for SPARC. + The code from CLANG for SPARC also is not fastest. + So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases. +*/ +#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \ + && !defined(MY_CPU_SPARC) \ + && ( \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \ + ) + +#define Z7_BSWAP16(v) __builtin_bswap16(v) +#define Z7_BSWAP32(v) __builtin_bswap32(v) +#define Z7_BSWAP64(v) __builtin_bswap64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +#else + +#define Z7_BSWAP16(v) ((UInt16) \ + ( ((UInt32)(v) << 8) \ + | ((UInt32)(v) >> 8) \ + )) + +#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v) + +#define Z7_BSWAP64(v) \ + ( ( ( (UInt64)(v) ) << 8 * 7 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \ + | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \ + | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \ + | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \ + | ( ( (UInt64)(v) >> 8 * 7 ) ) \ + ) + +#endif + + + #ifdef MY_CPU_LE #if defined(MY_CPU_X86_OR_AMD64) \ - || defined(MY_CPU_ARM64) + || defined(MY_CPU_ARM64) \ + || defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \ + || defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6) #define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN_64 #elif defined(__ARM_FEATURE_UNALIGNED) - /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment. - So we can't use unaligned 64-bit operations. */ - #define MY_CPU_LE_UNALIGN +/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions. + Description of problems: +problem-1 : 32-bit ARM architecture: + multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM) + require 32-bit (WORD) alignment (by 32-bit ARM architecture). + So there is "Alignment fault exception", if data is not aligned for 32-bit. + +problem-2 : 32-bit kernels and arm64 kernels: + 32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception". + So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux. + + But some arm64 kernels do not handle these faults in 32-bit programs. + So we have unhandled exception for such instructions. + Probably some new arm64 kernels have fixed it, and unaligned + paired-access instructions work in new kernels? + +problem-3 : compiler for 32-bit arm: + Compilers use LDRD/STRD/LDM/STM for UInt64 accesses + and for another cases where two 32-bit accesses are fused + to one multi-access instruction. + So UInt64 variables must be aligned for 32-bit, and each + 32-bit access must be aligned for 32-bit, if we want to + avoid "Alignment fault" exception (handled or unhandled). + +problem-4 : performace: + Even if unaligned access is handled by kernel, it will be slow. + So if we allow unaligned access, we can get fast unaligned + single-access, and slow unaligned paired-access. + + We don't allow unaligned access on 32-bit arm, because compiler + genarates paired-access instructions that require 32-bit alignment, + and some arm64 kernels have no handler for these instructions. + Also unaligned paired-access instructions will be slow, if kernel handles them. +*/ + // it must be disabled: + // #define MY_CPU_LE_UNALIGN #endif #endif @@ -272,13 +471,11 @@ #define GetUi32(p) (*(const UInt32 *)(const void *)(p)) #ifdef MY_CPU_LE_UNALIGN_64 #define GetUi64(p) (*(const UInt64 *)(const void *)(p)) +#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } #endif #define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); } #define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); } -#ifdef MY_CPU_LE_UNALIGN_64 -#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } -#endif #else @@ -305,50 +502,33 @@ #endif -#ifndef MY_CPU_LE_UNALIGN_64 - +#ifndef GetUi64 #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#endif +#ifndef SetUi64 #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ - SetUi32(_ppp2_ , (UInt32)_vvv2_); \ - SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } - + SetUi32(_ppp2_ , (UInt32)_vvv2_) \ + SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) } #endif +#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) - -#ifdef __has_builtin - #define MY__has_builtin(x) __has_builtin(x) +#if 0 +// Z7_BSWAP16 can be slow for x86-msvc +#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p))) #else - #define MY__has_builtin(x) 0 +#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16) #endif -#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ defined(_MSC_VER) && (_MSC_VER >= 1300) - -/* Note: we use bswap instruction, that is unsupported in 386 cpu */ +#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p)) +#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); } -#include - -#pragma intrinsic(_byteswap_ushort) -#pragma intrinsic(_byteswap_ulong) -#pragma intrinsic(_byteswap_uint64) - -/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */ -#define GetBe32(p) _byteswap_ulong (*(const UInt32 *)(const void *)(p)) -#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const void *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) - -#elif defined(MY_CPU_LE_UNALIGN) && ( \ - (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ - || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) ) - -/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const void *)(p)) */ -#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const void *)(p)) -#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const void *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) +#if defined(MY_CPU_LE_UNALIGN_64) +#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p)) +#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); } +#endif #else @@ -358,8 +538,6 @@ ((UInt32)((const Byte *)(p))[2] << 8) | \ ((const Byte *)(p))[3] ) -#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) - #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ _ppp_[0] = (Byte)(_vvv_ >> 24); \ _ppp_[1] = (Byte)(_vvv_ >> 16); \ @@ -368,53 +546,115 @@ #endif +#ifndef GetBe64 +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) +#endif -#ifndef GetBe16 +#ifndef SetBe64 +#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 56); \ + _ppp_[1] = (Byte)(_vvv_ >> 48); \ + _ppp_[2] = (Byte)(_vvv_ >> 40); \ + _ppp_[3] = (Byte)(_vvv_ >> 32); \ + _ppp_[4] = (Byte)(_vvv_ >> 24); \ + _ppp_[5] = (Byte)(_vvv_ >> 16); \ + _ppp_[6] = (Byte)(_vvv_ >> 8); \ + _ppp_[7] = (Byte)_vvv_; } +#endif +#ifndef GetBe16 +#ifdef GetBe16_to32 +#define GetBe16(p) ( (UInt16) GetBe16_to32(p)) +#else #define GetBe16(p) ( (UInt16) ( \ ((UInt16)((const Byte *)(p))[0] << 8) | \ ((const Byte *)(p))[1] )) +#endif +#endif + +#if defined(MY_CPU_BE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_NATIVE_TO_BE_32(v) (v) +// #define Z7_GET_NATIVE16_FROM_2_BYTES(b0, b1) ((b1) | ((b0) << 8)) +#elif defined(MY_CPU_LE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v) +// #define Z7_GET_NATIVE16_FROM_2_BYTES(b0, b1) ((b0) | ((b1) << 8)) +#else +#error Stop_Compiling_Unknown_Endian_CONV #endif +#if defined(MY_CPU_BE) -#ifdef MY_CPU_X86_OR_AMD64 +#define GetBe64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetBe32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetBe16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetUi64a(p) GetUi64(p) +#define GetUi32a(p) GetUi32(p) +#define GetUi16a(p) GetUi16(p) +#define SetUi32a(p, v) SetUi32(p, v) +#define SetUi16a(p, v) SetUi16(p, v) + +#elif defined(MY_CPU_LE) + +#define GetUi64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetUi32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetBe64a(p) GetBe64(p) +#define GetBe32a(p) GetBe32(p) +#define GetBe16a(p) GetBe16(p) +#define SetBe32a(p, v) SetBe32(p, v) +#define SetBe16a(p, v) SetBe16(p, v) -typedef struct -{ - UInt32 maxFunc; - UInt32 vendor[3]; - UInt32 ver; - UInt32 b; - UInt32 c; - UInt32 d; -} Cx86cpuid; - -enum -{ - CPU_FIRM_INTEL, - CPU_FIRM_AMD, - CPU_FIRM_VIA -}; - -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); - -BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p); -int x86cpuid_GetFirm(const Cx86cpuid *p); - -#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) -#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF)) -#define x86cpuid_GetStepping(ver) (ver & 0xF) +#else +#error Stop_Compiling_Unknown_Endian_CPU_a +#endif + + +#ifndef GetBe16_to32 +#define GetBe16_to32(p) GetBe16(p) +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_OR_ARM64) \ + || defined(MY_CPU_PPC_OR_PPC64) + #define Z7_CPU_FAST_ROTATE_SUPPORTED +#endif -BoolInt CPU_Is_InOrder(void); + +#ifdef MY_CPU_X86_OR_AMD64 + +void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function); +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void); +#if defined(MY_CPU_AMD64) +#define Z7_IF_X86_CPUID_SUPPORTED +#else +#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc()) +#endif BoolInt CPU_IsSupported_AES(void); +BoolInt CPU_IsSupported_AVX(void); BoolInt CPU_IsSupported_AVX2(void); +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void); BoolInt CPU_IsSupported_VAES_AVX2(void); +BoolInt CPU_IsSupported_CMOV(void); +BoolInt CPU_IsSupported_SSE(void); +BoolInt CPU_IsSupported_SSE2(void); BoolInt CPU_IsSupported_SSSE3(void); BoolInt CPU_IsSupported_SSE41(void); BoolInt CPU_IsSupported_SHA(void); +BoolInt CPU_IsSupported_SHA512(void); BoolInt CPU_IsSupported_PageGB(void); #elif defined(MY_CPU_ARM_OR_ARM64) @@ -432,12 +672,13 @@ BoolInt CPU_IsSupported_SHA2(void); BoolInt CPU_IsSupported_AES(void); #endif +BoolInt CPU_IsSupported_SHA512(void); #endif #if defined(__APPLE__) -int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); -int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); #endif EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Delta.h 7zip-22.01+really25.01+dfsg/C/Delta.h --- 7zip-22.01+dfsg/C/Delta.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Delta.h 2023-03-03 10:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Delta.h -- Delta converter -2013-01-18 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __DELTA_H -#define __DELTA_H +#ifndef ZIP7_INC_DELTA_H +#define ZIP7_INC_DELTA_H #include "7zTypes.h" diff -Nru 7zip-22.01+dfsg/C/DllSecur.c 7zip-22.01+really25.01+dfsg/C/DllSecur.c --- 7zip-22.01+dfsg/C/DllSecur.c 2022-07-15 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/DllSecur.c 2023-12-03 18:00:00.000000000 +0000 @@ -1,114 +1,99 @@ /* DllSecur.c -- DLL loading security -2022-07-15 : Igor Pavlov : Public domain */ +2023-12-03 : Igor Pavlov : Public domain */ #include "Precomp.h" #ifdef _WIN32 -#include +#include "7zWindows.h" #include "DllSecur.h" #ifndef UNDER_CE -#if defined(__GNUC__) && (__GNUC__ >= 8) - #pragma GCC diagnostic ignored "-Wcast-function-type" -#endif +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags); #define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400 #define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 +#define DELIM "\0" + static const char * const g_Dlls = + "userenv" + DELIM "setupapi" + DELIM "apphelp" + DELIM "propsys" + DELIM "dwmapi" + DELIM "cryptbase" + DELIM "oleacc" + DELIM "clbcatq" + DELIM "version" #ifndef _CONSOLE - "UXTHEME\0" + DELIM "uxtheme" #endif - "USERENV\0" - "SETUPAPI\0" - "APPHELP\0" - "PROPSYS\0" - "DWMAPI\0" - "CRYPTBASE\0" - "OLEACC\0" - "CLBCATQ\0" - "VERSION\0" - ; + DELIM; + +#endif +#ifdef __clang__ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#if defined (_MSC_VER) && _MSC_VER >= 1900 +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) #endif -// #define MY_CAST_FUNC (void(*)()) -#define MY_CAST_FUNC +#define IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN \ + if ((UInt16)GetVersion() != 6) { \ + const \ + Func_SetDefaultDllDirectories setDllDirs = \ + (Func_SetDefaultDllDirectories) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), \ + "SetDefaultDllDirectories"); \ + if (setDllDirs) if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) return; } -void My_SetDefaultDllDirectories() +void My_SetDefaultDllDirectories(void) { #ifndef UNDER_CE - - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) - { - Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) - MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); - if (setDllDirs) - if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) - return; - } - + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN #endif } -void LoadSecurityDlls() +void LoadSecurityDlls(void) { #ifndef UNDER_CE - - wchar_t buf[MAX_PATH + 100]; - - { - // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) - { - Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) - MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); - if (setDllDirs) - if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) - return; - } - } - - { - unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2); - if (len == 0 || len > MAX_PATH) - return; - } + // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN { + wchar_t buf[MAX_PATH + 100]; const char *dll; - unsigned pos = (unsigned)lstrlenW(buf); - + unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2); + if (pos == 0 || pos > MAX_PATH) + return; if (buf[pos - 1] != '\\') buf[pos++] = '\\'; - - for (dll = g_Dlls; dll[0] != 0;) + for (dll = g_Dlls; *dll != 0;) { - unsigned k = 0; + wchar_t *dest = &buf[pos]; for (;;) { - char c = *dll++; - buf[pos + k] = (Byte)c; - k++; + const char c = *dll++; if (c == 0) break; + *dest++ = (Byte)c; } - - lstrcatW(buf, L".dll"); + dest[0] = '.'; + dest[1] = 'd'; + dest[2] = 'l'; + dest[3] = 'l'; + dest[4] = 0; + // lstrcatW(buf, L".dll"); LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); } } - #endif } -#endif +#endif // _WIN32 diff -Nru 7zip-22.01+dfsg/C/DllSecur.h 7zip-22.01+really25.01+dfsg/C/DllSecur.h --- 7zip-22.01+dfsg/C/DllSecur.h 2021-01-22 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/DllSecur.h 2023-03-03 10:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* DllSecur.h -- DLL loading for security -2018-02-19 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __DLL_SECUR_H -#define __DLL_SECUR_H +#ifndef ZIP7_INC_DLL_SECUR_H +#define ZIP7_INC_DLL_SECUR_H #include "7zTypes.h" diff -Nru 7zip-22.01+dfsg/C/HuffEnc.c 7zip-22.01+really25.01+dfsg/C/HuffEnc.c --- 7zip-22.01+dfsg/C/HuffEnc.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/HuffEnc.c 2025-03-20 14:00:00.000000000 +0000 @@ -1,60 +1,125 @@ /* HuffEnc.c -- functions for Huffman encoding -2021-02-09 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ #include "Precomp.h" +#include + #include "HuffEnc.h" #include "Sort.h" +#include "CpuArch.h" -#define kMaxLen 16 -#define NUM_BITS 10 -#define MASK (((unsigned)1 << NUM_BITS) - 1) - -#define NUM_COUNTERS 64 - -#define HUFFMAN_SPEED_OPT +#define kMaxLen Z7_HUFFMAN_LEN_MAX +#define NUM_BITS 10 +#define MASK ((1u << NUM_BITS) - 1) +#define FREQ_MASK (~(UInt32)MASK) +#define NUM_COUNTERS (48 * 2) + +#if 1 && (defined(MY_CPU_LE) || defined(MY_CPU_BE)) +#if defined(MY_CPU_LE) + #define HI_HALF_OFFSET 1 +#else + #define HI_HALF_OFFSET 0 +#endif +#define LOAD_PARENT(p) ((unsigned)*((const UInt16 *)(p) + HI_HALF_OFFSET)) +#define STORE_PARENT(p, fb, val) *((UInt16 *)(p) + HI_HALF_OFFSET) = (UInt16)(val); +#define STORE_PARENT_DIRECT(p, fb, hi) STORE_PARENT(p, fb, hi) +#define UPDATE_E(eHi) eHi++; +#else +#define LOAD_PARENT(p) ((unsigned)(*(p) >> NUM_BITS)) +#define STORE_PARENT_DIRECT(p, fb, hi) *(p) = ((fb) & MASK) | (hi); // set parent field +#define STORE_PARENT(p, fb, val) STORE_PARENT_DIRECT(p, fb, ((UInt32)(val) << NUM_BITS)) +#define UPDATE_E(eHi) eHi += 1 << NUM_BITS; +#endif -void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen) +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, unsigned numSymbols, unsigned maxLen) { - UInt32 num = 0; - /* if (maxLen > 10) maxLen = 10; */ +#if NUM_COUNTERS > 2 + unsigned counters[NUM_COUNTERS]; +#endif +#if 1 && NUM_COUNTERS > (kMaxLen + 4) * 2 + #define lenCounters (counters) + #define codes (counters + kMaxLen + 4) +#else + unsigned lenCounters[kMaxLen + 1]; + UInt32 codes[kMaxLen + 1]; +#endif + + unsigned num; { - UInt32 i; - - #ifdef HUFFMAN_SPEED_OPT + unsigned i; + // UInt32 sum = 0; + +#if NUM_COUNTERS > 2 - UInt32 counters[NUM_COUNTERS]; +#define CTR_ITEM_FOR_FREQ(freq) \ + counters[(freq) >= NUM_COUNTERS - 1 ? NUM_COUNTERS - 1 : (unsigned)(freq)] + for (i = 0; i < NUM_COUNTERS; i++) counters[i] = 0; - for (i = 0; i < numSymbols; i++) + memset(lens, 0, numSymbols); { - UInt32 freq = freqs[i]; - counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++; + const UInt32 *fp = freqs + numSymbols; +#define NUM_UNROLLS 1 +#if NUM_UNROLLS > 1 // use 1 if odd (numSymbols) is possisble + if (numSymbols & 1) + { + UInt32 f; + f = *--fp; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; + } +#endif + do + { + UInt32 f; + fp -= NUM_UNROLLS; + f = fp[0]; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; +#if NUM_UNROLLS > 1 + f = fp[1]; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; +#endif + } + while (fp != freqs); } - - for (i = 1; i < NUM_COUNTERS; i++) +#if 0 + printf("\nsum=%8u numSymbols =%3u ctrs:", sum, numSymbols); { - UInt32 temp = counters[i]; - counters[i] = num; - num += temp; + unsigned k = 0; + for (k = 0; k < NUM_COUNTERS; k++) + printf(" %u", counters[k]); } - - for (i = 0; i < numSymbols; i++) +#endif + + num = counters[1]; + counters[1] = 0; + for (i = 2; i != NUM_COUNTERS; i += 2) { - UInt32 freq = freqs[i]; - if (freq == 0) - lens[i] = 0; - else - p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS); + unsigned c; + c = (counters )[i]; (counters )[i] = num; num += c; + c = (counters + 1)[i]; (counters + 1)[i] = num; num += c; + } + counters[0] = num; // we want to write (freq==0) symbols to the end of (p) array + { + i = 0; + do + { + const UInt32 f = freqs[i]; +#if 0 + if (f == 0) lens[i] = 0; else +#endif + p[CTR_ITEM_FOR_FREQ(f)++] = i | (f << NUM_BITS); + } + while (++i != numSymbols); } - counters[0] = 0; HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]); - #else - +#else // NUM_COUNTERS <= 2 + + num = 0; for (i = 0; i < numSymbols; i++) { - UInt32 freq = freqs[i]; + const UInt32 freq = freqs[i]; if (freq == 0) lens[i] = 0; else @@ -62,17 +127,27 @@ } HeapSort(p, num); - #endif +#endif } - if (num < 2) + if (num <= 2) { unsigned minCode = 0; unsigned maxCode = 1; - if (num == 1) + if (num) { - maxCode = (unsigned)p[0] & MASK; - if (maxCode == 0) + maxCode = (unsigned)p[(size_t)num - 1] & MASK; + if (num == 2) + { + minCode = (unsigned)p[0] & MASK; + if (minCode > maxCode) + { + const unsigned temp = minCode; + minCode = maxCode; + maxCode = temp; + } + } + else if (maxCode == 0) maxCode++; } p[minCode] = 0; @@ -80,69 +155,206 @@ lens[minCode] = lens[maxCode] = 1; return; } - { - UInt32 b, e, i; - - i = b = e = 0; - do - { - UInt32 n, m, freq; - n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; - freq = (p[n] & ~MASK); - p[n] = (p[n] & MASK) | (e << NUM_BITS); - m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; - freq += (p[m] & ~MASK); - p[m] = (p[m] & MASK) | (e << NUM_BITS); - p[e] = (p[e] & MASK) | freq; - e++; - } - while (num - e > 1); - + unsigned i; + for (i = 0; i <= kMaxLen; i++) + lenCounters[i] = 0; + lenCounters[1] = 2; // by default root node has 2 child leaves at level 1. + } + // if (num != 2) + { + // num > 2 + // the binary tree will contain (num - 1) internal nodes. + // p[num - 2] will be root node of binary tree. + UInt32 *b; + UInt32 *n; + // first node will have two leaf childs: p[0] and p[1]: + // p[0] += p[1] & FREQ_MASK; // set frequency sum of child leafs + // if (pi == n) exit(0); + // if (pi != n) { - UInt32 lenCounters[kMaxLen + 1]; - for (i = 0; i <= kMaxLen; i++) - lenCounters[i] = 0; - - p[--e] &= MASK; - lenCounters[1] = 2; - while (e > 0) - { - UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1; - p[e] = (p[e] & MASK) | (len << NUM_BITS); - if (len >= maxLen) - for (len = maxLen - 1; lenCounters[len] == 0; len--); - lenCounters[len]--; - lenCounters[(size_t)len + 1] += 2; - } - + UInt32 fb = (p[1] & FREQ_MASK) + p[0]; + UInt32 f = p[2] & FREQ_MASK; + const UInt32 *pi = p + 2; + UInt32 *e = p; + UInt32 eHi = 0; + n = p + num; + b = p; + // p[0] = fb; + for (;;) { - UInt32 len; - i = 0; - for (len = maxLen; len != 0; len--) + // (b <= e) + UInt32 sum; + e++; + UPDATE_E(eHi) + + // (b < e) + + // p range : high bits + // [0, b) : parent : processed nodes that have parent and childs + // [b, e) : FREQ : non-processed nodes that have no parent but have childs + // [e, pi) : FREQ : processed leaves for which parent node was created + // [pi, n) : FREQ : non-processed leaves for which parent node was not created + + // first child + // note : (*b < f) is same result as ((*b & FREQ_MASK) < f) + if (fb < f) { - UInt32 k; - for (k = lenCounters[len]; k != 0; k--) - lens[p[i++] & MASK] = (Byte)len; + // node freq is smaller + sum = fb & FREQ_MASK; + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + fb = *b; + if (b == e) + { + if (++pi == n) + break; + sum += f; + fb &= MASK; + fb |= sum; + *e = fb; + f = *pi & FREQ_MASK; + continue; + } + } + else if (++pi == n) + { + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + break; + } + else + { + sum = f; + f = *pi & FREQ_MASK; + } + + // (b < e) + + // second child + if (fb < f) + { + sum += fb; + sum &= FREQ_MASK; + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + *e = (*e & MASK) | sum; // set frequency sum + // (b <= e) is possible here + fb = *b; + } + else if (++pi == n) + break; + else + { + sum += f; + f = *pi & FREQ_MASK; + *e = (*e & MASK) | sum; // set frequency sum } } - + } + + // printf("\nnum-e=%3u, numSymbols=%3u, num=%3u, b=%3u", n - e, numSymbols, n - p, b - p); + { + n -= 2; + *n &= MASK; // root node : we clear high bits (zero bits mean level == 0) + if (n != b) { - UInt32 nextCodes[kMaxLen + 1]; + // We go here, if we have some number of non-created nodes up to root. + // We process them in simplified code: + // position of parent for each pair of nodes is known. + // n[-2], n[-1] : current pair of child nodes + // (p1) : parent node for current pair. + UInt32 *p1 = n; + do { - UInt32 code = 0; - UInt32 len; - for (len = 1; len <= kMaxLen; len++) - nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1; + const unsigned len = LOAD_PARENT(p1) + 1; + p1--; + (lenCounters )[len] -= 2; // we remove 2 leaves from level (len) + (lenCounters + 1)[len] += 2 * 2; // we add 4 leaves at level (len + 1) + n -= 2; + STORE_PARENT (n , n[0], len) + STORE_PARENT (n + 1, n[1], len) } - /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ - + while (n != b); + } + } + + if (b != p) + { + // we detect level of each node (realtive to root), + // and update lenCounters[]. + // We process only intermediate nodes and we don't process leaves. + do + { + // if (ii < b) : parent_bits_of (p[ii]) == index of parent node : ii < (p[ii]) + // if (ii >= b) : parent_bits_of (p[ii]) == level of this (ii) node in tree + unsigned len; + b--; + len = (unsigned)LOAD_PARENT(p + LOAD_PARENT(b)) + 1; + STORE_PARENT (b, *b, len) + if (len >= maxLen) { - UInt32 k; - for (k = 0; k < numSymbols; k++) - p[k] = nextCodes[lens[k]]++; + // We are not allowed to create node at level (maxLen) and higher, + // because all leaves must be placed to level (maxLen) or lower. + // We find nearest allowed leaf and place current node to level of that leaf: + for (len = maxLen - 1; lenCounters[len] == 0; len--) {} } + lenCounters[len]--; // we remove 1 leaf from level (len) + (lenCounters + 1)[len] += 2; // we add 2 leaves at level (len + 1) + } + while (b != p); + } + } + { + { + unsigned len = maxLen; + const UInt32 *p2 = p; + do + { + unsigned k = lenCounters[len]; + if (k) + do + lens[(unsigned)*p2++ & MASK] = (Byte)len; + while (--k); + } + while (--len); + } + codes[0] = 0; // we don't want garbage values to be written to p[] array. + // codes[1] = 0; + { + UInt32 code = 0; + unsigned len; + for (len = 0; len < kMaxLen; len++) + (codes + 1)[len] = code = (code + lenCounters[len]) << 1; + } + /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ + { + const Byte * const limit = lens + numSymbols; + do + { + unsigned len; + UInt32 c; + len = lens[0]; c = codes[len]; p[0] = c; codes[len] = c + 1; + // len = lens[1]; c = codes[len]; p[1] = c; codes[len] = c + 1; + p += 1; + lens += 1; } + while (lens != limit); } } } + +#undef kMaxLen +#undef NUM_BITS +#undef MASK +#undef FREQ_MASK +#undef NUM_COUNTERS +#undef CTR_ITEM_FOR_FREQ +#undef LOAD_PARENT +#undef STORE_PARENT +#undef STORE_PARENT_DIRECT +#undef UPDATE_E +#undef HI_HALF_OFFSET +#undef NUM_UNROLLS +#undef lenCounters +#undef codes diff -Nru 7zip-22.01+dfsg/C/HuffEnc.h 7zip-22.01+really25.01+dfsg/C/HuffEnc.h --- 7zip-22.01+dfsg/C/HuffEnc.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/HuffEnc.h 2025-03-20 14:00:00.000000000 +0000 @@ -1,21 +1,21 @@ /* HuffEnc.h -- Huffman encoding -2013-01-18 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ -#ifndef __HUFF_ENC_H -#define __HUFF_ENC_H +#ifndef ZIP7_INC_HUFF_ENC_H +#define ZIP7_INC_HUFF_ENC_H #include "7zTypes.h" EXTERN_C_BEGIN +#define Z7_HUFFMAN_LEN_MAX 16 /* Conditions: - num <= 1024 = 2 ^ NUM_BITS + 2 <= num <= 1024 = 2 ^ NUM_BITS Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS) - maxLen <= 16 = kMaxLen + 1 <= maxLen <= 16 = Z7_HUFFMAN_LEN_MAX Num_Items(p) >= HUFFMAN_TEMP_SIZE(num) */ - void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/LzFind.c 7zip-22.01+really25.01+dfsg/C/LzFind.c --- 7zip-22.01+dfsg/C/LzFind.c 2021-11-29 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzFind.c 2025-07-25 07:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* LzFind.c -- Match finder for LZ algorithms -2021-11-29 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -17,7 +17,7 @@ #define kEmptyHashValue 0 #define kMaxValForNormalize ((UInt32)0) -// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xFFF) // for debug +// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xfff) // for debug // #define kNormalizeAlign (1 << 7) // alignment for speculated accesses @@ -67,10 +67,10 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) { - if (!p->directInput) + // if (!p->directInput) { - ISzAlloc_Free(alloc, p->bufferBase); - p->bufferBase = NULL; + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; } } @@ -79,7 +79,7 @@ { if (blockSize == 0) return 0; - if (!p->bufferBase || p->blockSize != blockSize) + if (!p->bufBase || p->blockSize != blockSize) { // size_t blockSizeT; LzInWindow_Free(p, alloc); @@ -101,19 +101,25 @@ #endif */ - p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); - // printf("\nbufferBase = %p\n", p->bufferBase); + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); + // printf("\nbufferBase = %p\n", p->bufBase); // return 0; // for debug } - return (p->bufferBase != NULL); + return (p->bufBase != NULL); } -static const Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +static const Byte *MatchFinder_GetPointerToCurrentPos(void *p) +{ + return ((CMatchFinder *)p)->buffer; +} -static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return GET_AVAIL_BYTES(p); } +static UInt32 MatchFinder_GetNumAvailableBytes(void *p) +{ + return GET_AVAIL_BYTES((CMatchFinder *)p); +} -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_ReadBlock(CMatchFinder *p) { if (p->streamEndWasReached || p->result != SZ_OK) @@ -127,8 +133,8 @@ UInt32 curSize = 0xFFFFFFFF - GET_AVAIL_BYTES(p); if (curSize > p->directInputRem) curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; p->streamPos += curSize; + p->directInputRem -= curSize; if (p->directInputRem == 0) p->streamEndWasReached = 1; return; @@ -136,8 +142,8 @@ for (;;) { - Byte *dest = p->buffer + GET_AVAIL_BYTES(p); - size_t size = (size_t)(p->bufferBase + p->blockSize - dest); + const Byte *dest = p->buffer + GET_AVAIL_BYTES(p); + size_t size = (size_t)(p->bufBase + p->blockSize - dest); if (size == 0) { /* we call ReadBlock() after NeedMove() and MoveBlock(). @@ -153,7 +159,14 @@ // #define kRead 3 // if (size > kRead) size = kRead; // for debug - p->result = ISeqInStream_Read(p->stream, dest, &size); + /* + // we need cast (Byte *)dest. + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + */ + p->result = ISeqInStream_Read(p->stream, + p->bufBase + (dest - p->bufBase), &size); if (p->result != SZ_OK) return; if (size == 0) @@ -173,14 +186,14 @@ -MY_NO_INLINE +Z7_NO_INLINE void MatchFinder_MoveBlock(CMatchFinder *p) { - const size_t offset = (size_t)(p->buffer - p->bufferBase) - p->keepSizeBefore; + const size_t offset = (size_t)(p->buffer - p->bufBase) - p->keepSizeBefore; const size_t keepBefore = (offset & (kBlockMoveAlign - 1)) + p->keepSizeBefore; - p->buffer = p->bufferBase + keepBefore; - memmove(p->bufferBase, - p->bufferBase + (offset & ~((size_t)kBlockMoveAlign - 1)), + p->buffer = p->bufBase + keepBefore; + memmove(p->bufBase, + p->bufBase + (offset & ~((size_t)kBlockMoveAlign - 1)), keepBefore + (size_t)GET_AVAIL_BYTES(p)); } @@ -198,7 +211,7 @@ return 0; if (p->streamEndWasReached || p->result != SZ_OK) return 0; - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); + return ((size_t)(p->bufBase + p->blockSize - p->buffer) <= p->keepSizeAfter); } void MatchFinder_ReadIfRequired(CMatchFinder *p) @@ -214,6 +227,8 @@ p->cutValue = 32; p->btMode = 1; p->numHashBytes = 4; + p->numHashBytes_Min = 2; + p->numHashOutBits = 0; p->bigHash = 0; } @@ -222,8 +237,10 @@ void MatchFinder_Construct(CMatchFinder *p) { unsigned i; - p->bufferBase = NULL; + p->buffer = NULL; + p->bufBase = NULL; p->directInput = 0; + p->stream = NULL; p->hash = NULL; p->expectedDataSize = (UInt64)(Int64)-1; MatchFinder_SetDefaultSettings(p); @@ -238,6 +255,8 @@ } } +#undef kCrcPoly + static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) { ISzAlloc_Free(alloc, p->hash); @@ -252,7 +271,7 @@ static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) { - size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + const size_t sizeInBytes = (size_t)num * sizeof(CLzRef); if (sizeInBytes / sizeof(CLzRef) != num) return NULL; return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); @@ -298,6 +317,62 @@ } +// input is historySize +static UInt32 MatchFinder_GetHashMask2(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + +// input is historySize +static UInt32 MatchFinder_GetHashMask(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + hs >>= 1; + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + + int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc) @@ -318,78 +393,91 @@ p->blockSize = 0; if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc)) { - const UInt32 newCyclicBufferSize = historySize + 1; // do not change it - UInt32 hs; - p->matchMaxLen = matchMaxLen; + size_t hashSizeSum; { - // UInt32 hs4; - p->fixedHashSize = 0; - hs = (1 << 16) - 1; - if (p->numHashBytes != 2) + UInt32 hs; + UInt32 hsCur; + + if (p->numHashOutBits != 0) { - hs = historySize; - if (hs > p->expectedDataSize) - hs = (UInt32)p->expectedDataSize; - if (hs != 0) - hs--; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - // we propagated 16 bits in (hs). Low 16 bits must be set later - hs >>= 1; - if (hs >= (1 << 24)) - { - if (p->numHashBytes == 3) - hs = (1 << 24) - 1; - else - hs >>= 1; - /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ - } - - // hs = ((UInt32)1 << 25) - 1; // for test - + unsigned numBits = p->numHashOutBits; + const unsigned nbMax = + (p->numHashBytes == 2 ? 16 : + (p->numHashBytes == 3 ? 24 : 32)); + if (numBits >= nbMax) + numBits = nbMax; + if (numBits >= 32) + hs = (UInt32)0 - 1; + else + hs = ((UInt32)1 << numBits) - 1; // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) hs |= (1 << 16) - 1; /* don't change it! */ - - // bt5: we adjust the size with recommended minimum size if (p->numHashBytes >= 5) hs |= (256 << kLzHash_CrcShift_2) - 1; + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize); + if (hs >= hs2) + hs = hs2; + } + hsCur = hs; + if (p->expectedDataSize < historySize) + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize); + if (hsCur >= hs2) + hsCur = hs2; + } + } + else + { + hs = MatchFinder_GetHashMask(p, historySize); + hsCur = hs; + if (p->expectedDataSize < historySize) + { + hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize); + if (hsCur >= hs) // is it possible? + hsCur = hs; + } } - p->hashMask = hs; - hs++; - /* - hs4 = (1 << 20); - if (hs4 > hs) - hs4 = hs; - // hs4 = (1 << 16); // for test - p->hash4Mask = hs4 - 1; - */ + p->hashMask = hsCur; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; - hs += p->fixedHashSize; + hashSizeSum = hs; + hashSizeSum++; + if (hashSizeSum < hs) + return 0; + { + UInt32 fixedHashSize = 0; + if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size; + if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size; + // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; + hashSizeSum += fixedHashSize; + p->fixedHashSize = fixedHashSize; + } } + p->matchMaxLen = matchMaxLen; + { size_t newSize; size_t numSons; + const UInt32 newCyclicBufferSize = historySize + 1; // do not change it p->historySize = historySize; - p->hashSizeSum = hs; p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1) numSons = newCyclicBufferSize; if (p->btMode) numSons <<= 1; - newSize = hs + numSons; + newSize = hashSizeSum + numSons; + + if (numSons < newCyclicBufferSize || newSize < numSons) + return 0; // aligned size is not required here, but it can be better for some loops #define NUM_REFS_ALIGN_MASK 0xF newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK; - if (p->hash && p->numRefs == newSize) + // 22.02: we don't reallocate buffer, if old size is enough + if (p->hash && p->numRefs >= newSize) return 1; MatchFinder_FreeThisClassMemory(p, alloc); @@ -398,7 +486,7 @@ if (p->hash) { - p->son = p->hash + p->hashSizeSum; + p->son = p->hash + hashSizeSum; return 1; } } @@ -470,7 +558,8 @@ void MatchFinder_Init_4(CMatchFinder *p) { - p->buffer = p->bufferBase; + if (!p->directInput) + p->buffer = p->bufBase; { /* kEmptyHashValue = 0 (Zero) is used in hash tables as NO-VALUE marker. the code in CMatchFinderMt expects (pos = 1) */ @@ -488,8 +577,9 @@ #define CYC_TO_POS_OFFSET 0 // #define CYC_TO_POS_OFFSET 1 // for debug -void MatchFinder_Init(CMatchFinder *p) +void MatchFinder_Init(void *_p) { + CMatchFinder *p = (CMatchFinder *)_p; MatchFinder_Init_HighHash(p); MatchFinder_Init_LowHash(p); MatchFinder_Init_4(p); @@ -507,42 +597,42 @@ #ifdef MY_CPU_X86_OR_AMD64 - #if defined(__clang__) && (__clang_major__ >= 8) \ - || defined(__GNUC__) && (__GNUC__ >= 8) \ - || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) - #define USE_SATUR_SUB_128 - #define USE_AVX2 - #define ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) - #define ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) + // || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + + #define USE_LZFIND_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_256 + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) + #define LZFIND_ATTRIB_AVX2 __attribute__((__target__("avx2"))) #elif defined(_MSC_VER) #if (_MSC_VER >= 1600) - #define USE_SATUR_SUB_128 - #if (_MSC_VER >= 1900) - #define USE_AVX2 - #include // avx - #endif + #define USE_LZFIND_SATUR_SUB_128 + #endif + #if (_MSC_VER >= 1900) + #define USE_LZFIND_SATUR_SUB_256 #endif #endif -// #elif defined(MY_CPU_ARM_OR_ARM64) -#elif defined(MY_CPU_ARM64) +#elif defined(MY_CPU_ARM64) \ + /* || (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) */ - #if defined(__clang__) && (__clang_major__ >= 8) \ - || defined(__GNUC__) && (__GNUC__ >= 8) - #define USE_SATUR_SUB_128 + #if defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) + #define USE_LZFIND_SATUR_SUB_128 #ifdef MY_CPU_ARM64 - // #define ATTRIB_SSE41 __attribute__((__target__(""))) + // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__(""))) #else - // #define ATTRIB_SSE41 __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=neon"))) #endif #elif defined(_MSC_VER) #if (_MSC_VER >= 1910) - #define USE_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_128 #endif #endif - #if defined(_MSC_VER) && defined(MY_CPU_ARM64) + #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) #include #else #include @@ -550,121 +640,130 @@ #endif -/* -#ifndef ATTRIB_SSE41 - #define ATTRIB_SSE41 -#endif -#ifndef ATTRIB_AVX2 - #define ATTRIB_AVX2 -#endif -*/ -#ifdef USE_SATUR_SUB_128 +#ifdef USE_LZFIND_SATUR_SUB_128 -// #define _SHOW_HW_STATUS +// #define Z7_SHOW_HW_STATUS -#ifdef _SHOW_HW_STATUS +#ifdef Z7_SHOW_HW_STATUS #include -#define _PRF(x) x -_PRF(;) +#define PRF(x) x +PRF(;) #else -#define _PRF(x) +#define PRF(x) #endif + #ifdef MY_CPU_ARM_OR_ARM64 #ifdef MY_CPU_ARM64 -// #define FORCE_SATUR_SUB_128 +// #define FORCE_LZFIND_SATUR_SUB_128 #endif +typedef uint32x4_t LzFind_v128; +#define SASUB_128_V(v, s) \ + vsubq_u32(vmaxq_u32(v, s), s) -typedef uint32x4_t v128; -#define SASUB_128(i) \ - *(v128 *)(void *)(items + (i) * 4) = \ - vsubq_u32(vmaxq_u32(*(const v128 *)(const void *)(items + (i) * 4), sub2), sub2); - -#else +#else // MY_CPU_ARM_OR_ARM64 #include // sse4.1 -typedef __m128i v128; -#define SASUB_128(i) \ - *(v128 *)(void *)(items + (i) * 4) = \ - _mm_sub_epi32(_mm_max_epu32(*(const v128 *)(const void *)(items + (i) * 4), sub2), sub2); // SSE 4.1 +typedef __m128i LzFind_v128; +// SSE 4.1 +#define SASUB_128_V(v, s) \ + _mm_sub_epi32(_mm_max_epu32(v, s), s) + +#endif // MY_CPU_ARM_OR_ARM64 -#endif +#define SASUB_128(i) \ + *( LzFind_v128 *)( void *)(items + (i) * 4) = SASUB_128_V( \ + *(const LzFind_v128 *)(const void *)(items + (i) * 4), sub2); -MY_NO_INLINE +Z7_NO_INLINE static -#ifdef ATTRIB_SSE41 -ATTRIB_SSE41 +#ifdef LZFIND_ATTRIB_SSE41 +LZFIND_ATTRIB_SSE41 #endif void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim) { - v128 sub2 = + const LzFind_v128 sub2 = #ifdef MY_CPU_ARM_OR_ARM64 vdupq_n_u32(subValue); #else _mm_set_epi32((Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); #endif + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - SASUB_128(0) - SASUB_128(1) - SASUB_128(2) - SASUB_128(3) - items += 4 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; } while (items != lim); } -#ifdef USE_AVX2 +#ifdef USE_LZFIND_SATUR_SUB_256 #include // avx +/* +clang :immintrin.h uses +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__AVX2__) +#include +#endif +so we need for clang-cl */ -#define SASUB_256(i) *(__m256i *)(void *)(items + (i) * 8) = _mm256_sub_epi32(_mm256_max_epu32(*(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); // AVX2 +#if defined(__clang__) +#include +#include +#endif + +// AVX2: +#define SASUB_256(i) \ + *( __m256i *)( void *)(items + (i) * 8) = \ + _mm256_sub_epi32(_mm256_max_epu32( \ + *(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); -MY_NO_INLINE +Z7_NO_INLINE static -#ifdef ATTRIB_AVX2 -ATTRIB_AVX2 +#ifdef LZFIND_ATTRIB_AVX2 +LZFIND_ATTRIB_AVX2 #endif void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim) { - __m256i sub2 = _mm256_set_epi32( + const __m256i sub2 = _mm256_set_epi32( (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - SASUB_256(0) - SASUB_256(1) - items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; } while (items != lim); } -#endif // USE_AVX2 +#endif // USE_LZFIND_SATUR_SUB_256 -#ifndef FORCE_SATUR_SUB_128 -typedef void (MY_FAST_CALL *LZFIND_SATUR_SUB_CODE_FUNC)( +#ifndef FORCE_LZFIND_SATUR_SUB_128 +typedef void (Z7_FASTCALL *LZFIND_SATUR_SUB_CODE_FUNC)( UInt32 subValue, CLzRef *items, const CLzRef *lim); static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub; -#endif // FORCE_SATUR_SUB_128 +#endif // FORCE_LZFIND_SATUR_SUB_128 -#endif // USE_SATUR_SUB_128 +#endif // USE_LZFIND_SATUR_SUB_128 // kEmptyHashValue must be zero -// #define SASUB_32(i) v = items[i]; m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; -#define SASUB_32(i) v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; +// #define SASUB_32(i) { UInt32 v = items[i]; UInt32 m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; } +#define SASUB_32(i) { UInt32 v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; } -#ifdef FORCE_SATUR_SUB_128 +#ifdef FORCE_LZFIND_SATUR_SUB_128 #define DEFAULT_SaturSub LzFind_SaturSub_128 @@ -672,24 +771,19 @@ #define DEFAULT_SaturSub LzFind_SaturSub_32 -MY_NO_INLINE +Z7_NO_INLINE static void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim) { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - UInt32 v; - SASUB_32(0) - SASUB_32(1) - SASUB_32(2) - SASUB_32(3) - SASUB_32(4) - SASUB_32(5) - SASUB_32(6) - SASUB_32(7) - items += 8; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; } while (items != lim); } @@ -697,27 +791,23 @@ #endif -MY_NO_INLINE +Z7_NO_INLINE void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) { - #define K_NORM_ALIGN_BLOCK_SIZE (1 << 6) - - CLzRef *lim; - - for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (K_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) + #define LZFIND_NORM_ALIGN_BLOCK_SIZE (1 << 7) + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (LZFIND_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) { - UInt32 v; - SASUB_32(0); + SASUB_32(0) items++; } - { - #define K_NORM_ALIGN_MASK (K_NORM_ALIGN_BLOCK_SIZE / 4 - 1) - lim = items + (numItems & ~(size_t)K_NORM_ALIGN_MASK); - numItems &= K_NORM_ALIGN_MASK; + const size_t k_Align_Mask = (LZFIND_NORM_ALIGN_BLOCK_SIZE / 4 - 1); + CLzRef *lim = items + (numItems & ~(size_t)k_Align_Mask); + numItems &= k_Align_Mask; if (items != lim) { - #if defined(USE_SATUR_SUB_128) && !defined(FORCE_SATUR_SUB_128) + #if defined(USE_LZFIND_SATUR_SUB_128) && !defined(FORCE_LZFIND_SATUR_SUB_128) if (g_LzFind_SaturSub) g_LzFind_SaturSub(subValue, items, lim); else @@ -726,12 +816,10 @@ } items = lim; } - - + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE for (; numItems != 0; numItems--) { - UInt32 v; - SASUB_32(0); + SASUB_32(0) items++; } } @@ -740,7 +828,7 @@ // call MatchFinder_CheckLimits() only after (p->pos++) update -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_CheckLimits(CMatchFinder *p) { if (// !p->streamEndWasReached && p->result == SZ_OK && @@ -768,11 +856,14 @@ const UInt32 subValue = (p->pos - p->historySize - 1) /* & ~(UInt32)(kNormalizeAlign - 1) */; // const UInt32 subValue = (1 << 15); // for debug // printf("\nMatchFinder_Normalize() subValue == 0x%x\n", subValue); - size_t numSonRefs = p->cyclicBufferSize; - if (p->btMode) - numSonRefs <<= 1; - Inline_MatchFinder_ReduceOffsets(p, subValue); - MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashSizeSum + numSonRefs); + MatchFinder_REDUCE_OFFSETS(p, subValue) + MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashMask + 1 + p->fixedHashSize); + { + size_t numSonRefs = p->cyclicBufferSize; + if (p->btMode) + numSonRefs <<= 1; + MatchFinder_Normalize3(subValue, p->son, numSonRefs); + } } if (p->cyclicBufferPos == p->cyclicBufferSize) @@ -785,7 +876,7 @@ /* (lenLimit > maxLen) */ -MY_FORCE_INLINE +Z7_FORCE_INLINE static UInt32 * Hc_GetMatchesSpec(size_t lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, UInt32 *d, unsigned maxLen) @@ -799,7 +890,7 @@ return d; { const Byte *pb = cur - delta; - curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + curMatch = son[_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)]; if (pb[maxLen] == cur[maxLen] && *pb == *cur) { UInt32 len = 0; @@ -834,7 +925,7 @@ break; { ptrdiff_t diff; - curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + curMatch = son[_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)]; diff = (ptrdiff_t)0 - (ptrdiff_t)delta; if (cur[maxLen] == cur[(ptrdiff_t)maxLen + diff]) { @@ -867,7 +958,7 @@ } -MY_FORCE_INLINE +Z7_FORCE_INLINE UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, UInt32 *d, UInt32 maxLen) @@ -881,7 +972,7 @@ // if (curMatch >= pos) { *ptr0 = *ptr1 = kEmptyHashValue; return NULL; } cmCheck = (UInt32)(pos - _cyclicBufferSize); - if ((UInt32)pos <= _cyclicBufferSize) + if ((UInt32)pos < _cyclicBufferSize) cmCheck = 0; if (cmCheck < curMatch) @@ -889,7 +980,7 @@ { const UInt32 delta = pos - curMatch; { - CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)) << 1); const Byte *pb = cur - delta; unsigned len = (len0 < len1 ? len0 : len1); const UInt32 pair0 = pair[0]; @@ -948,7 +1039,7 @@ UInt32 cmCheck; cmCheck = (UInt32)(pos - _cyclicBufferSize); - if ((UInt32)pos <= _cyclicBufferSize) + if ((UInt32)pos < _cyclicBufferSize) cmCheck = 0; if (// curMatch >= pos || // failure @@ -957,7 +1048,7 @@ { const UInt32 delta = pos - curMatch; { - CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)) << 1); const Byte *pb = cur - delta; unsigned len = (len0 < len1 ? len0 : len1); if (pb[len] == cur[len]) @@ -998,13 +1089,15 @@ #define MOVE_POS \ - ++p->cyclicBufferPos; \ + p->cyclicBufferPos++; \ p->buffer++; \ - { const UInt32 pos1 = p->pos + 1; p->pos = pos1; if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); } + { const UInt32 pos1 = p->pos + 1; \ + p->pos = pos1; \ + if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); } #define MOVE_POS_RET MOVE_POS return distances; -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_MovePos(CMatchFinder *p) { /* we go here at the end of stream data, when (avail < num_hash_bytes) @@ -1015,24 +1108,30 @@ if (p->btMode) p->sons[(p->cyclicBufferPos << p->btMode) + 1] = 0; // kEmptyHashValue */ - MOVE_POS; + MOVE_POS } #define GET_MATCHES_HEADER2(minLen, ret_op) \ - unsigned lenLimit; UInt32 hv; Byte *cur; UInt32 curMatch; \ - lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + UInt32 hv; const Byte *cur; UInt32 curMatch; \ + UInt32 lenLimit = p->lenLimit; \ + if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; } \ cur = p->buffer; #define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return distances) -#define SKIP_HEADER(minLen) do { GET_MATCHES_HEADER2(minLen, continue) +#define SKIP_HEADER(minLen) \ + do { GET_MATCHES_HEADER2(minLen, continue) -#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue +#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, \ + p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -#define SKIP_FOOTER SkipMatchesSpec(MF_PARAMS(p)); MOVE_POS; } while (--num); +#define SKIP_FOOTER \ + SkipMatchesSpec(MF_PARAMS(p)); \ + MOVE_POS \ + } while (--num); #define GET_MATCHES_FOOTER_BASE(_maxLen_, func) \ - distances = func(MF_PARAMS(p), \ - distances, (UInt32)_maxLen_); MOVE_POS_RET; + distances = func(MF_PARAMS(p), distances, (UInt32)_maxLen_); \ + MOVE_POS_RET #define GET_MATCHES_FOOTER_BT(_maxLen_) \ GET_MATCHES_FOOTER_BASE(_maxLen_, GetMatchesSpec1) @@ -1049,10 +1148,11 @@ for (; c != lim; c++) if (*(c + diff) != *c) break; \ maxLen = (unsigned)(c - cur); } -static UInt32* Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32* Bt2_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; GET_MATCHES_HEADER(2) - HASH2_CALC; + HASH2_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_BT(1) @@ -1061,7 +1161,7 @@ UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_BT(2) @@ -1074,15 +1174,16 @@ mmm = pos; -static UInt32* Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32* Bt3_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; UInt32 mmm; UInt32 h2, d2, pos; unsigned maxLen; UInt32 *hash; GET_MATCHES_HEADER(3) - HASH3_CALC; + HASH3_CALC hash = p->hash; pos = p->pos; @@ -1107,7 +1208,7 @@ if (maxLen == lenLimit) { SkipMatchesSpec(MF_PARAMS(p)); - MOVE_POS_RET; + MOVE_POS_RET } } @@ -1115,15 +1216,16 @@ } -static UInt32* Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32* Bt4_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; UInt32 mmm; UInt32 h2, h3, d2, d3, pos; unsigned maxLen; UInt32 *hash; GET_MATCHES_HEADER(4) - HASH4_CALC; + HASH4_CALC hash = p->hash; pos = p->pos; @@ -1183,14 +1285,16 @@ } -static UInt32* Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32* Bt5_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; UInt32 mmm; - UInt32 h2, h3, d2, d3, maxLen, pos; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; UInt32 *hash; GET_MATCHES_HEADER(5) - HASH5_CALC; + HASH5_CALC hash = p->hash; pos = p->pos; @@ -1246,7 +1350,7 @@ if (maxLen == lenLimit) { SkipMatchesSpec(MF_PARAMS(p)); - MOVE_POS_RET; + MOVE_POS_RET } break; } @@ -1255,15 +1359,16 @@ } -static UInt32* Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32* Hc4_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; UInt32 mmm; UInt32 h2, h3, d2, d3, pos; unsigned maxLen; UInt32 *hash; GET_MATCHES_HEADER(4) - HASH4_CALC; + HASH4_CALC hash = p->hash; pos = p->pos; @@ -1314,23 +1419,25 @@ if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; + MOVE_POS_RET } break; } - GET_MATCHES_FOOTER_HC(maxLen); + GET_MATCHES_FOOTER_HC(maxLen) } -static UInt32 * Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32 * Hc5_MatchFinder_GetMatches(void *_p, UInt32 *distances) { + CMatchFinder *p = (CMatchFinder *)_p; UInt32 mmm; - UInt32 h2, h3, d2, d3, maxLen, pos; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; UInt32 *hash; GET_MATCHES_HEADER(5) - HASH5_CALC; + HASH5_CALC hash = p->hash; pos = p->pos; @@ -1382,34 +1489,35 @@ if (*(cur - d2 + 3) != cur[3]) break; UPDATE_maxLen - distances[-2] = maxLen; + distances[-2] = (UInt32)maxLen; if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; + MOVE_POS_RET } break; } - GET_MATCHES_FOOTER_HC(maxLen); + GET_MATCHES_FOOTER_HC(maxLen) } UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_HC(2) } -static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt2_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; SKIP_HEADER(2) { - HASH2_CALC; + HASH2_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; } @@ -1420,20 +1528,21 @@ { SKIP_HEADER(3) { - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; } SKIP_FOOTER } -static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt3_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; SKIP_HEADER(3) { UInt32 h2; UInt32 *hash; - HASH3_CALC; + HASH3_CALC hash = p->hash; curMatch = (hash + kFix3HashSize)[hv]; hash[h2] = @@ -1442,13 +1551,14 @@ SKIP_FOOTER } -static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt4_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; SKIP_HEADER(4) { UInt32 h2, h3; UInt32 *hash; - HASH4_CALC; + HASH4_CALC hash = p->hash; curMatch = (hash + kFix4HashSize)[hv]; hash [h2] = @@ -1458,13 +1568,14 @@ SKIP_FOOTER } -static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt5_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; SKIP_HEADER(5) { UInt32 h2, h3; UInt32 *hash; - HASH5_CALC; + HASH5_CALC hash = p->hash; curMatch = (hash + kFix5HashSize)[hv]; hash [h2] = @@ -1478,13 +1589,13 @@ #define HC_SKIP_HEADER(minLen) \ do { if (p->lenLimit < minLen) { MatchFinder_MovePos(p); num--; continue; } { \ - Byte *cur; \ + const Byte *cur; \ UInt32 *hash; \ UInt32 *son; \ UInt32 pos = p->pos; \ UInt32 num2 = num; \ /* (p->pos == p->posLimit) is not allowed here !!! */ \ - { const UInt32 rem = p->posLimit - pos; if (num2 > rem) num2 = rem; } \ + { const UInt32 rem = p->posLimit - pos; if (num2 >= rem) num2 = rem; } \ num -= num2; \ { const UInt32 cycPos = p->cyclicBufferPos; \ son = p->son + cycPos; \ @@ -1505,12 +1616,13 @@ }} while(num); \ -static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Hc4_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; HC_SKIP_HEADER(4) UInt32 h2, h3; - HASH4_CALC; + HASH4_CALC curMatch = (hash + kFix4HashSize)[hv]; hash [h2] = (hash + kFix3HashSize)[h3] = @@ -1520,8 +1632,9 @@ } -static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Hc5_MatchFinder_Skip(void *_p, UInt32 num) { + CMatchFinder *p = (CMatchFinder *)_p; HC_SKIP_HEADER(5) UInt32 h2, h3; @@ -1540,7 +1653,7 @@ { HC_SKIP_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = hash[hv]; hash[hv] = pos; @@ -1550,57 +1663,57 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable) { - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + vTable->Init = MatchFinder_Init; + vTable->GetNumAvailableBytes = MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = MatchFinder_GetPointerToCurrentPos; if (!p->btMode) { if (p->numHashBytes <= 4) { - vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + vTable->GetMatches = Hc4_MatchFinder_GetMatches; + vTable->Skip = Hc4_MatchFinder_Skip; } else { - vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip; + vTable->GetMatches = Hc5_MatchFinder_GetMatches; + vTable->Skip = Hc5_MatchFinder_Skip; } } else if (p->numHashBytes == 2) { - vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + vTable->GetMatches = Bt2_MatchFinder_GetMatches; + vTable->Skip = Bt2_MatchFinder_Skip; } else if (p->numHashBytes == 3) { - vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + vTable->GetMatches = Bt3_MatchFinder_GetMatches; + vTable->Skip = Bt3_MatchFinder_Skip; } else if (p->numHashBytes == 4) { - vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + vTable->GetMatches = Bt4_MatchFinder_GetMatches; + vTable->Skip = Bt4_MatchFinder_Skip; } else { - vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip; + vTable->GetMatches = Bt5_MatchFinder_GetMatches; + vTable->Skip = Bt5_MatchFinder_Skip; } } -void LzFindPrepare() +void LzFindPrepare(void) { - #ifndef FORCE_SATUR_SUB_128 - #ifdef USE_SATUR_SUB_128 + #ifndef FORCE_LZFIND_SATUR_SUB_128 + #ifdef USE_LZFIND_SATUR_SUB_128 LZFIND_SATUR_SUB_CODE_FUNC f = NULL; #ifdef MY_CPU_ARM_OR_ARM64 { if (CPU_IsSupported_NEON()) { // #pragma message ("=== LzFind NEON") - _PRF(printf("\n=== LzFind NEON\n")); + PRF(printf("\n=== LzFind NEON\n")); f = LzFind_SaturSub_128; } // f = 0; // for debug @@ -1609,20 +1722,25 @@ if (CPU_IsSupported_SSE41()) { // #pragma message ("=== LzFind SSE41") - _PRF(printf("\n=== LzFind SSE41\n")); + PRF(printf("\n=== LzFind SSE41\n")); f = LzFind_SaturSub_128; - #ifdef USE_AVX2 + #ifdef USE_LZFIND_SATUR_SUB_256 if (CPU_IsSupported_AVX2()) { // #pragma message ("=== LzFind AVX2") - _PRF(printf("\n=== LzFind AVX2\n")); + PRF(printf("\n=== LzFind AVX2\n")); f = LzFind_SaturSub_256; } #endif } #endif // MY_CPU_ARM_OR_ARM64 g_LzFind_SaturSub = f; - #endif // USE_SATUR_SUB_128 - #endif // FORCE_SATUR_SUB_128 + #endif // USE_LZFIND_SATUR_SUB_128 + #endif // FORCE_LZFIND_SATUR_SUB_128 } + + +#undef MOVE_POS +#undef MOVE_POS_RET +#undef PRF diff -Nru 7zip-22.01+dfsg/C/LzFind.h 7zip-22.01+really25.01+dfsg/C/LzFind.h --- 7zip-22.01+dfsg/C/LzFind.h 2021-07-13 08:52:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzFind.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* LzFind.h -- Match finder for LZ algorithms -2021-07-13 : Igor Pavlov : Public domain */ +2024-01-22 : Igor Pavlov : Public domain */ -#ifndef __LZ_FIND_H -#define __LZ_FIND_H +#ifndef ZIP7_INC_LZ_FIND_H +#define ZIP7_INC_LZ_FIND_H #include "7zTypes.h" @@ -10,9 +10,9 @@ typedef UInt32 CLzRef; -typedef struct _CMatchFinder +typedef struct { - Byte *buffer; + const Byte *buffer; UInt32 pos; UInt32 posLimit; UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */ @@ -32,8 +32,8 @@ UInt32 hashMask; UInt32 cutValue; - Byte *bufferBase; - ISeqInStream *stream; + Byte *bufBase; + ISeqInStreamPtr stream; UInt32 blockSize; UInt32 keepSizeBefore; @@ -43,7 +43,9 @@ size_t directInputRem; UInt32 historySize; UInt32 fixedHashSize; - UInt32 hashSizeSum; + Byte numHashBytes_Min; + Byte numHashOutBits; + Byte _pad2_[2]; SRes result; UInt32 crc[256]; size_t numRefs; @@ -69,24 +71,45 @@ void MatchFinder_Construct(CMatchFinder *p); -/* Conditions: - historySize <= 3 GB - keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +/* (directInput = 0) is default value. + It's required to provide correct (directInput) value + before calling MatchFinder_Create(). + You can set (directInput) by any of the following calls: + - MatchFinder_SET_DIRECT_INPUT_BUF() + - MatchFinder_SET_STREAM() + - MatchFinder_SET_STREAM_MODE() */ + +#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \ + (p)->stream = NULL; \ + (p)->directInput = 1; \ + (p)->buffer = (_src_); \ + (p)->directInputRem = (_srcLen_); } + +/* +#define MatchFinder_SET_STREAM_MODE(p) { \ + (p)->directInput = 0; } +*/ + +#define MatchFinder_SET_STREAM(p, _stream_) { \ + (p)->stream = _stream_; \ + (p)->directInput = 0; } + + int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); -// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); /* -#define Inline_MatchFinder_InitPos(p, val) \ +#define MatchFinder_INIT_POS(p, val) \ (p)->pos = (val); \ (p)->streamPos = (val); */ -#define Inline_MatchFinder_ReduceOffsets(p, subValue) \ +// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); +#define MatchFinder_REDUCE_OFFSETS(p, subValue) \ (p)->pos -= (subValue); \ (p)->streamPos -= (subValue); @@ -107,7 +130,7 @@ typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances); typedef void (*Mf_Skip_Func)(void *object, UInt32); -typedef struct _IMatchFinder +typedef struct { Mf_Init_Func Init; Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; @@ -121,7 +144,8 @@ void MatchFinder_Init_LowHash(CMatchFinder *p); void MatchFinder_Init_HighHash(CMatchFinder *p); void MatchFinder_Init_4(CMatchFinder *p); -void MatchFinder_Init(CMatchFinder *p); +// void MatchFinder_Init(CMatchFinder *p); +void MatchFinder_Init(void *p); UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); diff -Nru 7zip-22.01+dfsg/C/LzFindMt.c 7zip-22.01+really25.01+dfsg/C/LzFindMt.c --- 7zip-22.01+dfsg/C/LzFindMt.c 2021-12-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzFindMt.c 2025-06-30 16:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2021-12-21 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -69,7 +69,7 @@ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -#define __MT_HASH4_CALC { \ +#define MT_HASH4_CALC { \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ h2 = temp & (kHash2Size - 1); \ temp ^= ((UInt32)cur[2] << 8); \ @@ -79,14 +79,16 @@ */ -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_Construct(CMtSync *p) { + p->affinityGroup = -1; + p->affinityInGroup = 0; p->affinity = 0; p->wasCreated = False; p->csWasInitialized = False; p->csWasEntered = False; - Thread_Construct(&p->thread); + Thread_CONSTRUCT(&p->thread) Event_Construct(&p->canStart); Event_Construct(&p->wasStopped); Semaphore_Construct(&p->freeSemaphore); @@ -94,7 +96,7 @@ } -#define DEBUG_BUFFER_LOCK // define it to debug lock state +// #define DEBUG_BUFFER_LOCK // define it to debug lock state #ifdef DEBUG_BUFFER_LOCK #include @@ -116,7 +118,7 @@ (p)->csWasEntered = False; } -MY_NO_INLINE +Z7_NO_INLINE static UInt32 MtSync_GetNextBlock(CMtSync *p) { UInt32 numBlocks = 0; @@ -140,14 +142,14 @@ // buffer is UNLOCKED here Semaphore_Wait(&p->filledSemaphore); - LOCK_BUFFER(p); + LOCK_BUFFER(p) return numBlocks; } /* if Writing (Processing) thread was started, we must call MtSync_StopWriting() */ -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_StopWriting(CMtSync *p) { if (!Thread_WasCreated(&p->thread) || p->needStart) @@ -185,7 +187,7 @@ } -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_Destruct(CMtSync *p) { PRF(printf("\nMtSync_Destruct %p\n", p)); @@ -220,11 +222,11 @@ // #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } // we want to get real system error codes here instead of SZ_ERROR_THREAD -#define RINOK_THREAD(x) RINOK(x) +#define RINOK_THREAD(x) RINOK_WRes(x) // call it before each new file (when new starting is required): -MY_NO_INLINE +Z7_NO_INLINE static SRes MtSync_Init(CMtSync *p, UInt32 numBlocks) { WRes wres; @@ -245,12 +247,12 @@ if (p->wasCreated) return SZ_OK; - RINOK_THREAD(CriticalSection_Init(&p->cs)); + RINOK_THREAD(CriticalSection_Init(&p->cs)) p->csWasInitialized = True; p->csWasEntered = False; - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)) + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)) p->needStart = True; p->exit = True; /* p->exit is unused before (canStart) Event. @@ -259,18 +261,24 @@ // return ERROR_TOO_MANY_POSTS; // for debug // return EINVAL; // for debug +#ifdef _WIN32 + if (p->affinityGroup >= 0) + wres = Thread_Create_With_Group(&p->thread, startAddress, obj, + (unsigned)(UInt32)p->affinityGroup, (CAffinityMask)p->affinityInGroup); + else +#endif if (p->affinity != 0) wres = Thread_Create_With_Affinity(&p->thread, startAddress, obj, (CAffinityMask)p->affinity); else wres = Thread_Create(&p->thread, startAddress, obj); - RINOK_THREAD(wres); + RINOK_THREAD(wres) p->wasCreated = True; return SZ_OK; } -MY_NO_INLINE +Z7_NO_INLINE static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj) { const WRes wres = MtSync_Create_WRes(p, startAddress, obj); @@ -519,7 +527,7 @@ if (mf->pos > (UInt32)kMtMaxValForNormalize - num) { const UInt32 subValue = (mf->pos - mf->historySize - 1); // & ~(UInt32)(kNormalizeAlign - 1); - Inline_MatchFinder_ReduceOffsets(mf, subValue); + MatchFinder_REDUCE_OFFSETS(mf, subValue) MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1); } @@ -560,7 +568,7 @@ */ -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes); @@ -749,7 +757,7 @@ } -MY_NO_INLINE +Z7_NO_INLINE static void BtThreadFunc(CMatchFinderMt *mt) { CMtSync *p = &mt->btSync; @@ -864,21 +872,22 @@ if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) return SZ_ERROR_MEM; - RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p)); - RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p)); + RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p)) + RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p)) return SZ_OK; } SRes MatchFinderMt_InitMt(CMatchFinderMt *p) { - RINOK(MtSync_Init(&p->hashSync, kMtHashNumBlocks)); + RINOK(MtSync_Init(&p->hashSync, kMtHashNumBlocks)) return MtSync_Init(&p->btSync, kMtBtNumBlocks); } -static void MatchFinderMt_Init(CMatchFinderMt *p) +static void MatchFinderMt_Init(void *_p) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; CMatchFinder *mf = MF(p); p->btBufPos = @@ -941,7 +950,7 @@ } -MY_NO_INLINE +Z7_NO_INLINE static UInt32 MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) { if (p->failure_LZ_BT) @@ -981,8 +990,9 @@ -static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) +static const Byte * MatchFinderMt_GetPointerToCurrentPos(void *_p) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; return p->pointerToCurPos; } @@ -990,8 +1000,9 @@ #define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); -static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) +static UInt32 MatchFinderMt_GetNumAvailableBytes(void *_p) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; if (p->btBufPos != p->btBufPosLimit) return p->btNumAvailBytes; return MatchFinderMt_GetNextBlock_Bt(p); @@ -1163,7 +1174,7 @@ */ -static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) +static UInt32 * MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) { UInt32 h2, h3, /* h4, */ c2, c3 /* , c4 */; UInt32 *hash = p->hash; @@ -1179,9 +1190,8 @@ (hash + kFix3HashSize)[h3] = m; // (hash + kFix4HashSize)[h4] = m; - #define _USE_H2 - - #ifdef _USE_H2 + // #define BT5_USE_H2 + // #ifdef BT5_USE_H2 if (c2 >= matchMinPos && cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) { d[1] = m - c2 - 1; @@ -1197,8 +1207,8 @@ } d[0] = 3; d += 2; - - #ifdef _USE_H4 + + #ifdef BT5_USE_H4 if (c4 >= matchMinPos) if ( cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && @@ -1214,7 +1224,7 @@ d[0] = 2; d += 2; } - #endif + // #endif if (c3 >= matchMinPos && cur[(ptrdiff_t)c3 - (ptrdiff_t)m] == cur[0]) { @@ -1228,7 +1238,7 @@ d += 2; } - #ifdef _USE_H4 + #ifdef BT5_USE_H4 if (c4 >= matchMinPos) if ( cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && @@ -1244,8 +1254,9 @@ } -static UInt32* MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d) +static UInt32 * MatchFinderMt2_GetMatches(void *_p, UInt32 *d) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; const UInt32 *bt = p->btBufPos; const UInt32 len = *bt++; const UInt32 *btLim = bt + len; @@ -1268,8 +1279,9 @@ -static UInt32* MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *d) +static UInt32 * MatchFinderMt_GetMatches(void *_p, UInt32 *d) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; const UInt32 *bt = p->btBufPos; UInt32 len = *bt++; const UInt32 avail = p->btNumAvailBytes - 1; @@ -1316,14 +1328,16 @@ #define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; #define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += (size_t)*p->btBufPos + 1; } while (--num != 0); -static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) +static void MatchFinderMt0_Skip(void *_p, UInt32 num) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; SKIP_HEADER2_MT { p->btNumAvailBytes--; SKIP_FOOTER_MT } -static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) +static void MatchFinderMt2_Skip(void *_p, UInt32 num) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; SKIP_HEADER_MT(2) UInt32 h2; MT_HASH2_CALC @@ -1331,8 +1345,9 @@ SKIP_FOOTER_MT } -static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) +static void MatchFinderMt3_Skip(void *_p, UInt32 num) { + CMatchFinderMt *p = (CMatchFinderMt *)_p; SKIP_HEADER_MT(3) UInt32 h2, h3; MT_HASH3_CALC @@ -1362,39 +1377,46 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable) { - vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; + vTable->Init = MatchFinderMt_Init; + vTable->GetNumAvailableBytes = MatchFinderMt_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = MatchFinderMt_GetPointerToCurrentPos; + vTable->GetMatches = MatchFinderMt_GetMatches; switch (MF(p)->numHashBytes) { case 2: p->GetHeadsFunc = GetHeads2; - p->MixMatchesFunc = (Mf_Mix_Matches)NULL; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; + p->MixMatchesFunc = NULL; + vTable->Skip = MatchFinderMt0_Skip; + vTable->GetMatches = MatchFinderMt2_GetMatches; break; case 3: p->GetHeadsFunc = MF(p)->bigHash ? GetHeads3b : GetHeads3; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip; + p->MixMatchesFunc = MixMatches2; + vTable->Skip = MatchFinderMt2_Skip; break; case 4: p->GetHeadsFunc = MF(p)->bigHash ? GetHeads4b : GetHeads4; // it's fast inline version of GetMatches() - // vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches_Bt4; + // vTable->GetMatches = MatchFinderMt_GetMatches_Bt4; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; + p->MixMatchesFunc = MixMatches3; + vTable->Skip = MatchFinderMt3_Skip; break; default: p->GetHeadsFunc = MF(p)->bigHash ? GetHeads5b : GetHeads5; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4; + p->MixMatchesFunc = MixMatches4; vTable->Skip = - (Mf_Skip_Func)MatchFinderMt3_Skip; - // (Mf_Skip_Func)MatchFinderMt4_Skip; + MatchFinderMt3_Skip; + // MatchFinderMt4_Skip; break; } } + +#undef RINOK_THREAD +#undef PRF +#undef MF +#undef GetUi24hi_from32 +#undef LOCK_BUFFER +#undef UNLOCK_BUFFER diff -Nru 7zip-22.01+dfsg/C/LzFindMt.h 7zip-22.01+really25.01+dfsg/C/LzFindMt.h --- 7zip-22.01+dfsg/C/LzFindMt.h 2021-07-12 11:30:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzFindMt.h 2025-05-10 07:00:00.000000000 +0000 @@ -1,19 +1,21 @@ /* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2021-07-12 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __LZ_FIND_MT_H -#define __LZ_FIND_MT_H +#ifndef ZIP7_INC_LZ_FIND_MT_H +#define ZIP7_INC_LZ_FIND_MT_H #include "LzFind.h" #include "Threads.h" EXTERN_C_BEGIN -typedef struct _CMtSync +typedef struct { UInt32 numProcessedBlocks; - CThread thread; + Int32 affinityGroup; + UInt64 affinityInGroup; UInt64 affinity; + CThread thread; BoolInt wasCreated; BoolInt needStart; @@ -31,7 +33,10 @@ // UInt32 numBlocks_Sent; } CMtSync; -typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); + +struct CMatchFinderMt_; + +typedef UInt32 * (*Mf_Mix_Matches)(struct CMatchFinderMt_ *p, UInt32 matchMinPos, UInt32 *distances); /* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ #define kMtCacheLineDummy 128 @@ -39,7 +44,7 @@ typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); -typedef struct _CMatchFinderMt +typedef struct CMatchFinderMt_ { /* LZ */ const Byte *pointerToCurPos; diff -Nru 7zip-22.01+dfsg/C/LzFindOpt.c 7zip-22.01+really25.01+dfsg/C/LzFindOpt.c --- 7zip-22.01+dfsg/C/LzFindOpt.c 2021-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzFindOpt.c 2023-04-02 12:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* LzFindOpt.c -- multithreaded Match finder for LZ algorithms -2021-07-13 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -41,8 +41,8 @@ // #define CYC_TO_POS_OFFSET 1 // for debug /* -MY_NO_INLINE -UInt32 * MY_FAST_CALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, UInt32 *posRes) { do @@ -214,13 +214,13 @@ to eliminate "movsx" BUG in old MSVC x64 compiler. */ -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes); -MY_NO_INLINE -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes) @@ -404,7 +404,7 @@ /* typedef UInt32 uint32plus; // size_t -UInt32 * MY_FAST_CALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, uint32plus _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes) diff -Nru 7zip-22.01+dfsg/C/LzHash.h 7zip-22.01+really25.01+dfsg/C/LzHash.h --- 7zip-22.01+dfsg/C/LzHash.h 2019-10-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzHash.h 2023-03-05 17:00:00.000000000 +0000 @@ -1,8 +1,8 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2019-10-30 : Igor Pavlov : Public domain */ +/* LzHash.h -- HASH constants for LZ algorithms +2023-03-05 : Igor Pavlov : Public domain */ -#ifndef __LZ_HASH_H -#define __LZ_HASH_H +#ifndef ZIP7_INC_LZ_HASH_H +#define ZIP7_INC_LZ_HASH_H /* (kHash2Size >= (1 << 8)) : Required diff -Nru 7zip-22.01+dfsg/C/Lzma2Dec.c 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.c --- 7zip-22.01+dfsg/C/Lzma2Dec.c 2021-02-09 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.c 2024-03-01 07:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Lzma2Dec.c -- LZMA2 Decoder -2021-02-09 : Igor Pavlov : Public domain */ +2024-03-01 : Igor Pavlov : Public domain */ /* #define SHOW_DEBUG_INFO */ @@ -71,14 +71,14 @@ SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(Lzma2Dec_GetOldProps(prop, props)) return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); } SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(Lzma2Dec_GetOldProps(prop, props)) return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); } @@ -157,8 +157,10 @@ p->decoder.prop.lp = (Byte)lp; return LZMA2_STATE_DATA; } + + default: + return LZMA2_STATE_ERROR; } - return LZMA2_STATE_ERROR; } static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) @@ -474,8 +476,8 @@ SizeT outSize = *destLen, inSize = *srcLen; *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; - Lzma2Dec_Construct(&p); - RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); + Lzma2Dec_CONSTRUCT(&p) + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)) p.decoder.dic = dest; p.decoder.dicBufSize = outSize; Lzma2Dec_Init(&p); @@ -487,3 +489,5 @@ Lzma2Dec_FreeProbs(&p, alloc); return res; } + +#undef PRF diff -Nru 7zip-22.01+dfsg/C/Lzma2Dec.h 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.h --- 7zip-22.01+dfsg/C/Lzma2Dec.h 2018-02-19 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2Dec.h 2023-03-03 12:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Lzma2Dec.h -- LZMA2 Decoder -2018-02-19 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __LZMA2_DEC_H -#define __LZMA2_DEC_H +#ifndef ZIP7_INC_LZMA2_DEC_H +#define ZIP7_INC_LZMA2_DEC_H #include "LzmaDec.h" @@ -22,9 +22,10 @@ CLzmaDec decoder; } CLzma2Dec; -#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) -#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) -#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) +#define Lzma2Dec_CONSTRUCT(p) LzmaDec_CONSTRUCT(&(p)->decoder) +#define Lzma2Dec_Construct(p) Lzma2Dec_CONSTRUCT(p) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); @@ -90,7 +91,7 @@ at current input positon. */ -#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0); +#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0) /* ---------- One Call Interface ---------- */ diff -Nru 7zip-22.01+dfsg/C/Lzma2DecMt.c 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.c --- 7zip-22.01+dfsg/C/Lzma2DecMt.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.c 2023-04-13 08:00:00.000000000 +0000 @@ -1,44 +1,44 @@ /* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread -2021-04-01 : Igor Pavlov : Public domain */ +2023-04-13 : Igor Pavlov : Public domain */ #include "Precomp.h" // #define SHOW_DEBUG_INFO - -// #define _7ZIP_ST +// #define Z7_ST #ifdef SHOW_DEBUG_INFO #include #endif -#ifndef _7ZIP_ST -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif -#define PRF_STR(s) PRF(printf("\n" s "\n")) -#define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2)) -#endif - #include "Alloc.h" #include "Lzma2Dec.h" #include "Lzma2DecMt.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "MtDec.h" #define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28) #endif +#ifndef Z7_ST +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif +#define PRF_STR(s) PRF(printf("\n" s "\n");) +#define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2);) +#endif + + void Lzma2DecMtProps_Init(CLzma2DecMtProps *p) { p->inBufSize_ST = 1 << 20; p->outStep_ST = 1 << 20; - #ifndef _7ZIP_ST + #ifndef Z7_ST p->numThreads = 1; p->inBufSize_MT = 1 << 18; p->outBlockMax = LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT; @@ -48,7 +48,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST /* ---------- CLzma2DecMtThread ---------- */ @@ -81,7 +81,7 @@ /* ---------- CLzma2DecMt ---------- */ -typedef struct +struct CLzma2DecMt { // ISzAllocPtr alloc; ISzAllocPtr allocMid; @@ -90,9 +90,9 @@ CLzma2DecMtProps props; Byte prop; - ISeqInStream *inStream; - ISeqOutStream *outStream; - ICompressProgress *progress; + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; BoolInt finishMode; BoolInt outSize_Defined; @@ -111,14 +111,13 @@ size_t inPos; size_t inLim; - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt64 outProcessed_Parse; BoolInt mtc_WasConstructed; CMtDec mtc; - CLzma2DecMtThread coders[MTDEC__THREADS_MAX]; + CLzma2DecMtThread coders[MTDEC_THREADS_MAX]; #endif - -} CLzma2DecMt; +}; @@ -142,11 +141,11 @@ // Lzma2DecMtProps_Init(&p->props); - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtc_WasConstructed = False; { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CLzma2DecMtThread *t = &p->coders[i]; t->dec_created = False; @@ -156,16 +155,16 @@ } #endif - return p; + return (CLzma2DecMtHandle)(void *)p; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt *p) { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CLzma2DecMtThread *t = &p->coders[i]; if (t->outBuf) @@ -196,13 +195,15 @@ } -void Lzma2DecMt_Destroy(CLzma2DecMtHandle pp) +// #define GET_CLzma2DecMt_p CLzma2DecMt *p = (CLzma2DecMt *)(void *)pp; + +void Lzma2DecMt_Destroy(CLzma2DecMtHandle p) { - CLzma2DecMt *p = (CLzma2DecMt *)pp; + // GET_CLzma2DecMt_p Lzma2DecMt_FreeSt(p); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtc_WasConstructed) { @@ -211,7 +212,7 @@ } { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CLzma2DecMtThread *t = &p->coders[i]; if (t->dec_created) @@ -226,19 +227,19 @@ #endif - ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, pp); + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void Lzma2DecMt_MtCallback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) { CLzma2DecMt *me = (CLzma2DecMt *)obj; CLzma2DecMtThread *t = &me->coders[coderIndex]; - PRF_STR_INT_2("Parse", coderIndex, cc->srcSize); + PRF_STR_INT_2("Parse", coderIndex, cc->srcSize) cc->state = MTDEC_PARSE_CONTINUE; @@ -246,7 +247,7 @@ { if (!t->dec_created) { - Lzma2Dec_Construct(&t->dec); + Lzma2Dec_CONSTRUCT(&t->dec) t->dec_created = True; AlignOffsetAlloc_CreateVTable(&t->alloc); { @@ -297,7 +298,7 @@ // that must be finished at position <= outBlockMax. { - const SizeT srcOrig = cc->srcSize; + const size_t srcOrig = cc->srcSize; SizeT srcSize_Point = 0; SizeT dicPos_Point = 0; @@ -306,10 +307,10 @@ for (;;) { - SizeT srcCur = srcOrig - cc->srcSize; + SizeT srcCur = (SizeT)(srcOrig - cc->srcSize); status = Lzma2Dec_Parse(&t->dec, - limit - t->dec.decoder.dicPos, + (SizeT)limit - t->dec.decoder.dicPos, cc->src + cc->srcSize, &srcCur, checkFinishBlock); @@ -333,7 +334,7 @@ if (t->dec.decoder.dicPos >= (1 << 14)) break; dicPos_Point = t->dec.decoder.dicPos; - srcSize_Point = cc->srcSize; + srcSize_Point = (SizeT)cc->srcSize; continue; } @@ -391,7 +392,7 @@ if (unpackRem != 0) { /* we also reserve space for max possible number of output bytes of current LZMA chunk */ - SizeT rem = limit - dicPos; + size_t rem = limit - dicPos; if (rem > unpackRem) rem = unpackRem; dicPos += rem; @@ -444,7 +445,7 @@ } t->dec.decoder.dic = dest; - t->dec.decoder.dicBufSize = t->outPreSize; + t->dec.decoder.dicBufSize = (SizeT)t->outPreSize; t->needInit = True; @@ -462,7 +463,7 @@ UNUSED_VAR(srcFinished) - PRF_STR_INT_2("Code", coderIndex, srcSize); + PRF_STR_INT_2("Code", coderIndex, srcSize) *inCodePos = t->inCodeSize; *outCodePos = 0; @@ -476,13 +477,13 @@ { ELzmaStatus status; - size_t srcProcessed = srcSize; + SizeT srcProcessed = (SizeT)srcSize; BoolInt blockWasFinished = ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK); SRes res = Lzma2Dec_DecodeToDic(&t->dec, - t->outPreSize, + (SizeT)t->outPreSize, src, &srcProcessed, blockWasFinished ? LZMA_FINISH_END : LZMA_FINISH_ANY, &status); @@ -540,7 +541,7 @@ UNUSED_VAR(srcSize) UNUSED_VAR(isCross) - PRF_STR_INT_2("Write", coderIndex, srcSize); + PRF_STR_INT_2("Write", coderIndex, srcSize) *needContinue = False; *canRecode = True; @@ -588,7 +589,7 @@ *needContinue = needContinue2; return SZ_OK; } - RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0)); + RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0)) } } @@ -611,11 +612,11 @@ { if (!p->dec_created) { - Lzma2Dec_Construct(&p->dec); + Lzma2Dec_CONSTRUCT(&p->dec) p->dec_created = True; } - RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt)); + RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt)) if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) { @@ -634,7 +635,7 @@ static SRes Lzma2Dec_Decode_ST(CLzma2DecMt *p - #ifndef _7ZIP_ST + #ifndef Z7_ST , BoolInt tMode #endif ) @@ -646,7 +647,7 @@ CLzma2Dec *dec; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (tMode) { Lzma2DecMt_FreeOutBufs(p); @@ -654,7 +655,7 @@ } #endif - RINOK(Lzma2Dec_Prepare_ST(p)); + RINOK(Lzma2Dec_Prepare_ST(p)) dec = &p->dec; @@ -681,7 +682,7 @@ if (inPos == inLim) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (tMode) { inData = MtDec_Read(&p->mtc, &inLim); @@ -710,7 +711,7 @@ { SizeT next = dec->decoder.dicBufSize; if (next - wrPos > p->props.outStep_ST) - next = wrPos + p->props.outStep_ST; + next = wrPos + (SizeT)p->props.outStep_ST; size = next - dicPos; } @@ -726,7 +727,7 @@ } } - inProcessed = inLim - inPos; + inProcessed = (SizeT)(inLim - inPos); res = Lzma2Dec_DecodeToDic(dec, dicPos + size, inData + inPos, &inProcessed, finishMode, &status); @@ -755,7 +756,7 @@ dec->decoder.dicPos = 0; wrPos = dec->decoder.dicPos; - RINOK(res2); + RINOK(res2) if (needStop) { @@ -788,7 +789,7 @@ UInt64 outDelta = p->outProcessed - outPrev; if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) { - RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed)); + RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed)) inPrev = p->inProcessed; outPrev = p->outProcessed; } @@ -798,20 +799,20 @@ -SRes Lzma2DecMt_Decode(CLzma2DecMtHandle pp, +SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, Byte prop, const CLzma2DecMtProps *props, - ISeqOutStream *outStream, const UInt64 *outDataSize, int finishMode, + ISeqOutStreamPtr outStream, const UInt64 *outDataSize, int finishMode, // Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, // const Byte *inData, size_t inDataSize, UInt64 *inProcessed, // UInt64 *outProcessed, int *isMT, - ICompressProgress *progress) + ICompressProgressPtr progress) { - CLzma2DecMt *p = (CLzma2DecMt *)pp; - #ifndef _7ZIP_ST + // GET_CLzma2DecMt_p + #ifndef Z7_ST BoolInt tMode; #endif @@ -845,7 +846,7 @@ *isMT = False; - #ifndef _7ZIP_ST + #ifndef Z7_ST tMode = False; @@ -939,7 +940,7 @@ p->readWasFinished = p->mtc.readWasFinished; p->inProcessed = p->mtc.inProcessed; - PRF_STR("----- decoding ST -----"); + PRF_STR("----- decoding ST -----") } } @@ -950,7 +951,7 @@ { SRes res = Lzma2Dec_Decode_ST(p - #ifndef _7ZIP_ST + #ifndef Z7_ST , tMode #endif ); @@ -967,7 +968,7 @@ res = p->readRes; /* - #ifndef _7ZIP_ST + #ifndef Z7_ST if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK) res = p->mtc.parseRes; #endif @@ -980,13 +981,13 @@ /* ---------- Read from CLzma2DecMtHandle Interface ---------- */ -SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp, +SRes Lzma2DecMt_Init(CLzma2DecMtHandle p, Byte prop, const CLzma2DecMtProps *props, const UInt64 *outDataSize, int finishMode, - ISeqInStream *inStream) + ISeqInStreamPtr inStream) { - CLzma2DecMt *p = (CLzma2DecMt *)pp; + // GET_CLzma2DecMt_p if (prop > 40) return SZ_ERROR_UNSUPPORTED; @@ -1015,11 +1016,11 @@ } -SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, +SRes Lzma2DecMt_Read(CLzma2DecMtHandle p, Byte *data, size_t *outSize, UInt64 *inStreamProcessed) { - CLzma2DecMt *p = (CLzma2DecMt *)pp; + // GET_CLzma2DecMt_p ELzmaFinishMode finishMode; SRes readRes; size_t size = *outSize; @@ -1055,8 +1056,8 @@ readRes = ISeqInStream_Read(p->inStream, p->inBuf, &p->inLim); } - inCur = p->inLim - p->inPos; - outCur = size; + inCur = (SizeT)(p->inLim - p->inPos); + outCur = (SizeT)size; res = Lzma2Dec_DecodeToBuf(&p->dec, data, &outCur, p->inBuf + p->inPos, &inCur, finishMode, &status); @@ -1088,3 +1089,7 @@ return readRes; } } + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff -Nru 7zip-22.01+dfsg/C/Lzma2DecMt.h 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.h --- 7zip-22.01+dfsg/C/Lzma2DecMt.h 2018-02-17 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2DecMt.h 2023-04-13 08:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread -2018-02-17 : Igor Pavlov : Public domain */ +2023-04-13 : Igor Pavlov : Public domain */ -#ifndef __LZMA2_DEC_MT_H -#define __LZMA2_DEC_MT_H +#ifndef ZIP7_INC_LZMA2_DEC_MT_H +#define ZIP7_INC_LZMA2_DEC_MT_H #include "7zTypes.h" @@ -13,7 +13,7 @@ size_t inBufSize_ST; size_t outStep_ST; - #ifndef _7ZIP_ST + #ifndef Z7_ST unsigned numThreads; size_t inBufSize_MT; size_t outBlockMax; @@ -38,7 +38,9 @@ SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ -typedef void * CLzma2DecMtHandle; +typedef struct CLzma2DecMt CLzma2DecMt; +typedef CLzma2DecMt * CLzma2DecMtHandle; +// Z7_DECLARE_HANDLE(CLzma2DecMtHandle) CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); void Lzma2DecMt_Destroy(CLzma2DecMtHandle p); @@ -46,11 +48,11 @@ SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, Byte prop, const CLzma2DecMtProps *props, - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, const UInt64 *outDataSize, // NULL means undefined int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished // Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, // const Byte *inData, size_t inDataSize, // out variables: @@ -58,7 +60,7 @@ int *isMT, /* out: (*isMT == 0), if single thread decoding was used */ // UInt64 *outProcessed, - ICompressProgress *progress); + ICompressProgressPtr progress); /* ---------- Read from CLzma2DecMtHandle Interface ---------- */ @@ -67,7 +69,7 @@ Byte prop, const CLzma2DecMtProps *props, const UInt64 *outDataSize, int finishMode, - ISeqInStream *inStream); + ISeqInStreamPtr inStream); SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, Byte *data, size_t *outSize, diff -Nru 7zip-22.01+dfsg/C/Lzma2Enc.c 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.c --- 7zip-22.01+dfsg/C/Lzma2Enc.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.c 2025-06-30 17:00:00.000000000 +0000 @@ -1,18 +1,18 @@ /* Lzma2Enc.c -- LZMA2 Encoder -2021-02-09 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" #include -/* #define _7ZIP_ST */ +/* #define Z7_ST */ #include "Lzma2Enc.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "MtCoder.h" #else -#define MTCODER__THREADS_MAX 1 +#define MTCODER_THREADS_MAX 1 #endif #define LZMA2_CONTROL_LZMA (1 << 7) @@ -40,7 +40,7 @@ typedef struct { ISeqInStream vt; - ISeqInStream *realStream; + ISeqInStreamPtr realStream; UInt64 limit; UInt64 processed; int finished; @@ -53,15 +53,15 @@ p->finished = 0; } -static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +static SRes LimitedSeqInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) { - CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLimitedSeqInStream) size_t size2 = *size; SRes res = SZ_OK; if (p->limit != (UInt64)(Int64)-1) { - UInt64 rem = p->limit - p->processed; + const UInt64 rem = p->limit - p->processed; if (size2 > rem) size2 = (size_t)rem; } @@ -95,8 +95,8 @@ { SizeT propsSize = LZMA_PROPS_SIZE; Byte propsEncoded[LZMA_PROPS_SIZE]; - RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)); - RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)); + RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)) + RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)) p->propsByte = propsEncoded[0]; p->propsAreSet = True; } @@ -111,23 +111,23 @@ } -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); -void LzmaEnc_Finish(CLzmaEncHandle pp); -void LzmaEnc_SaveState(CLzmaEncHandle pp); -void LzmaEnc_RestoreState(CLzmaEncHandle pp); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); /* -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp); +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p); */ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, - size_t *packSizeRes, ISeqOutStream *outStream) + size_t *packSizeRes, ISeqOutStreamPtr outStream) { size_t packSizeLimit = *packSizeRes; size_t packSize = packSizeLimit; @@ -167,7 +167,7 @@ while (unpackSize > 0) { - UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; + const UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; if (packSizeLimit - destPos < u + 3) return SZ_ERROR_OUTPUT_EOF; outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); @@ -196,9 +196,9 @@ { size_t destPos = 0; - UInt32 u = unpackSize - 1; - UInt32 pm = (UInt32)(packSize - 1); - unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); + const UInt32 u = unpackSize - 1; + const UInt32 pm = (UInt32)(packSize - 1); + const unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); PRF(printf(" ")); @@ -231,10 +231,11 @@ void Lzma2EncProps_Init(CLzma2EncProps *p) { LzmaEncProps_Init(&p->lzmaProps); - p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO; + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO; p->numBlockThreads_Reduced = -1; p->numBlockThreads_Max = -1; p->numTotalThreads = -1; + p->numThreadGroups = 0; } void Lzma2EncProps_Normalize(CLzma2EncProps *p) @@ -251,8 +252,8 @@ t2 = p->numBlockThreads_Max; t3 = p->numTotalThreads; - if (t2 > MTCODER__THREADS_MAX) - t2 = MTCODER__THREADS_MAX; + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; if (t3 <= 0) { @@ -268,8 +269,8 @@ t1 = 1; t2 = t3; } - if (t2 > MTCODER__THREADS_MAX) - t2 = MTCODER__THREADS_MAX; + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; } else if (t1 <= 0) { @@ -286,8 +287,8 @@ fileSize = p->lzmaProps.reduceSize; - if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID - && p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO + if ( p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) p->lzmaProps.reduceSize = p->blockSize; @@ -297,19 +298,19 @@ t1 = p->lzmaProps.numThreads; - if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) { t2r = t2 = 1; t3 = t1; } - else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1) + else if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO && t2 <= 1) { /* if there is no block multi-threading, we use SOLID block */ - p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID; + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; } else { - if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) { const UInt32 kMinSize = (UInt32)1 << 20; const UInt32 kMaxSize = (UInt32)1 << 28; @@ -344,7 +345,7 @@ } -static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) +static SRes Progress(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize) { return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; } @@ -352,7 +353,7 @@ /* ---------- Lzma2 ---------- */ -typedef struct +struct CLzma2Enc { Byte propEncoded; CLzma2EncProps props; @@ -363,23 +364,22 @@ ISzAllocPtr alloc; ISzAllocPtr allocBig; - CLzma2EncInt coders[MTCODER__THREADS_MAX]; + CLzma2EncInt coders[MTCODER_THREADS_MAX]; - #ifndef _7ZIP_ST + #ifndef Z7_ST - ISeqOutStream *outStream; + ISeqOutStreamPtr outStream; Byte *outBuf; size_t outBuf_Rem; /* remainder in outBuf */ size_t outBufSize; /* size of allocated outBufs[i] */ - size_t outBufsDataSizes[MTCODER__BLOCKS_MAX]; + size_t outBufsDataSizes[MTCODER_BLOCKS_MAX]; BoolInt mtCoder_WasConstructed; CMtCoder mtCoder; - Byte *outBufs[MTCODER__BLOCKS_MAX]; + Byte *outBufs[MTCODER_BLOCKS_MAX]; #endif - -} CLzma2Enc; +}; @@ -396,30 +396,30 @@ p->allocBig = allocBig; { unsigned i; - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) p->coders[i].enc = NULL; } - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtCoder_WasConstructed = False; { unsigned i; - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) p->outBufs[i] = NULL; p->outBufSize = 0; } #endif - return p; + return (CLzma2EncHandle)p; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p) { unsigned i; - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) if (p->outBufs[i]) { ISzAlloc_Free(p->alloc, p->outBufs[i]); @@ -430,12 +430,13 @@ #endif +// #define GET_CLzma2Enc_p CLzma2Enc *p = (CLzma2Enc *)(void *)p; -void Lzma2Enc_Destroy(CLzma2EncHandle pp) +void Lzma2Enc_Destroy(CLzma2EncHandle p) { - CLzma2Enc *p = (CLzma2Enc *)pp; + // GET_CLzma2Enc_p unsigned i; - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) { CLzma2EncInt *t = &p->coders[i]; if (t->enc) @@ -446,7 +447,7 @@ } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtCoder_WasConstructed) { MtCoder_Destruct(&p->mtCoder); @@ -458,13 +459,13 @@ ISzAlloc_Free(p->alloc, p->tempBufLzma); p->tempBufLzma = NULL; - ISzAlloc_Free(p->alloc, pp); + ISzAlloc_Free(p->alloc, p); } -SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props) +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props) { - CLzma2Enc *p = (CLzma2Enc *)pp; + // GET_CLzma2Enc_p CLzmaEncProps lzmaProps = props->lzmaProps; LzmaEncProps_Normalize(&lzmaProps); if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) @@ -475,16 +476,16 @@ } -void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize) { - CLzma2Enc *p = (CLzma2Enc *)pp; + // GET_CLzma2Enc_p p->expectedDataSize = expectedDataSiize; } -Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp) +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p) { - CLzma2Enc *p = (CLzma2Enc *)pp; + // GET_CLzma2Enc_p unsigned i; UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); for (i = 0; i < 40; i++) @@ -497,12 +498,12 @@ static SRes Lzma2Enc_EncodeMt1( CLzma2Enc *me, CLzma2EncInt *p, - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, const Byte *inData, size_t inDataSize, int finished, - ICompressProgress *progress) + ICompressProgressPtr progress) { UInt64 unpackTotal = 0; UInt64 packTotal = 0; @@ -540,12 +541,12 @@ } } - RINOK(Lzma2EncInt_InitStream(p, &me->props)); + RINOK(Lzma2EncInt_InitStream(p, &me->props)) for (;;) { SRes res = SZ_OK; - size_t inSizeCur = 0; + SizeT inSizeCur = 0; Lzma2EncInt_InitBlock(p); @@ -559,7 +560,7 @@ if (me->expectedDataSize != (UInt64)(Int64)-1 && me->expectedDataSize >= unpackTotal) expected = me->expectedDataSize - unpackTotal; - if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID && expected > me->props.blockSize) expected = (size_t)me->props.blockSize; @@ -569,14 +570,14 @@ &limitedInStream.vt, LZMA2_KEEP_WINDOW_SIZE, me->alloc, - me->allocBig)); + me->allocBig)) } else { - inSizeCur = inDataSize - (size_t)unpackTotal; - if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID + inSizeCur = (SizeT)(inDataSize - (size_t)unpackTotal); + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID && inSizeCur > me->props.blockSize) - inSizeCur = (size_t)me->props.blockSize; + inSizeCur = (SizeT)(size_t)me->props.blockSize; // LzmaEnc_SetDataSize(p->enc, inSizeCur); @@ -584,7 +585,7 @@ inData + (size_t)unpackTotal, inSizeCur, LZMA2_KEEP_WINDOW_SIZE, me->alloc, - me->allocBig)); + me->allocBig)) } for (;;) @@ -621,7 +622,7 @@ unpackTotal += p->srcPos; - RINOK(res); + RINOK(res) if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur)) return SZ_ERROR_FAIL; @@ -652,12 +653,12 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST -static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, +static SRes Lzma2Enc_MtCallback_Code(void *p, unsigned coderIndex, unsigned outBufIndex, const Byte *src, size_t srcSize, int finished) { - CLzma2Enc *me = (CLzma2Enc *)pp; + CLzma2Enc *me = (CLzma2Enc *)p; size_t destSize = me->outBufSize; SRes res; CMtProgressThunk progressThunk; @@ -692,9 +693,9 @@ } -static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex) +static SRes Lzma2Enc_MtCallback_Write(void *p, unsigned outBufIndex) { - CLzma2Enc *me = (CLzma2Enc *)pp; + CLzma2Enc *me = (CLzma2Enc *)p; size_t size = me->outBufsDataSizes[outBufIndex]; const Byte *data = me->outBufs[outBufIndex]; @@ -713,14 +714,14 @@ -SRes Lzma2Enc_Encode2(CLzma2EncHandle pp, - ISeqOutStream *outStream, +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStreamPtr outStream, Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, const Byte *inData, size_t inDataSize, - ICompressProgress *progress) + ICompressProgressPtr progress) { - CLzma2Enc *p = (CLzma2Enc *)pp; + // GET_CLzma2Enc_p if (inStream && inData) return SZ_ERROR_PARAM; @@ -730,11 +731,11 @@ { unsigned i; - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) p->coders[i].propsAreSet = False; } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->props.numBlockThreads_Reduced > 1) { @@ -772,7 +773,7 @@ return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ { - size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16; + const size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16; if (destBlockSize < p->mtCoder.blockSize) return SZ_ERROR_PARAM; if (p->outBufSize != destBlockSize) @@ -781,10 +782,11 @@ } p->mtCoder.numThreadsMax = (unsigned)p->props.numBlockThreads_Max; + p->mtCoder.numThreadGroups = p->props.numThreadGroups; p->mtCoder.expectedDataSize = p->expectedDataSize; { - SRes res = MtCoder_Code(&p->mtCoder); + const SRes res = MtCoder_Code(&p->mtCoder); if (!outStream) *outBufSize = (size_t)(p->outBuf - outBuf); return res; @@ -801,3 +803,5 @@ True, /* finished */ progress); } + +#undef PRF diff -Nru 7zip-22.01+dfsg/C/Lzma2Enc.h 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.h --- 7zip-22.01+dfsg/C/Lzma2Enc.h 2017-07-27 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma2Enc.h 2025-06-28 12:00:00.000000000 +0000 @@ -1,15 +1,15 @@ /* Lzma2Enc.h -- LZMA2 Encoder -2017-07-27 : Igor Pavlov : Public domain */ +2023-04-13 : Igor Pavlov : Public domain */ -#ifndef __LZMA2_ENC_H -#define __LZMA2_ENC_H +#ifndef ZIP7_INC_LZMA2_ENC_H +#define ZIP7_INC_LZMA2_ENC_H #include "LzmaEnc.h" EXTERN_C_BEGIN -#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0 -#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1) +#define LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO 0 +#define LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID ((UInt64)(Int64)-1) typedef struct { @@ -18,6 +18,7 @@ int numBlockThreads_Reduced; int numBlockThreads_Max; int numTotalThreads; + unsigned numThreadGroups; // 0 : no groups } CLzma2EncProps; void Lzma2EncProps_Init(CLzma2EncProps *p); @@ -36,7 +37,9 @@ SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ -typedef void * CLzma2EncHandle; +typedef struct CLzma2Enc CLzma2Enc; +typedef CLzma2Enc * CLzma2EncHandle; +// Z7_DECLARE_HANDLE(CLzma2EncHandle) CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); void Lzma2Enc_Destroy(CLzma2EncHandle p); @@ -44,11 +47,11 @@ void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize); Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); SRes Lzma2Enc_Encode2(CLzma2EncHandle p, - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, const Byte *inData, size_t inDataSize, - ICompressProgress *progress); + ICompressProgressPtr progress); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Lzma86.h 7zip-22.01+really25.01+dfsg/C/Lzma86.h --- 7zip-22.01+dfsg/C/Lzma86.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma86.h 2023-03-03 13:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Lzma86.h -- LZMA + x86 (BCJ) Filter -2013-01-18 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __LZMA86_H -#define __LZMA86_H +#ifndef ZIP7_INC_LZMA86_H +#define ZIP7_INC_LZMA86_H #include "7zTypes.h" diff -Nru 7zip-22.01+dfsg/C/Lzma86Dec.c 7zip-22.01+really25.01+dfsg/C/Lzma86Dec.c --- 7zip-22.01+dfsg/C/Lzma86Dec.c 2016-05-16 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma86Dec.c 2023-03-03 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2016-05-16 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -46,9 +46,8 @@ return res; if (useFilter == 1) { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(dest, *destLen, 0, &x86State, 0); + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(dest, *destLen, 0, &x86State); } return SZ_OK; } diff -Nru 7zip-22.01+dfsg/C/Lzma86Enc.c 7zip-22.01+really25.01+dfsg/C/Lzma86Enc.c --- 7zip-22.01+dfsg/C/Lzma86Enc.c 2021-01-26 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Lzma86Enc.c 2023-03-03 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2018-07-04 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -46,9 +46,8 @@ memcpy(filteredStream, src, srcLen); } { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(filteredStream, srcLen, 0, &x86State, 1); + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State); } } diff -Nru 7zip-22.01+dfsg/C/LzmaDec.c 7zip-22.01+really25.01+dfsg/C/LzmaDec.c --- 7zip-22.01+dfsg/C/LzmaDec.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaDec.c 2023-04-07 18:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2021-04-01 : Igor Pavlov : Public domain */ +2023-04-07 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -8,15 +8,15 @@ /* #include "CpuArch.h" */ #include "LzmaDec.h" -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) #define RC_INIT_SIZE 5 -#ifndef _LZMA_DEC_OPT +#ifndef Z7_LZMA_DEC_OPT #define kNumMoveBits 5 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } @@ -25,14 +25,14 @@ #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } + { UPDATE_0(p) i = (i + i); A0; } else \ + { UPDATE_1(p) i = (i + i) + 1; A1; } #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ - { UPDATE_0(p + i); A0; } else \ - { UPDATE_1(p + i); A1; } + { UPDATE_0(p + i) A0; } else \ + { UPDATE_1(p + i) A1; } #define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) @@ -40,19 +40,19 @@ #define TREE_DECODE(probs, limit, i) \ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -/* #define _LZMA_SIZE_OPT */ +/* #define Z7_LZMA_SIZE_OPT */ -#ifdef _LZMA_SIZE_OPT +#ifdef Z7_LZMA_SIZE_OPT #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) #else #define TREE_6_DECODE(probs, i) \ { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ i -= 0x40; } #endif @@ -64,25 +64,25 @@ probLit = prob + (offs + bit + symbol); \ GET_BIT2(probLit, symbol, offs ^= bit; , ;) -#endif // _LZMA_DEC_OPT +#endif // Z7_LZMA_DEC_OPT #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); } -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) #define UPDATE_0_CHECK range = bound; #define UPDATE_1_CHECK range -= bound; code -= bound; #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } + { UPDATE_0_CHECK i = (i + i); A0; } else \ + { UPDATE_1_CHECK i = (i + i) + 1; A1; } #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) #define TREE_DECODE_CHECK(probs, limit, i) \ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ - { UPDATE_0_CHECK; i += m; m += m; } else \ - { UPDATE_1_CHECK; m += m; i += m; } + { UPDATE_0_CHECK i += m; m += m; } else \ + { UPDATE_1_CHECK m += m; i += m; } #define kNumPosBitsMax 4 @@ -224,14 +224,14 @@ */ -#ifdef _LZMA_DEC_OPT +#ifdef Z7_LZMA_DEC_OPT -int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); #else static -int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { CLzmaProb *probs = GET_PROBS; unsigned state = (unsigned)p->state; @@ -263,7 +263,7 @@ IF_BIT_0(prob) { unsigned symbol; - UPDATE_0(prob); + UPDATE_0(prob) prob = probs + Literal; if (processedPos != 0 || checkDicSize != 0) prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); @@ -273,7 +273,7 @@ { state -= (state < 4) ? state : 3; symbol = 1; - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT do { NORMAL_LITER_DEC } while (symbol < 0x100); #else NORMAL_LITER_DEC @@ -292,7 +292,7 @@ unsigned offs = 0x100; state -= (state < 10) ? 3 : 6; symbol = 1; - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT do { unsigned bit; @@ -321,25 +321,25 @@ } { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRep + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) state += kNumStates; prob = probs + LenCoder; } else { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG0 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) prob = probs + IsRep0Long + COMBINED_PS_STATE; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) // that case was checked before with kBadRepCode // if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; } @@ -353,30 +353,30 @@ state = state < kNumLitStates ? 9 : 11; continue; } - UPDATE_1(prob); + UPDATE_1(prob) } else { UInt32 distance; - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG1 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) distance = rep1; } else { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG2 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) distance = rep2; } else { - UPDATE_1(prob); + UPDATE_1(prob) distance = rep3; rep3 = rep2; } @@ -389,37 +389,37 @@ prob = probs + RepLenCoder; } - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT { unsigned lim, offset; CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE; offset = 0; lim = (1 << kLenNumLowBits); } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenChoice2; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); offset = kLenNumLowSymbols; lim = (1 << kLenNumLowBits); } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenHigh; offset = kLenNumLowSymbols * 2; lim = (1 << kLenNumHighBits); } } - TREE_DECODE(probLen, lim, len); + TREE_DECODE(probLen, lim, len) len += offset; } #else @@ -427,32 +427,32 @@ CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE; len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) len -= 8; } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenChoice2; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenHigh; - TREE_DECODE(probLen, (1 << kLenNumHighBits), len); + TREE_DECODE(probLen, (1 << kLenNumHighBits), len) len += kLenNumLowSymbols * 2; } } @@ -464,7 +464,7 @@ UInt32 distance; prob = probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); + TREE_6_DECODE(prob, distance) if (distance >= kStartPosModelIndex) { unsigned posSlot = (unsigned)distance; @@ -479,7 +479,7 @@ distance++; do { - REV_BIT_VAR(prob, distance, m); + REV_BIT_VAR(prob, distance, m) } while (--numDirectBits); distance -= m; @@ -514,10 +514,10 @@ distance <<= kNumAlignBits; { unsigned i = 1; - REV_BIT_CONST(prob, i, 1); - REV_BIT_CONST(prob, i, 2); - REV_BIT_CONST(prob, i, 4); - REV_BIT_LAST (prob, i, 8); + REV_BIT_CONST(prob, i, 1) + REV_BIT_CONST(prob, i, 2) + REV_BIT_CONST(prob, i, 4) + REV_BIT_LAST (prob, i, 8) distance |= i; } if (distance == (UInt32)0xFFFFFFFF) @@ -592,7 +592,7 @@ } while (dicPos < limit && buf < bufLimit); - NORMALIZE; + NORMALIZE p->buf = buf; p->range = range; @@ -613,7 +613,7 @@ -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) { unsigned len = (unsigned)p->remainLen; if (len == 0 /* || len >= kMatchSpecLenStart */) @@ -683,7 +683,7 @@ (p->checkDicSize == p->prop.dicSize) */ -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { if (p->checkDicSize == 0) { @@ -767,54 +767,54 @@ else { unsigned len; - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRep + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK state = 0; prob = probs + LenCoder; res = DUMMY_MATCH; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK res = DUMMY_REP; prob = probs + IsRepG0 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK prob = probs + IsRep0Long + COMBINED_PS_STATE; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK break; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRepG1 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRepG2 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } } } @@ -826,31 +826,31 @@ const CLzmaProb *probLen = prob + LenChoice; IF_BIT_0_CHECK(probLen) { - UPDATE_0_CHECK; + UPDATE_0_CHECK probLen = prob + LenLow + GET_LEN_STATE; offset = 0; limit = 1 << kLenNumLowBits; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK probLen = prob + LenChoice2; IF_BIT_0_CHECK(probLen) { - UPDATE_0_CHECK; + UPDATE_0_CHECK probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); offset = kLenNumLowSymbols; limit = 1 << kLenNumLowBits; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK probLen = prob + LenHigh; offset = kLenNumLowSymbols * 2; limit = 1 << kLenNumHighBits; } } - TREE_DECODE_CHECK(probLen, limit, len); + TREE_DECODE_CHECK(probLen, limit, len) len += offset; } @@ -860,7 +860,7 @@ prob = probs + PosSlot + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot) if (posSlot >= kStartPosModelIndex) { unsigned numDirectBits = ((posSlot >> 1) - 1); @@ -888,7 +888,7 @@ unsigned m = 1; do { - REV_BIT_CHECK(prob, i, m); + REV_BIT_CHECK(prob, i, m) } while (--numDirectBits); } @@ -897,7 +897,7 @@ } break; } - NORMALIZE_CHECK; + NORMALIZE_CHECK *bufOut = buf; return res; @@ -943,7 +943,7 @@ */ -#define RETURN__NOT_FINISHED__FOR_FINISH \ +#define RETURN_NOT_FINISHED_FOR_FINISH \ *status = LZMA_STATUS_NOT_FINISHED; \ return SZ_ERROR_DATA; // for strict mode // return SZ_OK; // for relaxed mode @@ -1029,7 +1029,7 @@ } if (p->remainLen != 0) { - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } checkEndMarkNow = 1; } @@ -1072,7 +1072,7 @@ for (i = 0; i < (unsigned)dummyProcessed; i++) p->tempBuf[i] = src[i]; // p->remainLen = kMatchSpecLen_Error_Data; - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } bufLimit = src; @@ -1150,7 +1150,7 @@ (*srcLen) += (unsigned)dummyProcessed - p->tempBufSize; p->tempBufSize = (unsigned)dummyProcessed; // p->remainLen = kMatchSpecLen_Error_Data; - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } } @@ -1299,8 +1299,8 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) { CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) p->prop = propNew; return SZ_OK; } @@ -1309,14 +1309,14 @@ { CLzmaProps propNew; SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) { UInt32 dictSize = propNew.dicSize; SizeT mask = ((UInt32)1 << 12) - 1; if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; - else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1; dicBufSize = ((SizeT)dictSize + mask) & ~mask; if (dicBufSize < dictSize) dicBufSize = dictSize; @@ -1348,8 +1348,8 @@ *status = LZMA_STATUS_NOT_SPECIFIED; if (inSize < RC_INIT_SIZE) return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); + LzmaDec_CONSTRUCT(&p) + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)) p.dic = dest; p.dicBufSize = outSize; LzmaDec_Init(&p); diff -Nru 7zip-22.01+dfsg/C/LzmaDec.h 7zip-22.01+really25.01+dfsg/C/LzmaDec.h --- 7zip-22.01+dfsg/C/LzmaDec.h 2020-03-19 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaDec.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,19 +1,19 @@ /* LzmaDec.h -- LZMA Decoder -2020-03-19 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H +#ifndef ZIP7_INC_LZMA_DEC_H +#define ZIP7_INC_LZMA_DEC_H #include "7zTypes.h" EXTERN_C_BEGIN -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, +/* #define Z7_LZMA_PROB32 */ +/* Z7_LZMA_PROB32 can increase the speed on some CPUs, but memory usage for CLzmaDec::probs will be doubled in that case */ typedef -#ifdef _LZMA_PROB32 +#ifdef Z7_LZMA_PROB32 UInt32 #else UInt16 @@ -25,7 +25,7 @@ #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaProps +typedef struct { Byte lc; Byte lp; @@ -73,7 +73,8 @@ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; } CLzmaDec; -#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p) void LzmaDec_Init(CLzmaDec *p); diff -Nru 7zip-22.01+dfsg/C/LzmaEnc.c 7zip-22.01+really25.01+dfsg/C/LzmaEnc.c --- 7zip-22.01+dfsg/C/LzmaEnc.c 2022-07-15 06:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaEnc.c 2025-05-11 14:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2022-07-15: Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ #include "Precomp.h" @@ -16,22 +16,22 @@ #include "LzmaEnc.h" #include "LzFind.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "LzFindMt.h" #endif /* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */ -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); -void LzmaEnc_Finish(CLzmaEncHandle pp); -void LzmaEnc_SaveState(CLzmaEncHandle pp); -void LzmaEnc_RestoreState(CLzmaEncHandle pp); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); #ifdef SHOW_STAT static unsigned g_STAT_OFFSET = 0; @@ -40,8 +40,8 @@ /* for good normalization speed we still reserve 256 MB before 4 GB range */ #define kLzmaMaxHistorySize ((UInt32)15 << 28) -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) @@ -60,8 +60,11 @@ p->dictSize = p->mc = 0; p->reduceSize = (UInt64)(Int64)-1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->numHashOutBits = 0; p->writeEndMark = 0; + p->affinityGroup = -1; p->affinity = 0; + p->affinityInGroup = 0; } void LzmaEncProps_Normalize(CLzmaEncProps *p) @@ -71,11 +74,11 @@ p->level = level; if (p->dictSize == 0) - p->dictSize = - ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : - ( level <= 6 ? ((UInt32)1 << (level + 19)) : - ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) - ))); + p->dictSize = (unsigned)level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + (unsigned)level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); if (p->dictSize > p->reduceSize) { @@ -91,15 +94,15 @@ if (p->lp < 0) p->lp = 0; if (p->pb < 0) p->pb = 2; - if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); - if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1; + if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64; if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5); if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1); if (p->numThreads < 0) p->numThreads = - #ifndef _7ZIP_ST + #ifndef Z7_ST ((p->btMode && p->algo) ? 2 : 1); #else 1; @@ -194,11 +197,11 @@ unsigned GetPosSlot1(UInt32 pos) { unsigned res; - BSR2_RET(pos, res); + BSR2_RET(pos, res) return res; } -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res) } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) } #else // ! LZMA_LOG_BSR @@ -293,7 +296,7 @@ #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) typedef -#ifdef _LZMA_PROB32 +#ifdef Z7_LZMA_PROB32 UInt32 #else UInt16 @@ -350,7 +353,7 @@ Byte *buf; Byte *bufLim; Byte *bufBase; - ISeqOutStream *outStream; + ISeqOutStreamPtr outStream; UInt64 processed; SRes res; } CRangeEnc; @@ -383,7 +386,7 @@ typedef UInt32 CProbPrice; -typedef struct +struct CLzmaEnc { void *matchFinderObj; IMatchFinder2 matchFinder; @@ -426,7 +429,7 @@ UInt32 dictSize; SRes result; - #ifndef _7ZIP_ST + #ifndef Z7_ST BoolInt mtMode; // begin of CMatchFinderMt is used in LZ thread CMatchFinderMt matchFinderMt; @@ -439,7 +442,7 @@ // we suppose that we have 8-bytes alignment after CMatchFinder - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte pad[128]; #endif @@ -479,77 +482,59 @@ CSaveState saveState; // BoolInt mf_Failure; - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte pad2[128]; #endif -} CLzmaEnc; +}; #define MFB (p->matchFinderBase) /* -#ifndef _7ZIP_ST +#ifndef Z7_ST #define MFB (p->matchFinderMt.MatchFinder) #endif */ -#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr)); +// #define GET_CLzmaEnc_p CLzmaEnc *p = (CLzmaEnc*)(void *)p; +// #define GET_const_CLzmaEnc_p const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p; -void LzmaEnc_SaveState(CLzmaEncHandle pp) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - CSaveState *dest = &p->saveState; - - dest->state = p->state; - - dest->lenProbs = p->lenProbs; - dest->repLenProbs = p->repLenProbs; - - COPY_ARR(dest, p, reps); +#define COPY_ARR(dest, src, arr) memcpy((dest)->arr, (src)->arr, sizeof((src)->arr)); - COPY_ARR(dest, p, posAlignEncoder); - COPY_ARR(dest, p, isRep); - COPY_ARR(dest, p, isRepG0); - COPY_ARR(dest, p, isRepG1); - COPY_ARR(dest, p, isRepG2); - COPY_ARR(dest, p, isMatch); - COPY_ARR(dest, p, isRep0Long); - COPY_ARR(dest, p, posSlotEncoder); - COPY_ARR(dest, p, posEncoders); +#define COPY_LZMA_ENC_STATE(d, s, p) \ + (d)->state = (s)->state; \ + COPY_ARR(d, s, reps) \ + COPY_ARR(d, s, posAlignEncoder) \ + COPY_ARR(d, s, isRep) \ + COPY_ARR(d, s, isRepG0) \ + COPY_ARR(d, s, isRepG1) \ + COPY_ARR(d, s, isRepG2) \ + COPY_ARR(d, s, isMatch) \ + COPY_ARR(d, s, isRep0Long) \ + COPY_ARR(d, s, posSlotEncoder) \ + COPY_ARR(d, s, posEncoders) \ + (d)->lenProbs = (s)->lenProbs; \ + (d)->repLenProbs = (s)->repLenProbs; \ + memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp); - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb)); +void LzmaEnc_SaveState(CLzmaEncHandle p) +{ + // GET_CLzmaEnc_p + CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(v, p, p) } - -void LzmaEnc_RestoreState(CLzmaEncHandle pp) +void LzmaEnc_RestoreState(CLzmaEncHandle p) { - CLzmaEnc *dest = (CLzmaEnc *)pp; - const CSaveState *p = &dest->saveState; - - dest->state = p->state; - - dest->lenProbs = p->lenProbs; - dest->repLenProbs = p->repLenProbs; - - COPY_ARR(dest, p, reps); - - COPY_ARR(dest, p, posAlignEncoder); - COPY_ARR(dest, p, isRep); - COPY_ARR(dest, p, isRepG0); - COPY_ARR(dest, p, isRepG1); - COPY_ARR(dest, p, isRepG2); - COPY_ARR(dest, p, isMatch); - COPY_ARR(dest, p, isRep0Long); - COPY_ARR(dest, p, posSlotEncoder); - COPY_ARR(dest, p, posEncoders); - - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb)); + // GET_CLzmaEnc_p + const CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(p, v, p) } - -SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +Z7_NO_INLINE +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2) { - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p CLzmaEncProps props = *props2; LzmaEncProps_Normalize(&props); @@ -585,6 +570,7 @@ p->fastMode = (props.algo == 0); // p->_maxMode = True; MFB.btMode = (Byte)(props.btMode ? 1 : 0); + // MFB.btMode = (Byte)(props.btMode); { unsigned numHashBytes = 4; if (props.btMode) @@ -595,13 +581,15 @@ if (props.numHashBytes >= 5) numHashBytes = 5; MFB.numHashBytes = numHashBytes; + // MFB.numHashBytes_Min = 2; + MFB.numHashOutBits = (Byte)props.numHashOutBits; } MFB.cutValue = props.mc; p->writeEndMark = (BoolInt)props.writeEndMark; - #ifndef _7ZIP_ST + #ifndef Z7_ST /* if (newMultiThread != _multiThread) { @@ -612,15 +600,19 @@ p->multiThread = (props.numThreads > 1); p->matchFinderMt.btSync.affinity = p->matchFinderMt.hashSync.affinity = props.affinity; + p->matchFinderMt.btSync.affinityGroup = + p->matchFinderMt.hashSync.affinityGroup = props.affinityGroup; + p->matchFinderMt.btSync.affinityInGroup = + p->matchFinderMt.hashSync.affinityInGroup = props.affinityInGroup; #endif return SZ_OK; } -void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize) { - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p MFB.expectedDataSize = expectedDataSiize; } @@ -684,7 +676,7 @@ p->res = SZ_OK; } -MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) +Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) { const size_t num = (size_t)(p->buf - p->bufBase); if (p->res == SZ_OK) @@ -696,7 +688,7 @@ p->buf = p->bufBase; } -MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p) { UInt32 low = (UInt32)p->low; unsigned high = (unsigned)(p->low >> 32); @@ -741,9 +733,9 @@ ttt = *(prob); \ newBound = (range >> kNumBitModelTotalBits) * ttt; -// #define _LZMA_ENC_USE_BRANCH +// #define Z7_LZMA_ENC_USE_BRANCH -#ifdef _LZMA_ENC_USE_BRANCH +#ifdef Z7_LZMA_ENC_USE_BRANCH #define RC_BIT(p, prob, bit) { \ RC_BIT_PRE(p, prob) \ @@ -811,7 +803,7 @@ CLzmaProb *prob = probs + (sym >> 8); UInt32 bit = (sym >> 7) & 1; sym <<= 1; - RC_BIT(p, prob, bit); + RC_BIT(p, prob, bit) } while (sym < 0x10000); p->range = range; @@ -833,7 +825,7 @@ bit = (sym >> 7) & 1; sym <<= 1; offs &= ~(matchByte ^ sym); - RC_BIT(p, prob, bit); + RC_BIT(p, prob, bit) } while (sym < 0x10000); p->range = range; @@ -867,10 +859,10 @@ #define GET_PRICE(prob, bit) \ - p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] #define GET_PRICEa(prob, bit) \ - ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] @@ -921,7 +913,7 @@ unsigned bit = sym & 1; // RangeEnc_EncodeBit(rc, probs + m, bit); sym >>= 1; - RC_BIT(rc, probs + m, bit); + RC_BIT(rc, probs + m, bit) m = (m << 1) | bit; } while (--numBits); @@ -944,15 +936,15 @@ UInt32 range, ttt, newBound; CLzmaProb *probs = p->low; range = rc->range; - RC_BIT_PRE(rc, probs); + RC_BIT_PRE(rc, probs) if (sym >= kLenNumLowSymbols) { - RC_BIT_1(rc, probs); + RC_BIT_1(rc, probs) probs += kLenNumLowSymbols; - RC_BIT_PRE(rc, probs); + RC_BIT_PRE(rc, probs) if (sym >= kLenNumLowSymbols * 2) { - RC_BIT_1(rc, probs); + RC_BIT_1(rc, probs) rc->range = range; // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2); LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2); @@ -965,11 +957,11 @@ { unsigned m; unsigned bit; - RC_BIT_0(rc, probs); + RC_BIT_0(rc, probs) probs += (posState << (1 + kLenNumLowBits)); - bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit; - bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit; - bit = sym & 1; RC_BIT(rc, probs + m, bit); + bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit) m = (1 << 1) + bit; + bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit) m = (m << 1) + bit; + bit = sym & 1; RC_BIT(rc, probs + m, bit) rc->range = range; } } @@ -990,7 +982,7 @@ } -MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTables( +Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables( CLenPriceEnc *p, unsigned numPosStates, const CLenEnc *enc, @@ -1054,14 +1046,14 @@ UInt32 price = b; do { - unsigned bit = sym & 1; + const unsigned bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); } while (sym >= 2); { - unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))]; + const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))]; prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob); prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob); } @@ -1070,7 +1062,7 @@ { unsigned posState; - size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]); + const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]); for (posState = 1; posState < numPosStates; posState++) memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num); } @@ -1152,7 +1144,7 @@ + GET_PRICE_1(p->isRep[state]) \ + GET_PRICE_0(p->isRepG0[state]) -MY_FORCE_INLINE +Z7_FORCE_INLINE static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState) { UInt32 price; @@ -1331,7 +1323,7 @@ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); } - MakeAs_Lit(&p->opt[1]); + MakeAs_Lit(&p->opt[1]) matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); @@ -1343,7 +1335,7 @@ if (shortRepPrice < p->opt[1].price) { p->opt[1].price = shortRepPrice; - MakeAs_ShortRep(&p->opt[1]); + MakeAs_ShortRep(&p->opt[1]) } if (last < 2) { @@ -1410,7 +1402,7 @@ else { unsigned slot; - GetPosSlot2(dist, slot); + GetPosSlot2(dist, slot) price += p->alignPrices[dist & kAlignMask]; price += p->posSlotPrices[lenToPosState][slot]; } @@ -1486,7 +1478,7 @@ unsigned delta = best - cur; if (delta != 0) { - MOVE_POS(p, delta); + MOVE_POS(p, delta) } } cur = best; @@ -1633,7 +1625,7 @@ { nextOpt->price = litPrice; nextOpt->len = 1; - MakeAs_Lit(nextOpt); + MakeAs_Lit(nextOpt) nextIsLit = True; } } @@ -1667,7 +1659,7 @@ { nextOpt->price = shortRepPrice; nextOpt->len = 1; - MakeAs_ShortRep(nextOpt); + MakeAs_ShortRep(nextOpt) nextIsLit = False; } } @@ -1871,7 +1863,7 @@ dist = MATCHES[(size_t)offs + 1]; // if (dist >= kNumFullDistances) - GetPosSlot2(dist, posSlot); + GetPosSlot2(dist, posSlot) for (len = /*2*/ startLen; ; len++) { @@ -1962,7 +1954,7 @@ break; dist = MATCHES[(size_t)offs + 1]; // if (dist >= kNumFullDistances) - GetPosSlot2(dist, posSlot); + GetPosSlot2(dist, posSlot) } } } @@ -2138,7 +2130,7 @@ { UInt32 ttt, newBound; RC_BIT_PRE(p, probs + m) - RC_BIT_1(&p->rc, probs + m); + RC_BIT_1(&p->rc, probs + m) m = (m << 1) + 1; } while (m < (1 << kNumPosSlotBits)); @@ -2163,7 +2155,7 @@ { UInt32 ttt, newBound; RC_BIT_PRE(p, probs + m) - RC_BIT_1(&p->rc, probs + m); + RC_BIT_1(&p->rc, probs + m) m = (m << 1) + 1; } while (m < kAlignTableSize); @@ -2179,7 +2171,7 @@ if (p->rc.res != SZ_OK) p->result = SZ_ERROR_WRITE; - #ifndef _7ZIP_ST + #ifndef Z7_ST if ( // p->mf_Failure || (p->mtMode && @@ -2187,7 +2179,7 @@ p->matchFinderMt.failure_LZ_BT)) ) { - p->result = MY_HRES_ERROR__INTERNAL_ERROR; + p->result = MY_HRES_ERROR_INTERNAL_ERROR; // printf("\nCheckErrors p->matchFinderMt.failureLZ\n"); } #endif @@ -2201,7 +2193,7 @@ } -MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) { /* ReleaseMFStream(); */ p->finished = True; @@ -2213,7 +2205,7 @@ } -MY_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) +Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) { unsigned i; const CProbPrice *ProbPrices = p->ProbPrices; @@ -2237,7 +2229,7 @@ } -MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) +Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) { // int y; for (y = 0; y < 100; y++) { @@ -2337,7 +2329,7 @@ RangeEnc_Construct(&p->rc); MatchFinder_Construct(&MFB); - #ifndef _7ZIP_ST + #ifndef Z7_ST p->matchFinderMt.MatchFinder = &MFB; MatchFinderMt_Construct(&p->matchFinderMt); #endif @@ -2345,7 +2337,7 @@ { CLzmaEncProps props; LzmaEncProps_Init(&props); - LzmaEnc_SetProps(p, &props); + LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props); } #ifndef LZMA_LOG_BSR @@ -2376,7 +2368,7 @@ static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - #ifndef _7ZIP_ST + #ifndef Z7_ST MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); #endif @@ -2387,21 +2379,22 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + // GET_CLzmaEnc_p + LzmaEnc_Destruct(p, alloc, allocBig); ISzAlloc_Free(alloc, p); } -MY_NO_INLINE +Z7_NO_INLINE static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize) { UInt32 nowPos32, startPos32; if (p->needInit) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtMode) { - RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)); + RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)) } #endif p->matchFinder.Init(p->matchFinderObj); @@ -2410,7 +2403,7 @@ if (p->finished) return p->result; - RINOK(CheckErrors(p)); + RINOK(CheckErrors(p)) nowPos32 = (UInt32)p->nowPos64; startPos32 = nowPos32; @@ -2473,7 +2466,7 @@ const Byte *data; unsigned state; - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) p->rc.range = range; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; probs = LIT_PROBS(nowPos32, *(data - 1)); @@ -2487,53 +2480,53 @@ } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRep[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist < LZMA_NUM_REPS) { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG0[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 0) { - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) probs = &p->isRep0Long[p->state][posState]; RC_BIT_PRE(&p->rc, probs) if (len != 1) { - RC_BIT_1_BASE(&p->rc, probs); + RC_BIT_1_BASE(&p->rc, probs) } else { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) p->state = kShortRepNextStates[p->state]; } } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG1[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 1) { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) dist = p->reps[1]; } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG2[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 2) { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) dist = p->reps[2]; } else { - RC_BIT_1_BASE(&p->rc, probs); + RC_BIT_1_BASE(&p->rc, probs) dist = p->reps[3]; p->reps[3] = p->reps[2]; } @@ -2557,7 +2550,7 @@ else { unsigned posSlot; - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) p->rc.range = range; p->state = kMatchNextStates[p->state]; @@ -2571,7 +2564,7 @@ p->reps[0] = dist + 1; p->matchPriceCount++; - GetPosSlot(dist, posSlot); + GetPosSlot(dist, posSlot) // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot); { UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits); @@ -2582,7 +2575,7 @@ CLzmaProb *prob = probs + (sym >> kNumPosSlotBits); UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1; sym <<= 1; - RC_BIT(&p->rc, prob, bit); + RC_BIT(&p->rc, prob, bit) } while (sym < (1 << kNumPosSlotBits * 2)); p->rc.range = range; @@ -2626,10 +2619,10 @@ { unsigned m = 1; unsigned bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) p->rc.range = range; // p->alignPriceCount++; } @@ -2704,17 +2697,17 @@ if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0)); #endif { - unsigned lclp = p->lc + p->lp; + const unsigned lclp = p->lc + p->lp; if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) { LzmaEnc_FreeLits(p, alloc); - p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); - p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); if (!p->litProbs || !p->saveState.litProbs) { LzmaEnc_FreeLits(p, alloc); @@ -2748,15 +2741,14 @@ (numFastBytes + LZMA_MATCH_LEN_MAX + 1) */ - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtMode) { RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */ - , allocBig)); + , allocBig)) p->matchFinderObj = &p->matchFinderMt; - MFB.bigHash = (Byte)( - (p->dictSize > kBigHashDicLimit && MFB.hashMask >= 0xFFFFFF) ? 1 : 0); + MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0); MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); } else @@ -2816,8 +2808,8 @@ } { - UInt32 num = (UInt32)0x300 << (p->lp + p->lc); - UInt32 k; + const size_t num = (size_t)0x300 << (p->lp + p->lc); + size_t k; CLzmaProb *probs = p->litProbs; for (k = 0; k < num; k++) probs[k] = kProbInitValue; @@ -2872,59 +2864,53 @@ p->finished = False; p->result = SZ_OK; - RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + p->nowPos64 = 0; + p->needInit = 1; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)) LzmaEnc_Init(p); LzmaEnc_InitPrices(p); - p->nowPos64 = 0; return SZ_OK; } -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, +static SRes LzmaEnc_Prepare(CLzmaEncHandle p, + ISeqOutStreamPtr outStream, + ISeqInStreamPtr inStream, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - MFB.stream = inStream; - p->needInit = 1; + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) p->rc.outStream = outStream; return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); } -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, - ISeqInStream *inStream, UInt32 keepWindowSize, +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, + ISeqInStreamPtr inStream, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - MFB.stream = inStream; - p->needInit = 1; + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -{ - MFB.directInput = 1; - MFB.bufferBase = (Byte *)src; - MFB.directInputRem = srcLen; -} - -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, + const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - LzmaEnc_SetInputBuf(p, src, srcLen); - p->needInit = 1; - - LzmaEnc_SetDataSize(pp, srcLen); + // GET_CLzmaEnc_p + MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen) + LzmaEnc_SetDataSize(p, srcLen); return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -void LzmaEnc_Finish(CLzmaEncHandle pp) +void LzmaEnc_Finish(CLzmaEncHandle p) { - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; + #ifndef Z7_ST + // GET_CLzmaEnc_p if (p->mtMode) MatchFinderMt_ReleaseStream(&p->matchFinderMt); #else - UNUSED_VAR(pp); + UNUSED_VAR(p) #endif } @@ -2933,13 +2919,13 @@ { ISeqOutStream vt; Byte *data; - SizeT rem; + size_t rem; BoolInt overflow; } CLzmaEnc_SeqOutStreamBuf; -static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size) +static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size) { - CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf) if (p->rem < size) { size = p->rem; @@ -2956,25 +2942,25 @@ /* -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + GET_const_CLzmaEnc_p return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); } */ -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_const_CLzmaEnc_p return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; } // (desiredPackSize == 0) is not allowed -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) { - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p UInt64 nowPos64; SRes res; CLzmaEnc_SeqOutStreamBuf outStream; @@ -3006,12 +2992,12 @@ } -MY_NO_INLINE -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) +Z7_NO_INLINE +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress) { SRes res = SZ_OK; - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte allocaDummy[0x300]; allocaDummy[0] = 0; allocaDummy[1] = allocaDummy[0]; @@ -3033,7 +3019,7 @@ } } - LzmaEnc_Finish(p); + LzmaEnc_Finish((CLzmaEncHandle)(void *)p); /* if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB)) @@ -3045,21 +3031,22 @@ } -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); + // GET_CLzmaEnc_p + RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig)) + return LzmaEnc_Encode2(p, progress); } -SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size) { if (*size < LZMA_PROPS_SIZE) return SZ_ERROR_PARAM; *size = LZMA_PROPS_SIZE; { - const CLzmaEnc *p = (const CLzmaEnc *)pp; + // GET_CLzmaEnc_p const UInt32 dictSize = p->dictSize; UInt32 v; props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); @@ -3083,23 +3070,24 @@ while (v < dictSize); } - SetUi32(props + 1, v); + SetUi32(props + 1, v) return SZ_OK; } } -unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp) +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p) { - return (unsigned)((CLzmaEnc *)pp)->writeEndMark; + // GET_CLzmaEnc_p + return (unsigned)p->writeEndMark; } -SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { SRes res; - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p CLzmaEnc_SeqOutStreamBuf outStream; @@ -3111,7 +3099,7 @@ p->writeEndMark = writeEndMark; p->rc.outStream = &outStream.vt; - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); + res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig); if (res == SZ_OK) { @@ -3120,7 +3108,7 @@ res = SZ_ERROR_FAIL; } - *destLen -= outStream.rem; + *destLen -= (SizeT)outStream.rem; if (outStream.overflow) return SZ_ERROR_OUTPUT_EOF; return res; @@ -3129,9 +3117,9 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + CLzmaEncHandle p = LzmaEnc_Create(alloc); SRes res; if (!p) return SZ_ERROR_MEM; @@ -3151,10 +3139,10 @@ /* -#ifndef _7ZIP_ST -void LzmaEnc_GetLzThreads(CLzmaEncHandle pp, HANDLE lz_threads[2]) +#ifndef Z7_ST +void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2]) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + GET_const_CLzmaEnc_p lz_threads[0] = p->matchFinderMt.hashSync.thread; lz_threads[1] = p->matchFinderMt.btSync.thread; } diff -Nru 7zip-22.01+dfsg/C/LzmaEnc.h 7zip-22.01+really25.01+dfsg/C/LzmaEnc.h --- 7zip-22.01+dfsg/C/LzmaEnc.h 2019-10-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaEnc.h 2025-05-10 07:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* LzmaEnc.h -- LZMA Encoder -2019-10-30 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H +#ifndef ZIP7_INC_LZMA_ENC_H +#define ZIP7_INC_LZMA_ENC_H #include "7zTypes.h" @@ -10,7 +10,7 @@ #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaEncProps +typedef struct { int level; /* 0 <= level <= 9 */ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version @@ -23,14 +23,19 @@ int fb; /* 5 <= fb <= 273, default = 32 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int numHashBytes; /* 2, 3 or 4, default = 4 */ + unsigned numHashOutBits; /* default = ? */ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ int numThreads; /* 1 or 2, default = 2 */ + // int _pad; + Int32 affinityGroup; + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. Encoder uses this value to reduce dictionary size */ UInt64 affinity; + UInt64 affinityInGroup; } CLzmaEncProps; void LzmaEncProps_Init(CLzmaEncProps *p); @@ -51,7 +56,9 @@ SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ -typedef void * CLzmaEncHandle; +typedef struct CLzmaEnc CLzmaEnc; +typedef CLzmaEnc * CLzmaEncHandle; +// Z7_DECLARE_HANDLE(CLzmaEncHandle) CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); @@ -61,17 +68,17 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); -SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); /* ---------- One Call Interface ---------- */ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/LzmaLib.c 7zip-22.01+really25.01+dfsg/C/LzmaLib.c --- 7zip-22.01+dfsg/C/LzmaLib.c 2015-06-13 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaLib.c 2023-04-02 12:00:00.000000000 +0000 @@ -1,12 +1,14 @@ /* LzmaLib.c -- LZMA library wrapper -2015-06-13 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "Alloc.h" #include "LzmaDec.h" #include "LzmaEnc.h" #include "LzmaLib.h" -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, unsigned char *outProps, size_t *outPropsSize, int level, /* 0 <= level <= 9, default = 5 */ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ @@ -32,7 +34,7 @@ } -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, const unsigned char *props, size_t propsSize) { ELzmaStatus status; diff -Nru 7zip-22.01+dfsg/C/LzmaLib.h 7zip-22.01+really25.01+dfsg/C/LzmaLib.h --- 7zip-22.01+dfsg/C/LzmaLib.h 2021-04-03 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/LzmaLib.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,14 +1,14 @@ /* LzmaLib.h -- LZMA library interface -2021-04-03 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __LZMA_LIB_H -#define __LZMA_LIB_H +#ifndef ZIP7_INC_LZMA_LIB_H +#define ZIP7_INC_LZMA_LIB_H #include "7zTypes.h" EXTERN_C_BEGIN -#define MY_STDAPI int MY_STD_CALL +#define Z7_STDAPI int Z7_STDCALL #define LZMA_PROPS_SIZE 5 @@ -100,7 +100,7 @@ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) */ -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ int level, /* 0 <= level <= 9, default = 5 */ unsigned dictSize, /* default = (1 << 24) */ @@ -130,7 +130,7 @@ SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) */ -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, const unsigned char *props, size_t propsSize); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/Md5.c 7zip-22.01+really25.01+dfsg/C/Md5.c --- 7zip-22.01+dfsg/C/Md5.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Md5.c 2024-11-26 09:00:00.000000000 +0000 @@ -0,0 +1,206 @@ +/* Md5.c -- MD5 Hash +: Igor Pavlov : Public domain +This code is based on Colin Plumb's public domain md5.c code */ + +#include "Precomp.h" + +#include + +#include "Md5.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#define MD5_UPDATE_BLOCKS(p) Md5_UpdateBlocks + +Z7_NO_INLINE +void Md5_Init(CMd5 *p) +{ + p->count = 0; + p->state[0] = 0x67452301; + p->state[1] = 0xefcdab89; + p->state[2] = 0x98badcfe; + p->state[3] = 0x10325476; +} + +#if 0 && !defined(MY_CPU_LE_UNALIGN) +// optional optimization for Big-endian processors or processors without unaligned access: +// it is intended to reduce the number of complex LE32 memory reading from 64 to 16. +// But some compilers (sparc, armt) are better without this optimization. +#define Z7_MD5_USE_DATA32_ARRAY +#endif + +#define LOAD_DATA(i) GetUi32((const UInt32 *)(const void *)data + (i)) + +#ifdef Z7_MD5_USE_DATA32_ARRAY +#define D(i) data32[i] +#else +#define D(i) LOAD_DATA(i) +#endif + +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define R1(i, f, start, step, w, x, y, z, s, k) \ + w += D((start + step * (i)) % 16) + k; \ + w += f(x, y, z); \ + w = rotlFixed(w, s) + x; \ + +#define R4(i4, f, start, step, s0,s1,s2,s3, k0,k1,k2,k3) \ + R1 (i4*4+0, f, start, step, a,b,c,d, s0, k0) \ + R1 (i4*4+1, f, start, step, d,a,b,c, s1, k1) \ + R1 (i4*4+2, f, start, step, c,d,a,b, s2, k2) \ + R1 (i4*4+3, f, start, step, b,c,d,a, s3, k3) \ + +#define R16(f, start, step, s0,s1,s2,s3, k00,k01,k02,k03, k10,k11,k12,k13, k20,k21,k22,k23, k30,k31,k32,k33) \ + R4 (0, f, start, step, s0,s1,s2,s3, k00,k01,k02,k03) \ + R4 (1, f, start, step, s0,s1,s2,s3, k10,k11,k12,k13) \ + R4 (2, f, start, step, s0,s1,s2,s3, k20,k21,k22,k23) \ + R4 (3, f, start, step, s0,s1,s2,s3, k30,k31,k32,k33) \ + +static +Z7_NO_INLINE +void Z7_FASTCALL Md5_UpdateBlocks(UInt32 state[4], const Byte *data, size_t numBlocks) +{ + UInt32 a, b, c, d; + // if (numBlocks == 0) return; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + do + { +#ifdef Z7_MD5_USE_DATA32_ARRAY + UInt32 data32[MD5_NUM_BLOCK_WORDS]; + { +#define LOAD_data32_x4(i) { \ + data32[i ] = LOAD_DATA(i ); \ + data32[i + 1] = LOAD_DATA(i + 1); \ + data32[i + 2] = LOAD_DATA(i + 2); \ + data32[i + 3] = LOAD_DATA(i + 3); } +#if 1 + LOAD_data32_x4 (0 * 4) + LOAD_data32_x4 (1 * 4) + LOAD_data32_x4 (2 * 4) + LOAD_data32_x4 (3 * 4) +#else + unsigned i; + for (i = 0; i < MD5_NUM_BLOCK_WORDS; i += 4) + { + LOAD_data32_x4(i) + } +#endif + } +#endif + + R16 (F1, 0, 1, 7,12,17,22, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821) + R16 (F2, 1, 5, 5, 9,14,20, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a) + R16 (F3, 5, 3, 4,11,16,23, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665) + R16 (F4, 0, 7, 6,10,15,21, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391) + + a += state[0]; + b += state[1]; + c += state[2]; + d += state[3]; + + state[0] = a; + state[1] = b; + state[2] = c; + state[3] = d; + + data += MD5_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Md5_UpdateBlock(p) MD5_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Md5_Update(CMd5 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1); + const unsigned num = MD5_BLOCK_SIZE - pos; + p->count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Md5_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 6; + if (numBlocks) + MD5_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= MD5_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 6); + memcpy(p->buffer, data, size); + } +} + + +void Md5_Final(CMd5 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (MD5_BLOCK_SIZE - 4 * 2)) + { + while (pos != MD5_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, MD5_BLOCK_SIZE - pos); + Md5_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (MD5_BLOCK_SIZE - 4 * 2) - pos); + { + const UInt64 numBits = p->count << 3; +#if defined(MY_CPU_LE_UNALIGN) + SetUi64 (p->buffer + MD5_BLOCK_SIZE - 4 * 2, numBits) +#else + SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 2, (UInt32)(numBits)) + SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 1, (UInt32)(numBits >> 32)) +#endif + } + Md5_UpdateBlock(p); + + SetUi32(digest, p->state[0]) + SetUi32(digest + 4, p->state[1]) + SetUi32(digest + 8, p->state[2]) + SetUi32(digest + 12, p->state[3]) + + Md5_Init(p); +} + +#undef R1 +#undef R4 +#undef R16 +#undef D +#undef LOAD_DATA +#undef LOAD_data32_x4 +#undef F1 +#undef F2 +#undef F3 +#undef F4 diff -Nru 7zip-22.01+dfsg/C/Md5.h 7zip-22.01+really25.01+dfsg/C/Md5.h --- 7zip-22.01+dfsg/C/Md5.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Md5.h 2024-11-26 09:00:00.000000000 +0000 @@ -0,0 +1,34 @@ +/* Md5.h -- MD5 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MD5_H +#define ZIP7_INC_MD5_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define MD5_NUM_BLOCK_WORDS 16 +#define MD5_NUM_DIGEST_WORDS 4 + +#define MD5_BLOCK_SIZE (MD5_NUM_BLOCK_WORDS * 4) +#define MD5_DIGEST_SIZE (MD5_NUM_DIGEST_WORDS * 4) + +typedef struct +{ + UInt64 count; + UInt64 _pad_1; + // we want 16-bytes alignment here + UInt32 state[MD5_NUM_DIGEST_WORDS]; + UInt64 _pad_2[4]; + // we want 64-bytes alignment here + Byte buffer[MD5_BLOCK_SIZE]; +} CMd5; + +void Md5_Init(CMd5 *p); +void Md5_Update(CMd5 *p, const Byte *data, size_t size); +void Md5_Final(CMd5 *p, Byte *digest); + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/MtCoder.c 7zip-22.01+really25.01+dfsg/C/MtCoder.c --- 7zip-22.01+dfsg/C/MtCoder.c 2021-12-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/MtCoder.c 2025-07-04 06:00:00.000000000 +0000 @@ -1,28 +1,28 @@ /* MtCoder.c -- Multi-thread Coder -2021-12-21 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" #include "MtCoder.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST -static SRes MtProgressThunk_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) +static SRes MtProgressThunk_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) { - CMtProgressThunk *thunk = CONTAINER_FROM_VTBL(pp, CMtProgressThunk, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CMtProgressThunk) UInt64 inSize2 = 0; UInt64 outSize2 = 0; if (inSize != (UInt64)(Int64)-1) { - inSize2 = inSize - thunk->inSize; - thunk->inSize = inSize; + inSize2 = inSize - p->inSize; + p->inSize = inSize; } if (outSize != (UInt64)(Int64)-1) { - outSize2 = outSize - thunk->outSize; - thunk->outSize = outSize; + outSize2 = outSize - p->outSize; + p->outSize = outSize; } - return MtProgress_ProgressAdd(thunk->mtProgress, inSize2, outSize2); + return MtProgress_ProgressAdd(p->mtProgress, inSize2, outSize2); } @@ -36,25 +36,31 @@ #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } -static WRes ArEvent_OptCreate_And_Reset(CEvent *p) -{ - if (Event_IsCreated(p)) - return Event_Reset(p); - return AutoResetEvent_CreateNotSignaled(p); -} - - static THREAD_FUNC_DECL ThreadFunc(void *pp); -static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t) +static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t +#ifdef _WIN32 + , CMtCoder * const mtc +#endif + ) { - WRes wres = ArEvent_OptCreate_And_Reset(&t->startEvent); + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->startEvent); + // printf("\n====== MtCoderThread_CreateAndStart : \n"); if (wres == 0) { t->stop = False; if (!Thread_WasCreated(&t->thread)) - wres = Thread_Create(&t->thread, ThreadFunc, t); + { +#ifdef _WIN32 + if (mtc->numThreadGroups) + wres = Thread_Create_With_Group(&t->thread, ThreadFunc, t, + ThreadNextGroup_GetNext(&mtc->nextGroup), // group + 0); // affinityMask + else +#endif + wres = Thread_Create(&t->thread, ThreadFunc, t); + } if (wres == 0) wres = Event_Set(&t->startEvent); } @@ -64,6 +70,7 @@ } +Z7_FORCE_INLINE static void MtCoderThread_Destruct(CMtCoderThread *t) { if (Thread_WasCreated(&t->thread)) @@ -84,24 +91,6 @@ -static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize) -{ - size_t size = *processedSize; - *processedSize = 0; - while (size != 0) - { - size_t cur = size; - SRes res = ISeqInStream_Read(stream, data, &cur); - *processedSize += cur; - data += cur; - size -= cur; - RINOK(res); - if (cur == 0) - return SZ_OK; - } - return SZ_OK; -} - /* ThreadFunc2() returns: @@ -111,7 +100,7 @@ static SRes ThreadFunc2(CMtCoderThread *t) { - CMtCoder *mtc = t->mtCoder; + CMtCoder * const mtc = t->mtCoder; for (;;) { @@ -152,7 +141,7 @@ } if (res == SZ_OK) { - res = FullRead(mtc->inStream, t->inBuf, &size); + res = SeqInStream_ReadMax(mtc->inStream, t->inBuf, &size); readProcessed = mtc->readProcessed + size; mtc->readProcessed = readProcessed; } @@ -211,7 +200,11 @@ if (mtc->numStartedThreads < mtc->numStartedThreadsLimit && mtc->expectedDataSize != readProcessed) { - res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads]); + res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads] +#ifdef _WIN32 + , mtc +#endif + ); if (res == SZ_OK) mtc->numStartedThreads++; else @@ -247,13 +240,13 @@ } { - CMtCoderBlock *block = &mtc->blocks[bi]; + CMtCoderBlock * const block = &mtc->blocks[bi]; block->res = res; block->bufIndex = bufIndex; block->finished = finished; } - #ifdef MTCODER__USE_WRITE_THREAD + #ifdef MTCODER_USE_WRITE_THREAD RINOK_THREAD(Event_Set(&mtc->writeEvents[bi])) #else { @@ -337,7 +330,7 @@ static THREAD_FUNC_DECL ThreadFunc(void *pp) { - CMtCoderThread *t = (CMtCoderThread *)pp; + CMtCoderThread * const t = (CMtCoderThread *)pp; for (;;) { if (Event_Wait(&t->startEvent) != 0) @@ -345,16 +338,16 @@ if (t->stop) return 0; { - SRes res = ThreadFunc2(t); + const SRes res = ThreadFunc2(t); CMtCoder *mtc = t->mtCoder; if (res != SZ_OK) { MtProgress_SetError(&mtc->mtProgress, res); } - #ifndef MTCODER__USE_WRITE_THREAD + #ifndef MTCODER_USE_WRITE_THREAD { - unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); + const unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); if (numFinished == mtc->numStartedThreads) if (Event_Set(&mtc->finishedEvent) != 0) return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; @@ -372,6 +365,7 @@ p->blockSize = 0; p->numThreadsMax = 0; + p->numThreadGroups = 0; p->expectedDataSize = (UInt64)(Int64)-1; p->inStream = NULL; @@ -389,7 +383,7 @@ Event_Construct(&p->readEvent); Semaphore_Construct(&p->blocksSemaphore); - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) { CMtCoderThread *t = &p->threads[i]; t->mtCoder = p; @@ -397,11 +391,11 @@ t->inBuf = NULL; t->stop = False; Event_Construct(&t->startEvent); - Thread_Construct(&t->thread); + Thread_CONSTRUCT(&t->thread) } - #ifdef MTCODER__USE_WRITE_THREAD - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) Event_Construct(&p->writeEvents[i]); #else Event_Construct(&p->finishedEvent); @@ -424,14 +418,14 @@ Event_Set(&p->readEvent); */ - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) MtCoderThread_Destruct(&p->threads[i]); Event_Close(&p->readEvent); Semaphore_Close(&p->blocksSemaphore); - #ifdef MTCODER__USE_WRITE_THREAD - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) Event_Close(&p->writeEvents[i]); #else Event_Close(&p->finishedEvent); @@ -455,20 +449,22 @@ unsigned i; SRes res = SZ_OK; - if (numThreads > MTCODER__THREADS_MAX) - numThreads = MTCODER__THREADS_MAX; - numBlocksMax = MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads); + // printf("\n====== MtCoder_Code : \n"); + + if (numThreads > MTCODER_THREADS_MAX) + numThreads = MTCODER_THREADS_MAX; + numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads); if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++; if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++; if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++; - if (numBlocksMax > MTCODER__BLOCKS_MAX) - numBlocksMax = MTCODER__BLOCKS_MAX; + if (numBlocksMax > MTCODER_BLOCKS_MAX) + numBlocksMax = MTCODER_BLOCKS_MAX; if (p->blockSize != p->allocatedBufsSize) { - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) { CMtCoderThread *t = &p->threads[i]; if (t->inBuf) @@ -484,23 +480,23 @@ MtProgress_Init(&p->mtProgress, p->progress); - #ifdef MTCODER__USE_WRITE_THREAD + #ifdef MTCODER_USE_WRITE_THREAD for (i = 0; i < numBlocksMax; i++) { - RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->writeEvents[i])); + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->writeEvents[i])) } #else - RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->finishedEvent)); + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) #endif { - RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->readEvent)); - RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, numBlocksMax, numBlocksMax)); + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->readEvent)) + RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, (UInt32)numBlocksMax, (UInt32)numBlocksMax)) } - for (i = 0; i < MTCODER__BLOCKS_MAX - 1; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX - 1; i++) p->freeBlockList[i] = i + 1; - p->freeBlockList[MTCODER__BLOCKS_MAX - 1] = (unsigned)(int)-1; + p->freeBlockList[MTCODER_BLOCKS_MAX - 1] = (unsigned)(int)-1; p->freeBlockHead = 0; p->readProcessed = 0; @@ -508,26 +504,37 @@ p->numBlocksMax = numBlocksMax; p->stopReading = False; - #ifndef MTCODER__USE_WRITE_THREAD + #ifndef MTCODER_USE_WRITE_THREAD p->writeIndex = 0; p->writeRes = SZ_OK; - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) p->ReadyBlocks[i] = False; p->numFinishedThreads = 0; #endif p->numStartedThreadsLimit = numThreads; p->numStartedThreads = 0; + ThreadNextGroup_Init(&p->nextGroup, p->numThreadGroups, 0); // startGroup // for (i = 0; i < numThreads; i++) { + // here we create new thread for first block. + // And each new thread will create another new thread after block reading + // until numStartedThreadsLimit is reached. CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++]; - RINOK(MtCoderThread_CreateAndStart(nextThread)); + { + const SRes res2 = MtCoderThread_CreateAndStart(nextThread +#ifdef _WIN32 + , p +#endif + ); + RINOK(res2) + } } RINOK_THREAD(Event_Set(&p->readEvent)) - #ifdef MTCODER__USE_WRITE_THREAD + #ifdef MTCODER_USE_WRITE_THREAD { unsigned bi = 0; @@ -539,9 +546,9 @@ RINOK_THREAD(Event_Wait(&p->writeEvents[bi])) { - const CMtCoderBlock *block = &p->blocks[bi]; - unsigned bufIndex = block->bufIndex; - BoolInt finished = block->finished; + const CMtCoderBlock * const block = &p->blocks[bi]; + const unsigned bufIndex = block->bufIndex; + const BoolInt finished = block->finished; if (res == SZ_OK && block->res != SZ_OK) res = block->res; @@ -571,7 +578,7 @@ } #else { - WRes wres = Event_Wait(&p->finishedEvent); + const WRes wres = Event_Wait(&p->finishedEvent); res = MY_SRes_HRESULT_FROM_WRes(wres); } #endif @@ -582,7 +589,7 @@ if (res == SZ_OK) res = p->mtProgress.res; - #ifndef MTCODER__USE_WRITE_THREAD + #ifndef MTCODER_USE_WRITE_THREAD if (res == SZ_OK) res = p->writeRes; #endif @@ -593,3 +600,5 @@ } #endif + +#undef RINOK_THREAD diff -Nru 7zip-22.01+dfsg/C/MtCoder.h 7zip-22.01+really25.01+dfsg/C/MtCoder.h --- 7zip-22.01+dfsg/C/MtCoder.h 2018-07-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/MtCoder.h 2025-05-15 06:00:00.000000000 +0000 @@ -1,30 +1,30 @@ /* MtCoder.h -- Multi-thread Coder -2018-07-04 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __MT_CODER_H -#define __MT_CODER_H +#ifndef ZIP7_INC_MT_CODER_H +#define ZIP7_INC_MT_CODER_H #include "MtDec.h" EXTERN_C_BEGIN /* - if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream - if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream + if ( defined MTCODER_USE_WRITE_THREAD) : main thread writes all data blocks to output stream + if (not defined MTCODER_USE_WRITE_THREAD) : any coder thread can write data blocks to output stream */ -/* #define MTCODER__USE_WRITE_THREAD */ +/* #define MTCODER_USE_WRITE_THREAD */ -#ifndef _7ZIP_ST - #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) - #define MTCODER__THREADS_MAX 64 - #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3) +#ifndef Z7_ST + #define MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) + #define MTCODER_THREADS_MAX 256 + #define MTCODER_BLOCKS_MAX (MTCODER_GET_NUM_BLOCKS_FROM_THREADS(MTCODER_THREADS_MAX) + 3) #else - #define MTCODER__THREADS_MAX 1 - #define MTCODER__BLOCKS_MAX 1 + #define MTCODER_THREADS_MAX 1 + #define MTCODER_BLOCKS_MAX 1 #endif -#ifndef _7ZIP_ST +#ifndef Z7_ST typedef struct @@ -37,15 +37,15 @@ void MtProgressThunk_CreateVTable(CMtProgressThunk *p); -#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; } +#define MtProgressThunk_INIT(p) { (p)->inSize = 0; (p)->outSize = 0; } -struct _CMtCoder; +struct CMtCoder_; typedef struct { - struct _CMtCoder *mtCoder; + struct CMtCoder_ *mtCoder; unsigned index; int stop; Byte *inBuf; @@ -71,19 +71,20 @@ } CMtCoderBlock; -typedef struct _CMtCoder +typedef struct CMtCoder_ { /* input variables */ size_t blockSize; /* size of input block */ unsigned numThreadsMax; + unsigned numThreadGroups; UInt64 expectedDataSize; - ISeqInStream *inStream; + ISeqInStreamPtr inStream; const Byte *inData; size_t inDataSize; - ICompressProgress *progress; + ICompressProgressPtr progress; ISzAllocPtr allocBig; IMtCoderCallback2 *mtCallback; @@ -100,13 +101,13 @@ BoolInt stopReading; SRes readRes; - #ifdef MTCODER__USE_WRITE_THREAD - CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX]; + #ifdef MTCODER_USE_WRITE_THREAD + CAutoResetEvent writeEvents[MTCODER_BLOCKS_MAX]; #else CAutoResetEvent finishedEvent; SRes writeRes; unsigned writeIndex; - Byte ReadyBlocks[MTCODER__BLOCKS_MAX]; + Byte ReadyBlocks[MTCODER_BLOCKS_MAX]; LONG numFinishedThreads; #endif @@ -120,11 +121,13 @@ CCriticalSection cs; unsigned freeBlockHead; - unsigned freeBlockList[MTCODER__BLOCKS_MAX]; + unsigned freeBlockList[MTCODER_BLOCKS_MAX]; CMtProgress mtProgress; - CMtCoderBlock blocks[MTCODER__BLOCKS_MAX]; - CMtCoderThread threads[MTCODER__THREADS_MAX]; + CMtCoderBlock blocks[MTCODER_BLOCKS_MAX]; + CMtCoderThread threads[MTCODER_THREADS_MAX]; + + CThreadNextGroup nextGroup; } CMtCoder; diff -Nru 7zip-22.01+dfsg/C/MtDec.c 7zip-22.01+really25.01+dfsg/C/MtDec.c --- 7zip-22.01+dfsg/C/MtDec.c 2021-12-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/MtDec.c 2024-02-20 10:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* MtDec.c -- Multi-thread Decoder -2021-12-21 : Igor Pavlov : Public domain */ +2024-02-20 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -14,7 +14,7 @@ #include "MtDec.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #ifdef SHOW_DEBUG_INFO #define PRF(x) x @@ -24,7 +24,7 @@ #define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) -void MtProgress_Init(CMtProgress *p, ICompressProgress *progress) +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress) { p->progress = progress; p->res = SZ_OK; @@ -81,36 +81,28 @@ #define RINOK_THREAD(x) RINOK_WRes(x) -static WRes ArEvent_OptCreate_And_Reset(CEvent *p) +struct CMtDecBufLink_ { - if (Event_IsCreated(p)) - return Event_Reset(p); - return AutoResetEvent_CreateNotSignaled(p); -} - - -struct __CMtDecBufLink -{ - struct __CMtDecBufLink *next; + struct CMtDecBufLink_ *next; void *pad[3]; }; -typedef struct __CMtDecBufLink CMtDecBufLink; +typedef struct CMtDecBufLink_ CMtDecBufLink; #define MTDEC__LINK_DATA_OFFSET sizeof(CMtDecBufLink) #define MTDEC__DATA_PTR_FROM_LINK(link) ((Byte *)(link) + MTDEC__LINK_DATA_OFFSET) -static THREAD_FUNC_DECL ThreadFunc(void *pp); +static THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp); static WRes MtDecThread_CreateEvents(CMtDecThread *t) { - WRes wres = ArEvent_OptCreate_And_Reset(&t->canWrite); + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->canWrite); if (wres == 0) { - wres = ArEvent_OptCreate_And_Reset(&t->canRead); + wres = AutoResetEvent_OptCreate_And_Reset(&t->canRead); if (wres == 0) return SZ_OK; } @@ -126,7 +118,7 @@ { if (Thread_WasCreated(&t->thread)) return SZ_OK; - wres = Thread_Create(&t->thread, ThreadFunc, t); + wres = Thread_Create(&t->thread, MtDec_ThreadFunc, t); if (wres == 0) return SZ_OK; } @@ -167,7 +159,7 @@ static void MtDec_CloseThreads(CMtDec *p) { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) MtDecThread_CloseThread(&p->threads[i]); } @@ -179,25 +171,6 @@ -static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize) -{ - size_t size = *processedSize; - *processedSize = 0; - while (size != 0) - { - size_t cur = size; - SRes res = ISeqInStream_Read(stream, data, &cur); - *processedSize += cur; - data += cur; - size -= cur; - RINOK(res); - if (cur == 0) - return SZ_OK; - } - return SZ_OK; -} - - static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted) { SRes res; @@ -253,7 +226,7 @@ /* - ThreadFunc2() returns: + MtDec_ThreadFunc2() returns: 0 - in all normal cases (even for stream error or memory allocation error) (!= 0) - WRes error return by system threading function */ @@ -261,11 +234,11 @@ // #define MTDEC_ProgessStep (1 << 22) #define MTDEC_ProgessStep (1 << 0) -static WRes ThreadFunc2(CMtDecThread *t) +static WRes MtDec_ThreadFunc2(CMtDecThread *t) { CMtDec *p = t->mtDec; - PRF_STR_INT("ThreadFunc2", t->index); + PRF_STR_INT("MtDec_ThreadFunc2", t->index) // SetThreadAffinityMask(GetCurrentThread(), 1 << t->index); @@ -295,13 +268,13 @@ // CMtDecCallbackInfo parse; CMtDecThread *nextThread; - PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index); + PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index) - RINOK_THREAD(Event_Wait(&t->canRead)); + RINOK_THREAD(Event_Wait(&t->canRead)) if (p->exitThread) return 0; - PRF_STR_INT("after Event_Wait(&t->canRead)", t->index); + PRF_STR_INT("after Event_Wait(&t->canRead)", t->index) // if (t->index == 3) return 19; // for test @@ -373,7 +346,7 @@ { size = p->inBufSize; - res = FullRead(p->inStream, data, &size); + res = SeqInStream_ReadMax(p->inStream, data, &size); // size = 10; // test @@ -615,7 +588,7 @@ // if ( !finish ) we must call Event_Set(&nextThread->canWrite) in any case // if ( finish ) we switch to single-thread mode and there are 2 ways at the end of current iteration (current block): // - if (needContinue) after Write(&needContinue), we restore decoding with new iteration - // - otherwise we stop decoding and exit from ThreadFunc2() + // - otherwise we stop decoding and exit from MtDec_ThreadFunc2() // Don't change (finish) variable in the further code @@ -688,7 +661,7 @@ // ---------- WRITE ---------- - RINOK_THREAD(Event_Wait(&t->canWrite)); + RINOK_THREAD(Event_Wait(&t->canWrite)) { BoolInt isErrorMode = False; @@ -801,14 +774,14 @@ if (!finish) { - RINOK_THREAD(Event_Set(&nextThread->canWrite)); + RINOK_THREAD(Event_Set(&nextThread->canWrite)) } else { if (needContinue) { // we restore decoding with new iteration - RINOK_THREAD(Event_Set(&p->threads[0].canWrite)); + RINOK_THREAD(Event_Set(&p->threads[0].canWrite)) } else { @@ -817,7 +790,7 @@ return SZ_OK; p->exitThread = True; } - RINOK_THREAD(Event_Set(&p->threads[0].canRead)); + RINOK_THREAD(Event_Set(&p->threads[0].canRead)) } } } @@ -836,7 +809,17 @@ #endif -static THREAD_FUNC_DECL ThreadFunc1(void *pp) +typedef + #ifdef _WIN32 + UINT_PTR + #elif 1 + uintptr_t + #else + ptrdiff_t + #endif + MY_uintptr_t; + +static THREAD_FUNC_DECL MtDec_ThreadFunc1(void *pp) { WRes res; @@ -845,10 +828,10 @@ // fprintf(stdout, "\n%d = %p\n", t->index, &t); - res = ThreadFunc2(t); + res = MtDec_ThreadFunc2(t); p = t->mtDec; if (res == 0) - return (THREAD_FUNC_RET_TYPE)(UINT_PTR)p->exitThreadWRes; + return (THREAD_FUNC_RET_TYPE)(MY_uintptr_t)p->exitThreadWRes; { // it's unexpected situation for some threading function error if (p->exitThreadWRes == 0) @@ -859,17 +842,17 @@ Event_Set(&p->threads[0].canWrite); MtProgress_SetError(&p->mtProgress, MY_SRes_HRESULT_FROM_WRes(res)); } - return (THREAD_FUNC_RET_TYPE)(UINT_PTR)res; + return (THREAD_FUNC_RET_TYPE)(MY_uintptr_t)res; } -static MY_NO_INLINE THREAD_FUNC_DECL ThreadFunc(void *pp) +static Z7_NO_INLINE THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp) { #ifdef USE_ALLOCA CMtDecThread *t = (CMtDecThread *)pp; // fprintf(stderr, "\n%d = %p - before", t->index, &t); t->allocaPtr = alloca(t->index * 128); #endif - return ThreadFunc1(pp); + return MtDec_ThreadFunc1(pp); } @@ -883,7 +866,7 @@ { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) if (i > p->numStartedThreads || p->numFilledThreads <= (i >= p->filledThreadStart ? @@ -987,7 +970,7 @@ p->allocatedBufsSize = 0; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CMtDecThread *t = &p->threads[i]; t->mtDec = p; @@ -995,7 +978,7 @@ t->inBuf = NULL; Event_Construct(&t->canRead); Event_Construct(&t->canWrite); - Thread_Construct(&t->thread); + Thread_CONSTRUCT(&t->thread) } // Event_Construct(&p->finishedEvent); @@ -1010,7 +993,7 @@ p->exitThread = True; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) MtDecThread_Destruct(&p->threads[i]); // Event_Close(&p->finishedEvent); @@ -1061,15 +1044,15 @@ { unsigned numThreads = p->numThreadsMax; - if (numThreads > MTDEC__THREADS_MAX) - numThreads = MTDEC__THREADS_MAX; + if (numThreads > MTDEC_THREADS_MAX) + numThreads = MTDEC_THREADS_MAX; p->numStartedThreads_Limit = numThreads; p->numStartedThreads = 0; } if (p->inBufSize != p->allocatedBufsSize) { - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CMtDecThread *t = &p->threads[i]; if (t->inBuf) @@ -1086,7 +1069,7 @@ MtProgress_Init(&p->mtProgress, p->progress); - // RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->finishedEvent)); + // RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) p->exitThread = False; p->exitThreadWRes = 0; @@ -1098,8 +1081,8 @@ wres = MtDecThread_CreateEvents(nextThread); if (wres == 0) { wres = Event_Set(&nextThread->canWrite); if (wres == 0) { wres = Event_Set(&nextThread->canRead); - if (wres == 0) { THREAD_FUNC_RET_TYPE res = ThreadFunc(nextThread); - wres = (WRes)(UINT_PTR)res; + if (wres == 0) { THREAD_FUNC_RET_TYPE res = MtDec_ThreadFunc(nextThread); + wres = (WRes)(MY_uintptr_t)res; if (wres != 0) { p->needContinue = False; @@ -1137,3 +1120,5 @@ } #endif + +#undef PRF diff -Nru 7zip-22.01+dfsg/C/MtDec.h 7zip-22.01+really25.01+dfsg/C/MtDec.h --- 7zip-22.01+dfsg/C/MtDec.h 2020-03-05 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/MtDec.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,46 +1,46 @@ /* MtDec.h -- Multi-thread Decoder -2020-03-05 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __MT_DEC_H -#define __MT_DEC_H +#ifndef ZIP7_INC_MT_DEC_H +#define ZIP7_INC_MT_DEC_H #include "7zTypes.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "Threads.h" #endif EXTERN_C_BEGIN -#ifndef _7ZIP_ST +#ifndef Z7_ST -#ifndef _7ZIP_ST - #define MTDEC__THREADS_MAX 32 +#ifndef Z7_ST + #define MTDEC_THREADS_MAX 32 #else - #define MTDEC__THREADS_MAX 1 + #define MTDEC_THREADS_MAX 1 #endif typedef struct { - ICompressProgress *progress; + ICompressProgressPtr progress; SRes res; UInt64 totalInSize; UInt64 totalOutSize; CCriticalSection cs; } CMtProgress; -void MtProgress_Init(CMtProgress *p, ICompressProgress *progress); +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress); SRes MtProgress_Progress_ST(CMtProgress *p); SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize); SRes MtProgress_GetError(CMtProgress *p); void MtProgress_SetError(CMtProgress *p, SRes res); -struct _CMtDec; +struct CMtDec; typedef struct { - struct _CMtDec *mtDec; + struct CMtDec_ *mtDec; unsigned index; void *inBuf; @@ -117,7 +117,7 @@ -typedef struct _CMtDec +typedef struct CMtDec_ { /* input variables */ @@ -126,11 +126,11 @@ // size_t inBlockMax; unsigned numThreadsMax_2; - ISeqInStream *inStream; + ISeqInStreamPtr inStream; // const Byte *inData; // size_t inDataSize; - ICompressProgress *progress; + ICompressProgressPtr progress; ISzAllocPtr alloc; IMtDecCallback2 *mtCallback; @@ -171,11 +171,11 @@ unsigned filledThreadStart; unsigned numFilledThreads; - #ifndef _7ZIP_ST + #ifndef Z7_ST BoolInt needInterrupt; UInt64 interruptIndex; CMtProgress mtProgress; - CMtDecThread threads[MTDEC__THREADS_MAX]; + CMtDecThread threads[MTDEC_THREADS_MAX]; #endif } CMtDec; diff -Nru 7zip-22.01+dfsg/C/Ppmd.h 7zip-22.01+really25.01+dfsg/C/Ppmd.h --- 7zip-22.01+dfsg/C/Ppmd.h 2021-04-13 20:06:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd.h 2023-03-05 15:00:00.000000000 +0000 @@ -1,9 +1,9 @@ /* Ppmd.h -- PPMD codec common code -2021-04-13 : Igor Pavlov : Public domain +2023-03-05 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ -#ifndef __PPMD_H -#define __PPMD_H +#ifndef ZIP7_INC_PPMD_H +#define ZIP7_INC_PPMD_H #include "CpuArch.h" @@ -48,8 +48,10 @@ Byte Count; /* Count to next change of Shift */ } CPpmd_See; -#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ - { (p)->Summ = (UInt16)((p)->Summ << 1); (p)->Count = (Byte)(3 << (p)->Shift++); } +#define Ppmd_See_UPDATE(p) \ + { if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ + { (p)->Summ = (UInt16)((p)->Summ << 1); \ + (p)->Count = (Byte)(3 << (p)->Shift++); }} typedef struct diff -Nru 7zip-22.01+dfsg/C/Ppmd7.c 7zip-22.01+really25.01+dfsg/C/Ppmd7.c --- 7zip-22.01+dfsg/C/Ppmd7.c 2021-04-13 19:20:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd7.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd7.c -- PPMdH codec -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -14,7 +14,7 @@ MY_ALIGN(16) static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; MY_ALIGN(16) -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; +static const UInt16 PPMD7_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; #define MAX_FREQ 124 #define UNIT_SIZE 12 @@ -33,7 +33,7 @@ #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) #define SUFFIX(ctx) CTX((ctx)->Suffix) -typedef CPpmd7_Context * CTX_PTR; +typedef CPpmd7_Context * PPMD7_CTX_PTR; struct CPpmd7_Node_; @@ -107,14 +107,14 @@ // ---------- Internal Memory Allocator ---------- /* We can use CPpmd7_Node in list of free units (as in Ppmd8) - But we still need one additional list walk pass in GlueFreeBlocks(). - So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in InsertNode() / RemoveNode() + But we still need one additional list walk pass in Ppmd7_GlueFreeBlocks(). + So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in Ppmd7_InsertNode() / Ppmd7_RemoveNode() */ #define EMPTY_NODE 0 -static void InsertNode(CPpmd7 *p, void *node, unsigned indx) +static void Ppmd7_InsertNode(CPpmd7 *p, void *node, unsigned indx) { *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx]; @@ -124,7 +124,7 @@ } -static void *RemoveNode(CPpmd7 *p, unsigned indx) +static void *Ppmd7_RemoveNode(CPpmd7 *p, unsigned indx) { CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); p->FreeList[indx] = *node; @@ -134,32 +134,32 @@ } -static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +static void Ppmd7_SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) { unsigned i, nu = I2U(oldIndx) - I2U(newIndx); ptr = (Byte *)ptr + U2B(I2U(newIndx)); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + Ppmd7_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); } - InsertNode(p, ptr, i); + Ppmd7_InsertNode(p, ptr, i); } /* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */ -typedef union _CPpmd7_Node_Union +typedef union { CPpmd7_Node Node; CPpmd7_Node_Ref NextRef; } CPpmd7_Node_Union; -/* Original PPmdH (Ppmd7) code uses doubly linked list in GlueFreeBlocks() +/* Original PPmdH (Ppmd7) code uses doubly linked list in Ppmd7_GlueFreeBlocks() we use single linked list similar to Ppmd8 code */ -static void GlueFreeBlocks(CPpmd7 *p) +static void Ppmd7_GlueFreeBlocks(CPpmd7 *p) { /* we use first UInt16 field of 12-bytes UNITs as record type stamp @@ -239,27 +239,27 @@ if (nu == 0) continue; for (; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); + Ppmd7_InsertNode(p, node, PPMD_NUM_INDEXES - 1); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, node + k, (unsigned)nu - k - 1); + Ppmd7_InsertNode(p, node + k, (unsigned)nu - k - 1); } - InsertNode(p, node, i); + Ppmd7_InsertNode(p, node, i); } } -MY_NO_INLINE -static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) +Z7_NO_INLINE +static void *Ppmd7_AllocUnitsRare(CPpmd7 *p, unsigned indx) { unsigned i; if (p->GlueCount == 0) { - GlueFreeBlocks(p); + Ppmd7_GlueFreeBlocks(p); if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd7_RemoveNode(p, indx); } i = indx; @@ -277,17 +277,17 @@ while (p->FreeList[i] == 0); { - void *block = RemoveNode(p, i); - SplitBlock(p, block, i, indx); + void *block = Ppmd7_RemoveNode(p, i); + Ppmd7_SplitBlock(p, block, i, indx); return block; } } -static void *AllocUnits(CPpmd7 *p, unsigned indx) +static void *Ppmd7_AllocUnits(CPpmd7 *p, unsigned indx) { if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd7_RemoveNode(p, indx); { UInt32 numBytes = U2B(I2U(indx)); Byte *lo = p->LoUnit; @@ -297,13 +297,22 @@ return lo; } } - return AllocUnitsRare(p, indx); + return Ppmd7_AllocUnitsRare(p, indx); } -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } +#define MEM_12_CPY(dest, src, num) \ + { UInt32 *d = (UInt32 *)(dest); \ + const UInt32 *z = (const UInt32 *)(src); \ + unsigned n = (num); \ + do { \ + d[0] = z[0]; \ + d[1] = z[1]; \ + d[2] = z[2]; \ + z += 3; \ + d += 3; \ + } while (--n); \ + } /* @@ -315,12 +324,12 @@ return oldPtr; if (p->FreeList[i1] != 0) { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); + void *ptr = Ppmd7_RemoveNode(p, i1); + MEM_12_CPY(ptr, oldPtr, newNU) + Ppmd7_InsertNode(p, oldPtr, i0); return ptr; } - SplitBlock(p, oldPtr, i0, i1); + Ppmd7_SplitBlock(p, oldPtr, i0, i1); return oldPtr; } */ @@ -329,14 +338,14 @@ #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { - Ppmd_SET_SUCCESSOR(p, v); + Ppmd_SET_SUCCESSOR(p, v) } -MY_NO_INLINE +Z7_NO_INLINE static -void RestartModel(CPpmd7 *p) +void Ppmd7_RestartModel(CPpmd7 *p) { unsigned i, k; @@ -352,8 +361,8 @@ p->PrevSuccess = 0; { - CPpmd7_Context *mc = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + CPpmd7_Context *mc = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd7_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ p->LoUnit += U2B(256 / 2); p->MaxContext = p->MinContext = mc; @@ -391,7 +400,7 @@ { unsigned m; UInt16 *dest = p->BinSumm[i] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); + const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD7_kInitBinEsc[k] / (i + 2)); for (m = 0; m < 64; m += 8) dest[m] = val; } @@ -423,13 +432,13 @@ { p->MaxOrder = maxOrder; - RestartModel(p); + Ppmd7_RestartModel(p); } /* - CreateSuccessors() + Ppmd7_CreateSuccessors() It's called when (FoundState->Successor) is RAW-Successor, that is the link to position in Raw text. So we create Context records and write the links to @@ -445,10 +454,10 @@ also it can return pointer to real context of same order, */ -MY_NO_INLINE -static CTX_PTR CreateSuccessors(CPpmd7 *p) +Z7_NO_INLINE +static PPMD7_CTX_PTR Ppmd7_CreateSuccessors(CPpmd7 *p) { - CTX_PTR c = p->MinContext; + PPMD7_CTX_PTR c = p->MinContext; CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); Byte newSym, newFreq; unsigned numPs = 0; @@ -522,15 +531,15 @@ do { - CTX_PTR c1; + PPMD7_CTX_PTR c1; /* = AllocContext(p); */ if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); + c1 = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); + c1 = (PPMD7_CTX_PTR)Ppmd7_RemoveNode(p, 0); else { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); + c1 = (PPMD7_CTX_PTR)Ppmd7_AllocUnitsRare(p, 0); if (!c1) return NULL; } @@ -550,16 +559,16 @@ -#define SwapStates(s) \ +#define SWAP_STATES(s) \ { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; } void Ppmd7_UpdateModel(CPpmd7 *p); -MY_NO_INLINE +Z7_NO_INLINE void Ppmd7_UpdateModel(CPpmd7 *p) { CPpmd_Void_Ref maxSuccessor, minSuccessor; - CTX_PTR c, mc; + PPMD7_CTX_PTR c, mc; unsigned s0, ns; @@ -592,7 +601,7 @@ if (s[0].Freq >= s[-1].Freq) { - SwapStates(s); + SWAP_STATES(s) s--; } } @@ -610,10 +619,10 @@ { /* MAX ORDER context */ /* (FoundState->Successor) is RAW-Successor. */ - p->MaxContext = p->MinContext = CreateSuccessors(p); + p->MaxContext = p->MinContext = Ppmd7_CreateSuccessors(p); if (!p->MinContext) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } SetSuccessor(p->FoundState, REF(p->MinContext)); @@ -629,7 +638,7 @@ p->Text = text; if (text >= p->UnitsStart) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } maxSuccessor = REF(text); @@ -645,10 +654,10 @@ if (minSuccessor <= maxSuccessor) { // minSuccessor is RAW-Successor. So we will create real contexts records: - CTX_PTR cs = CreateSuccessors(p); + PPMD7_CTX_PTR cs = Ppmd7_CreateSuccessors(p); if (!cs) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } minSuccessor = REF(cs); @@ -711,27 +720,27 @@ if ((ns1 & 1) == 0) { /* Expand for one UNIT */ - unsigned oldNU = ns1 >> 1; - unsigned i = U2I(oldNU); + const unsigned oldNU = ns1 >> 1; + const unsigned i = U2I(oldNU); if (i != U2I((size_t)oldNU + 1)) { - void *ptr = AllocUnits(p, i + 1); + void *ptr = Ppmd7_AllocUnits(p, i + 1); void *oldPtr; if (!ptr) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); + MEM_12_CPY(ptr, oldPtr, oldNU) + Ppmd7_InsertNode(p, oldPtr, i); c->Union4.Stats = STATS_REF(ptr); } } sum = c->Union2.SummFreq; /* max increase of Escape_Freq is 3 here. total increase of Union2.SummFreq for all symbols is less than 256 here */ - sum += (UInt32)(2 * ns1 < ns) + 2 * ((unsigned)(4 * ns1 <= ns) & (sum <= 8 * ns1)); + sum += (UInt32)(unsigned)((2 * ns1 < ns) + 2 * ((unsigned)(4 * ns1 <= ns) & (sum <= 8 * ns1))); /* original PPMdH uses 16-bit variable for (sum) here. But (sum < 0x9000). So we don't truncate (sum) to 16-bit */ // sum = (UInt16)sum; @@ -739,10 +748,10 @@ else { // instead of One-symbol context we create 2-symbol context - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); + CPpmd_State *s = (CPpmd_State*)Ppmd7_AllocUnits(p, 0); if (!s) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } { @@ -761,7 +770,7 @@ // (max(s->freq) == 120), when we convert from 1-symbol into 2-symbol context s->Freq = (Byte)freq; // max(InitEsc = PPMD7_kExpEscape[*]) is 25. So the max(escapeFreq) is 26 here - sum = freq + p->InitEsc + (ns > 3); + sum = (UInt32)(freq + p->InitEsc + (ns > 3)); } } @@ -795,8 +804,8 @@ -MY_NO_INLINE -static void Rescale(CPpmd7 *p) +Z7_NO_INLINE +static void Ppmd7_Rescale(CPpmd7 *p) { unsigned i, adder, sumFreq, escFreq; CPpmd_State *stats = STATS(p->MinContext); @@ -885,7 +894,7 @@ *s = *stats; s->Freq = (Byte)freq; // (freq <= 260 / 4) p->FoundState = s; - InsertNode(p, stats, U2I(n0)); + Ppmd7_InsertNode(p, stats, U2I(n0)); return; } @@ -899,13 +908,13 @@ { if (p->FreeList[i1] != 0) { - void *ptr = RemoveNode(p, i1); + void *ptr = Ppmd7_RemoveNode(p, i1); p->MinContext->Union4.Stats = STATS_REF(ptr); - MyMem12Cpy(ptr, (const void *)stats, n1); - InsertNode(p, stats, i0); + MEM_12_CPY(ptr, (const void *)stats, n1) + Ppmd7_InsertNode(p, stats, i0); } else - SplitBlock(p, stats, i0, i1); + Ppmd7_SplitBlock(p, stats, i0, i1); } } } @@ -933,10 +942,10 @@ p->HiBitsFlag; { // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ - unsigned summ = (UInt16)see->Summ; // & 0xFFFF - unsigned r = (summ >> see->Shift); + const unsigned summ = (UInt16)see->Summ; // & 0xFFFF + const unsigned r = (summ >> see->Shift); see->Summ = (UInt16)(summ - r); - *escFreq = r + (r == 0); + *escFreq = (UInt32)(r + (r == 0)); } } else @@ -948,9 +957,9 @@ } -static void NextContext(CPpmd7 *p) +static void Ppmd7_NextContext(CPpmd7 *p) { - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + PPMD7_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); if (p->OrderFall == 0 && (const Byte *)c > p->Text) p->MaxContext = p->MinContext = c; else @@ -967,12 +976,12 @@ s->Freq = (Byte)freq; if (freq > s[-1].Freq) { - SwapStates(s); + SWAP_STATES(s) p->FoundState = --s; if (freq > MAX_FREQ) - Rescale(p); + Ppmd7_Rescale(p); } - NextContext(p); + Ppmd7_NextContext(p); } @@ -981,15 +990,15 @@ CPpmd_State *s = p->FoundState; CPpmd7_Context *mc = p->MinContext; unsigned freq = s->Freq; - unsigned summFreq = mc->Union2.SummFreq; + const unsigned summFreq = mc->Union2.SummFreq; p->PrevSuccess = (2 * freq > summFreq); - p->RunLength += (int)p->PrevSuccess; + p->RunLength += (Int32)p->PrevSuccess; mc->Union2.SummFreq = (UInt16)(summFreq + 4); freq += 4; s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); - NextContext(p); + Ppmd7_Rescale(p); + Ppmd7_NextContext(p); } @@ -1000,7 +1009,7 @@ p->FoundState->Freq = (Byte)(freq + (freq < 128)); p->PrevSuccess = 1; p->RunLength++; - NextContext(p); + Ppmd7_NextContext(p); } */ @@ -1013,7 +1022,7 @@ p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); + Ppmd7_Rescale(p); Ppmd7_UpdateModel(p); } @@ -1042,8 +1051,8 @@ The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors. The code doesn't free UNITs allocated for CPpmd7_Context records. -The code calls RestartModel(), when there is no free memory for allocation. -And RestartModel() changes the state to orignal start state, with full free block. +The code calls Ppmd7_RestartModel(), when there is no free memory for allocation. +And Ppmd7_RestartModel() changes the state to orignal start state, with full free block. The code allocates UNITs with the following order: @@ -1051,14 +1060,14 @@ Allocation of 1 UNIT for Context record - from free space (HiUnit) down to (LoUnit) - from FreeList[0] - - AllocUnitsRare() + - Ppmd7_AllocUnitsRare() -AllocUnits() for CPpmd_State vectors: +Ppmd7_AllocUnits() for CPpmd_State vectors: - from FreeList[i] - from free space (LoUnit) up to (HiUnit) - - AllocUnitsRare() + - Ppmd7_AllocUnitsRare() -AllocUnitsRare() +Ppmd7_AllocUnitsRare() - if (GlueCount == 0) { Glue lists, GlueCount = 255, allocate from FreeList[i]] } - loop for all higher sized FreeList[...] lists @@ -1093,8 +1102,8 @@ We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124) So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol. If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7. -SummFreq and Escape_Freq can be changed in Rescale() and *Update*() functions. -Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Rescale() for +SummFreq and Escape_Freq can be changed in Ppmd7_Rescale() and *Update*() functions. +Ppmd7_Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Ppmd7_Rescale() for max-order context. When the PPMd code still break (Total <= RC::Range) condition in range coder, @@ -1102,3 +1111,21 @@ 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases. 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value. */ + +#undef MAX_FREQ +#undef UNIT_SIZE +#undef U2B +#undef U2I +#undef I2U +#undef I2U_UInt16 +#undef REF +#undef STATS_REF +#undef CTX +#undef STATS +#undef ONE_STATE +#undef SUFFIX +#undef NODE +#undef EMPTY_NODE +#undef MEM_12_CPY +#undef SUCCESSOR +#undef SWAP_STATES diff -Nru 7zip-22.01+dfsg/C/Ppmd7.h 7zip-22.01+really25.01+dfsg/C/Ppmd7.h --- 7zip-22.01+dfsg/C/Ppmd7.h 2021-04-13 18:42:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd7.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,11 +1,11 @@ /* Ppmd7.h -- Ppmd7 (PPMdH) compression codec -2021-04-13 : Igor Pavlov : Public domain +2023-04-02 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain */ -#ifndef __PPMD7_H -#define __PPMD7_H +#ifndef ZIP7_INC_PPMD7_H +#define ZIP7_INC_PPMD7_H #include "Ppmd.h" @@ -55,7 +55,7 @@ UInt32 Range; UInt32 Code; UInt32 Low; - IByteIn *Stream; + IByteInPtr Stream; } CPpmd7_RangeDec; @@ -66,7 +66,7 @@ // Byte _dummy_[3]; UInt64 Low; UInt64 CacheSize; - IByteOut *Stream; + IByteOutPtr Stream; } CPpmd7z_RangeEnc; diff -Nru 7zip-22.01+dfsg/C/Ppmd7Dec.c 7zip-22.01+really25.01+dfsg/C/Ppmd7Dec.c --- 7zip-22.01+dfsg/C/Ppmd7Dec.c 2021-04-13 19:22:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd7Dec.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain */ @@ -8,7 +8,7 @@ #include "Ppmd7.h" -#define kTopValue (1 << 24) +#define kTopValue ((UInt32)1 << 24) #define READ_BYTE(p) IByteIn_Read((p)->Stream) @@ -37,9 +37,9 @@ #define R (&p->rc.dec) -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeDec_Decode(CPpmd7 *p, UInt32 start, UInt32 size) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) { @@ -48,18 +48,18 @@ RC_NORM_LOCAL(R) } -#define RC_Decode(start, size) RangeDec_Decode(p, start, size); -#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) -#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) +#define RC_Decode(start, size) Ppmd7z_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) -typedef CPpmd7_Context * CTX_PTR; +// typedef CPpmd7_Context * CTX_PTR; #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd7_UpdateModel(CPpmd7 *p); -#define MASK(sym) ((unsigned char *)charMask)[sym] -// MY_FORCE_INLINE +#define MASK(sym) ((Byte *)charMask)[sym] +// Z7_FORCE_INLINE // static int Ppmd7z_DecodeSymbol(CPpmd7 *p) { @@ -70,7 +70,7 @@ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); unsigned i; UInt32 count, hiCnt; - UInt32 summFreq = p->MinContext->Union2.SummFreq; + const UInt32 summFreq = p->MinContext->Union2.SummFreq; @@ -81,7 +81,7 @@ if ((Int32)(count -= s->Freq) < 0) { Byte sym; - RC_DecodeFinal(0, s->Freq); + RC_DecodeFinal(0, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1_0(p); @@ -96,7 +96,7 @@ if ((Int32)(count -= (++s)->Freq) < 0) { Byte sym; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1(p); @@ -109,10 +109,10 @@ return PPMD7_SYM_ERROR; hiCnt -= count; - RC_Decode(hiCnt, summFreq - hiCnt); + RC_Decode(hiCnt, summFreq - hiCnt) p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // i = p->MinContext->NumStats - 1; // do { MASK((--s)->Symbol) = 0; } while (--i); { @@ -120,8 +120,8 @@ MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -152,7 +152,7 @@ // Ppmd7_UpdateBin(p); { unsigned freq = s->Freq; - CTX_PTR c = CTX(SUCCESSOR(s)); + CPpmd7_Context *c = CTX(SUCCESSOR(s)); sym = s->Symbol; p->FoundState = s; p->PrevSuccess = 1; @@ -176,7 +176,7 @@ R->Range -= size0; RC_NORM_LOCAL(R) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; p->PrevSuccess = 0; } @@ -209,17 +209,17 @@ unsigned num2 = num / 2; num &= 1; - hiCnt = (s->Freq & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num); + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); s += num; p->MinContext = mc; do { - unsigned sym0 = s[0].Symbol; - unsigned sym1 = s[1].Symbol; + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; s += 2; - hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0))); - hiCnt += (s[-1].Freq & (unsigned)(MASK(sym1))); + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); } while (--num2); } @@ -238,20 +238,20 @@ s = Ppmd7_GetStats(p, p->MinContext); hiCnt = count; - // count -= s->Freq & (unsigned)(MASK(s->Symbol)); + // count -= s->Freq & (UInt32)(MASK(s->Symbol)); // if ((Int32)count >= 0) { for (;;) { - count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - }; + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + } } s--; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) // new (see->Summ) value can overflow over 16-bits in some rare cases - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sym = s->Symbol; Ppmd7_Update2(p); @@ -261,7 +261,7 @@ if (count >= freqSum) return PPMD7_SYM_ERROR; - RC_Decode(hiCnt, freqSum - hiCnt); + RC_Decode(hiCnt, freqSum - hiCnt) // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. // new (see->Summ) value can overflow over 16-bits in some rare cases @@ -295,3 +295,18 @@ return buf; } */ + +#undef kTopValue +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru 7zip-22.01+dfsg/C/Ppmd7Enc.c 7zip-22.01+really25.01+dfsg/C/Ppmd7Enc.c --- 7zip-22.01+dfsg/C/Ppmd7Enc.c 2021-04-13 19:22:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd7Enc.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd7Enc.c -- Ppmd7z (PPMdH with 7z Range Coder) Encoder -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain */ @@ -8,7 +8,7 @@ #include "Ppmd7.h" -#define kTopValue (1 << 24) +#define kTopValue ((UInt32)1 << 24) #define R (&p->rc.enc) @@ -20,8 +20,8 @@ R->CacheSize = 1; } -MY_NO_INLINE -static void RangeEnc_ShiftLow(CPpmd7 *p) +Z7_NO_INLINE +static void Ppmd7z_RangeEnc_ShiftLow(CPpmd7 *p) { if ((UInt32)R->Low < (UInt32)0xFF000000 || (unsigned)(R->Low >> 32) != 0) { @@ -38,53 +38,53 @@ R->Low = (UInt32)((UInt32)R->Low << 8); } -#define RC_NORM_BASE(p) if (R->Range < kTopValue) { R->Range <<= 8; RangeEnc_ShiftLow(p); -#define RC_NORM_1(p) RC_NORM_BASE(p) } -#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} +#define RC_NORM_BASE(p) if (R->Range < kTopValue) { R->Range <<= 8; Ppmd7z_RangeEnc_ShiftLow(p); +#define RC_NORM_1(p) RC_NORM_BASE(p) } +#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} // we must use only one type of Normalization from two: LOCAL or REMOTE #define RC_NORM_LOCAL(p) // RC_NORM(p) #define RC_NORM_REMOTE(p) RC_NORM(p) /* -#define RangeEnc_Encode(p, start, _size_) \ +#define Ppmd7z_RangeEnc_Encode(p, start, _size_) \ { UInt32 size = _size_; \ R->Low += start * R->Range; \ R->Range *= size; \ RC_NORM_LOCAL(p); } */ -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeEnc_Encode(CPpmd7 *p, UInt32 start, UInt32 size) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RangeEnc_Encode(CPpmd7 *p, UInt32 start, UInt32 size) { R->Low += start * R->Range; R->Range *= size; - RC_NORM_LOCAL(p); + RC_NORM_LOCAL(p) } void Ppmd7z_Flush_RangeEnc(CPpmd7 *p) { unsigned i; for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); + Ppmd7z_RangeEnc_ShiftLow(p); } -#define RC_Encode(start, size) RangeEnc_Encode(p, start, size); -#define RC_EncodeFinal(start, size) RC_Encode(start, size); RC_NORM_REMOTE(p); +#define RC_Encode(start, size) Ppmd7z_RangeEnc_Encode(p, start, size); +#define RC_EncodeFinal(start, size) RC_Encode(start, size) RC_NORM_REMOTE(p) #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) #define SUFFIX(ctx) CTX((ctx)->Suffix) -typedef CPpmd7_Context * CTX_PTR; +// typedef CPpmd7_Context * CTX_PTR; #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd7_UpdateModel(CPpmd7 *p); -#define MASK(sym) ((unsigned char *)charMask)[sym] +#define MASK(sym) ((Byte *)charMask)[sym] -MY_FORCE_INLINE +Z7_FORCE_INLINE static void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol) { @@ -104,7 +104,7 @@ if (s->Symbol == symbol) { // R->Range /= p->MinContext->Union2.SummFreq; - RC_EncodeFinal(0, s->Freq); + RC_EncodeFinal(0, s->Freq) p->FoundState = s; Ppmd7_Update1_0(p); return; @@ -117,7 +117,7 @@ if ((++s)->Symbol == symbol) { // R->Range /= p->MinContext->Union2.SummFreq; - RC_EncodeFinal(sum, s->Freq); + RC_EncodeFinal(sum, s->Freq) p->FoundState = s; Ppmd7_Update1(p); return; @@ -127,10 +127,10 @@ while (--i); // R->Range /= p->MinContext->Union2.SummFreq; - RC_Encode(sum, p->MinContext->Union2.SummFreq - sum); + RC_Encode(sum, p->MinContext->Union2.SummFreq - sum) p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // MASK(s->Symbol) = 0; // i = p->MinContext->NumStats - 1; // do { MASK((--s)->Symbol) = 0; } while (--i); @@ -139,8 +139,8 @@ MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -153,20 +153,20 @@ UInt16 *prob = Ppmd7_GetBinSumm(p); CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); UInt32 pr = *prob; - UInt32 bound = (R->Range >> 14) * pr; + const UInt32 bound = (R->Range >> 14) * pr; pr = PPMD_UPDATE_PROB_1(pr); if (s->Symbol == symbol) { *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); // RangeEnc_EncodeBit_0(p, bound); R->Range = bound; - RC_NORM_1(p); + RC_NORM_1(p) // p->FoundState = s; // Ppmd7_UpdateBin(p); { - unsigned freq = s->Freq; - CTX_PTR c = CTX(SUCCESSOR(s)); + const unsigned freq = s->Freq; + CPpmd7_Context *c = CTX(SUCCESSOR(s)); p->FoundState = s; p->PrevSuccess = 1; p->RunLength++; @@ -187,7 +187,7 @@ R->Range -= bound; RC_NORM_LOCAL(p) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(s->Symbol) = 0; p->PrevSuccess = 0; } @@ -248,14 +248,14 @@ do { - unsigned cur = s->Symbol; + const unsigned cur = s->Symbol; if ((int)cur == symbol) { - UInt32 low = sum; - UInt32 freq = s->Freq; + const UInt32 low = sum; + const UInt32 freq = s->Freq; unsigned num2; - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sum += escFreq; @@ -265,21 +265,20 @@ if (num2 != 0) { s += i; - for (;;) + do { - unsigned sym0 = s[0].Symbol; - unsigned sym1 = s[1].Symbol; + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; s += 2; sum += (s[-2].Freq & (unsigned)(MASK(sym0))); sum += (s[-1].Freq & (unsigned)(MASK(sym1))); - if (--num2 == 0) - break; } + while (--num2); } R->Range /= sum; - RC_EncodeFinal(low, freq); + RC_EncodeFinal(low, freq) Ppmd7_Update2(p); return; } @@ -289,21 +288,21 @@ while (--i); { - UInt32 total = sum + escFreq; + const UInt32 total = sum + escFreq; see->Summ = (UInt16)(see->Summ + total); R->Range /= total; - RC_Encode(sum, escFreq); + RC_Encode(sum, escFreq) } { - CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + const CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); s--; MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -321,3 +320,18 @@ Ppmd7z_EncodeSymbol(p, *buf); } } + +#undef kTopValue +#undef WRITE_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Encode +#undef RC_EncodeFinal +#undef SUFFIX +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru 7zip-22.01+dfsg/C/Ppmd7aDec.c 7zip-22.01+really25.01+dfsg/C/Ppmd7aDec.c --- 7zip-22.01+dfsg/C/Ppmd7aDec.c 2021-04-13 19:22:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd7aDec.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd7aDec.c -- PPMd7a (PPMdH) Decoder -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ @@ -8,8 +8,8 @@ #include "Ppmd7.h" -#define kTop (1 << 24) -#define kBot (1 << 15) +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) #define READ_BYTE(p) IByteIn_Read((p)->Stream) @@ -37,9 +37,9 @@ #define R (&p->rc.dec) -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeDec_Decode(CPpmd7 *p, UInt32 start, UInt32 size) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7a_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) { start *= R->Range; R->Low += start; @@ -48,9 +48,9 @@ RC_NORM_LOCAL(R) } -#define RC_Decode(start, size) RangeDec_Decode(p, start, size); -#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) -#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) +#define RC_Decode(start, size) Ppmd7a_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) @@ -58,7 +58,7 @@ #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd7_UpdateModel(CPpmd7 *p); -#define MASK(sym) ((unsigned char *)charMask)[sym] +#define MASK(sym) ((Byte *)charMask)[sym] int Ppmd7a_DecodeSymbol(CPpmd7 *p) @@ -70,7 +70,7 @@ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); unsigned i; UInt32 count, hiCnt; - UInt32 summFreq = p->MinContext->Union2.SummFreq; + const UInt32 summFreq = p->MinContext->Union2.SummFreq; if (summFreq > R->Range) return PPMD7_SYM_ERROR; @@ -81,7 +81,7 @@ if ((Int32)(count -= s->Freq) < 0) { Byte sym; - RC_DecodeFinal(0, s->Freq); + RC_DecodeFinal(0, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1_0(p); @@ -96,7 +96,7 @@ if ((Int32)(count -= (++s)->Freq) < 0) { Byte sym; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1(p); @@ -109,10 +109,10 @@ return PPMD7_SYM_ERROR; hiCnt -= count; - RC_Decode(hiCnt, summFreq - hiCnt); + RC_Decode(hiCnt, summFreq - hiCnt) p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // i = p->MinContext->NumStats - 1; // do { MASK((--s)->Symbol) = 0; } while (--i); { @@ -120,8 +120,8 @@ MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -176,7 +176,7 @@ R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0; RC_NORM_LOCAL(R) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; p->PrevSuccess = 0; } @@ -209,17 +209,17 @@ unsigned num2 = num / 2; num &= 1; - hiCnt = (s->Freq & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num); + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); s += num; p->MinContext = mc; do { - unsigned sym0 = s[0].Symbol; - unsigned sym1 = s[1].Symbol; + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; s += 2; - hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0))); - hiCnt += (s[-1].Freq & (unsigned)(MASK(sym1))); + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); } while (--num2); } @@ -238,20 +238,20 @@ s = Ppmd7_GetStats(p, p->MinContext); hiCnt = count; - // count -= s->Freq & (unsigned)(MASK(s->Symbol)); + // count -= s->Freq & (UInt32)(MASK(s->Symbol)); // if ((Int32)count >= 0) { for (;;) { - count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - }; + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + } } s--; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) // new (see->Summ) value can overflow over 16-bits in some rare cases - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sym = s->Symbol; Ppmd7_Update2(p); @@ -261,7 +261,7 @@ if (count >= freqSum) return PPMD7_SYM_ERROR; - RC_Decode(hiCnt, freqSum - hiCnt); + RC_Decode(hiCnt, freqSum - hiCnt) // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. // new (see->Summ) value can overflow over 16-bits in some rare cases @@ -277,3 +277,19 @@ while (s != s2); } } + +#undef kTop +#undef kBot +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru 7zip-22.01+dfsg/C/Ppmd8.c 7zip-22.01+really25.01+dfsg/C/Ppmd8.c --- 7zip-22.01+dfsg/C/Ppmd8.c 2021-04-13 19:20:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd8.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd8.c -- PPMdI codec -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -14,7 +14,7 @@ MY_ALIGN(16) static const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; MY_ALIGN(16) -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; +static const UInt16 PPMD8_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; #define MAX_FREQ 124 #define UNIT_SIZE 12 @@ -33,7 +33,7 @@ #define ONE_STATE(ctx) Ppmd8Context_OneState(ctx) #define SUFFIX(ctx) CTX((ctx)->Suffix) -typedef CPpmd8_Context * CTX_PTR; +typedef CPpmd8_Context * PPMD8_CTX_PTR; struct CPpmd8_Node_; @@ -114,7 +114,7 @@ #define EMPTY_NODE 0xFFFFFFFF -static void InsertNode(CPpmd8 *p, void *node, unsigned indx) +static void Ppmd8_InsertNode(CPpmd8 *p, void *node, unsigned indx) { ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE; ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx]; @@ -124,7 +124,7 @@ } -static void *RemoveNode(CPpmd8 *p, unsigned indx) +static void *Ppmd8_RemoveNode(CPpmd8 *p, unsigned indx) { CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]); p->FreeList[indx] = node->Next; @@ -134,16 +134,16 @@ } -static void SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +static void Ppmd8_SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx) { unsigned i, nu = I2U(oldIndx) - I2U(newIndx); ptr = (Byte *)ptr + U2B(I2U(newIndx)); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + Ppmd8_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); } - InsertNode(p, ptr, i); + Ppmd8_InsertNode(p, ptr, i); } @@ -159,7 +159,7 @@ -static void GlueFreeBlocks(CPpmd8 *p) +static void Ppmd8_GlueFreeBlocks(CPpmd8 *p) { /* we use first UInt32 field of 12-bytes UNITs as record type stamp @@ -239,27 +239,27 @@ if (nu == 0) continue; for (; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); + Ppmd8_InsertNode(p, node, PPMD_NUM_INDEXES - 1); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, node + k, (unsigned)nu - k - 1); + Ppmd8_InsertNode(p, node + k, (unsigned)nu - k - 1); } - InsertNode(p, node, i); + Ppmd8_InsertNode(p, node, i); } } -MY_NO_INLINE -static void *AllocUnitsRare(CPpmd8 *p, unsigned indx) +Z7_NO_INLINE +static void *Ppmd8_AllocUnitsRare(CPpmd8 *p, unsigned indx) { unsigned i; if (p->GlueCount == 0) { - GlueFreeBlocks(p); + Ppmd8_GlueFreeBlocks(p); if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd8_RemoveNode(p, indx); } i = indx; @@ -277,17 +277,17 @@ while (p->FreeList[i] == 0); { - void *block = RemoveNode(p, i); - SplitBlock(p, block, i, indx); + void *block = Ppmd8_RemoveNode(p, i); + Ppmd8_SplitBlock(p, block, i, indx); return block; } } -static void *AllocUnits(CPpmd8 *p, unsigned indx) +static void *Ppmd8_AllocUnits(CPpmd8 *p, unsigned indx) { if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd8_RemoveNode(p, indx); { UInt32 numBytes = U2B(I2U(indx)); Byte *lo = p->LoUnit; @@ -297,13 +297,22 @@ return lo; } } - return AllocUnitsRare(p, indx); + return Ppmd8_AllocUnitsRare(p, indx); } -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } +#define MEM_12_CPY(dest, src, num) \ + { UInt32 *d = (UInt32 *)(dest); \ + const UInt32 *z = (const UInt32 *)(src); \ + unsigned n = (num); \ + do { \ + d[0] = z[0]; \ + d[1] = z[1]; \ + d[2] = z[2]; \ + z += 3; \ + d += 3; \ + } while (--n); \ + } @@ -315,26 +324,26 @@ return oldPtr; if (p->FreeList[i1] != 0) { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); + void *ptr = Ppmd8_RemoveNode(p, i1); + MEM_12_CPY(ptr, oldPtr, newNU) + Ppmd8_InsertNode(p, oldPtr, i0); return ptr; } - SplitBlock(p, oldPtr, i0, i1); + Ppmd8_SplitBlock(p, oldPtr, i0, i1); return oldPtr; } static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu) { - InsertNode(p, ptr, U2I(nu)); + Ppmd8_InsertNode(p, ptr, U2I(nu)); } static void SpecialFreeUnit(CPpmd8 *p, void *ptr) { if ((Byte *)ptr != p->UnitsStart) - InsertNode(p, ptr, 0); + Ppmd8_InsertNode(p, ptr, 0); else { #ifdef PPMD8_FREEZE_SUPPORT @@ -352,10 +361,10 @@ void *ptr; if ((Byte *)oldPtr > p->UnitsStart + (1 << 14) || REF(oldPtr) > p->FreeList[indx]) return oldPtr; - ptr = RemoveNode(p, indx); - MyMem12Cpy(ptr, oldPtr, nu); + ptr = Ppmd8_RemoveNode(p, indx); + MEM_12_CPY(ptr, oldPtr, nu) if ((Byte *)oldPtr != p->UnitsStart) - InsertNode(p, oldPtr, indx); + Ppmd8_InsertNode(p, oldPtr, indx); else p->UnitsStart += U2B(I2U(indx)); return ptr; @@ -411,22 +420,22 @@ #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) +static void Ppmd8State_SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { - Ppmd_SET_SUCCESSOR(p, v); + Ppmd_SET_SUCCESSOR(p, v) } #define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); } -MY_NO_INLINE +Z7_NO_INLINE static -void RestartModel(CPpmd8 *p) +void Ppmd8_RestartModel(CPpmd8 *p) { unsigned i, k, m; memset(p->FreeList, 0, sizeof(p->FreeList)); memset(p->Stamps, 0, sizeof(p->Stamps)); - RESET_TEXT(0); + RESET_TEXT(0) p->HiUnit = p->Text + p->Size; p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; p->GlueCount = 0; @@ -436,8 +445,8 @@ p->PrevSuccess = 0; { - CPpmd8_Context *mc = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + CPpmd8_Context *mc = (PPMD8_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd8_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ p->LoUnit += U2B(256 / 2); p->MaxContext = p->MinContext = mc; @@ -452,7 +461,7 @@ { s->Symbol = (Byte)i; s->Freq = 1; - SetSuccessor(s, 0); + Ppmd8State_SetSuccessor(s, 0); } } @@ -475,7 +484,7 @@ { unsigned r; UInt16 *dest = p->BinSumm[m] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 1)); + const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD8_kInitBinEsc[k] / (i + 1)); for (r = 0; r < 64; r += 8) dest[r] = val; } @@ -507,7 +516,7 @@ { p->MaxOrder = maxOrder; p->RestoreMethod = restoreMethod; - RestartModel(p); + Ppmd8_RestartModel(p); } @@ -531,7 +540,7 @@ It increases Escape_Freq for sum of all removed symbols. */ -static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale) +static void Refresh(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned oldNU, unsigned scale) { unsigned i = ctx->NumStats, escFreq, sumFreq, flags; CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1); @@ -581,7 +590,7 @@ } -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) +static void SWAP_STATES(CPpmd_State *t1, CPpmd_State *t2) { CPpmd_State tmp = *t1; *t1 = *t2; @@ -597,7 +606,7 @@ if the (Union4.Stats) is close to (UnitsStart), it moves it up. */ -static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order) +static CPpmd_Void_Ref CutOff(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned order) { int ns = ctx->NumStats; unsigned nu; @@ -613,7 +622,7 @@ successor = CutOff(p, CTX(successor), order + 1); else successor = 0; - SetSuccessor(s, successor); + Ppmd8State_SetSuccessor(s, successor); if (successor || order <= 9) /* O_BOUND */ return REF(ctx); } @@ -630,11 +639,11 @@ if ((UInt32)((Byte *)stats - p->UnitsStart) <= (1 << 14) && (CPpmd_Void_Ref)ctx->Union4.Stats <= p->FreeList[indx]) { - void *ptr = RemoveNode(p, indx); + void *ptr = Ppmd8_RemoveNode(p, indx); ctx->Union4.Stats = STATS_REF(ptr); - MyMem12Cpy(ptr, (const void *)stats, nu); + MEM_12_CPY(ptr, (const void *)stats, nu) if ((Byte *)stats != p->UnitsStart) - InsertNode(p, stats, indx); + Ppmd8_InsertNode(p, stats, indx); else p->UnitsStart += U2B(I2U(indx)); stats = ptr; @@ -656,16 +665,16 @@ } else { - SwapStates(s, s2); - SetSuccessor(s2, 0); + SWAP_STATES(s, s2); + Ppmd8State_SetSuccessor(s2, 0); } } else { if (order < p->MaxOrder) - SetSuccessor(s, CutOff(p, CTX(successor), order + 1)); + Ppmd8State_SetSuccessor(s, CutOff(p, CTX(successor), order + 1)); else - SetSuccessor(s, 0); + Ppmd8State_SetSuccessor(s, 0); } } while (--s >= stats); @@ -711,7 +720,7 @@ removes Bin Context without Successor, if suffix of that context is also binary. */ -static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, CTX_PTR ctx, unsigned order) +static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned order) { if (!ctx->NumStats) { @@ -721,7 +730,7 @@ successor = RemoveBinContexts(p, CTX(successor), order + 1); else successor = 0; - SetSuccessor(s, successor); + Ppmd8State_SetSuccessor(s, successor); /* Suffix context can be removed already, since different (high-order) Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */ if (!successor && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF)) @@ -737,9 +746,9 @@ { CPpmd_Void_Ref successor = SUCCESSOR(s); if ((Byte *)Ppmd8_GetPtr(p, successor) >= p->UnitsStart && order < p->MaxOrder) - SetSuccessor(s, RemoveBinContexts(p, CTX(successor), order + 1)); + Ppmd8State_SetSuccessor(s, RemoveBinContexts(p, CTX(successor), order + 1)); else - SetSuccessor(s, 0); + Ppmd8State_SetSuccessor(s, 0); } while (--s >= STATS(ctx)); } @@ -767,15 +776,15 @@ #endif -static void RestoreModel(CPpmd8 *p, CTX_PTR ctxError +static void RestoreModel(CPpmd8 *p, PPMD8_CTX_PTR ctxError #ifdef PPMD8_FREEZE_SUPPORT - , CTX_PTR fSuccessor + , PPMD8_CTX_PTR fSuccessor #endif ) { - CTX_PTR c; + PPMD8_CTX_PTR c; CPpmd_State *s; - RESET_TEXT(0); + RESET_TEXT(0) // we go here in cases of error of allocation for context (c1) // Order(MinContext) < Order(ctxError) <= Order(MaxContext) @@ -831,7 +840,7 @@ else #endif if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1)) - RestartModel(p); + Ppmd8_RestartModel(p); else { while (p->MaxContext->Suffix) @@ -850,8 +859,8 @@ -MY_NO_INLINE -static CTX_PTR CreateSuccessors(CPpmd8 *p, BoolInt skip, CPpmd_State *s1, CTX_PTR c) +Z7_NO_INLINE +static PPMD8_CTX_PTR Ppmd8_CreateSuccessors(CPpmd8 *p, BoolInt skip, CPpmd_State *s1, PPMD8_CTX_PTR c) { CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); @@ -927,15 +936,15 @@ do { - CTX_PTR c1; + PPMD8_CTX_PTR c1; /* = AllocContext(p); */ if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); + c1 = (PPMD8_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); + c1 = (PPMD8_CTX_PTR)Ppmd8_RemoveNode(p, 0); else { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); + c1 = (PPMD8_CTX_PTR)Ppmd8_AllocUnitsRare(p, 0); if (!c1) return NULL; } @@ -943,9 +952,9 @@ c1->NumStats = 0; c1->Union2.State2.Symbol = newSym; c1->Union2.State2.Freq = newFreq; - SetSuccessor(ONE_STATE(c1), upBranch); + Ppmd8State_SetSuccessor(ONE_STATE(c1), upBranch); c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); + Ppmd8State_SetSuccessor(ps[--numPs], REF(c1)); c = c1; } while (numPs != 0); @@ -954,10 +963,10 @@ } -static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c) +static PPMD8_CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, PPMD8_CTX_PTR c) { CPpmd_State *s = NULL; - CTX_PTR c1 = c; + PPMD8_CTX_PTR c1 = c; CPpmd_Void_Ref upBranch = REF(p->Text); #ifdef PPMD8_FREEZE_SUPPORT @@ -967,7 +976,7 @@ ps[numPs++] = p->FoundState; #endif - SetSuccessor(p->FoundState, upBranch); + Ppmd8State_SetSuccessor(p->FoundState, upBranch); p->OrderFall++; for (;;) @@ -985,8 +994,8 @@ #ifdef PPMD8_FREEZE_SUPPORT if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) { - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); + do { Ppmd8State_SetSuccessor(ps[--numPs], REF(c)); } while (numPs); + RESET_TEXT(1) p->OrderFall = 1; } #endif @@ -1014,7 +1023,7 @@ #ifdef PPMD8_FREEZE_SUPPORT ps[numPs++] = s; #endif - SetSuccessor(s, upBranch); + Ppmd8State_SetSuccessor(s, upBranch); p->OrderFall++; } @@ -1022,8 +1031,8 @@ if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) { c = CTX(SUCCESSOR(s)); - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); + do { Ppmd8State_SetSuccessor(ps[--numPs], REF(c)); } while (numPs); + RESET_TEXT(1) p->OrderFall = 1; return c; } @@ -1031,15 +1040,15 @@ #endif if (SUCCESSOR(s) <= upBranch) { - CTX_PTR successor; + PPMD8_CTX_PTR successor; CPpmd_State *s2 = p->FoundState; p->FoundState = s; - successor = CreateSuccessors(p, False, NULL, c); + successor = Ppmd8_CreateSuccessors(p, False, NULL, c); if (!successor) - SetSuccessor(s, 0); + Ppmd8State_SetSuccessor(s, 0); else - SetSuccessor(s, REF(successor)); + Ppmd8State_SetSuccessor(s, REF(successor)); p->FoundState = s2; } @@ -1047,7 +1056,7 @@ CPpmd_Void_Ref successor = SUCCESSOR(s); if (p->OrderFall == 1 && c1 == p->MaxContext) { - SetSuccessor(p->FoundState, successor); + Ppmd8State_SetSuccessor(p->FoundState, successor); p->Text--; } if (successor == 0) @@ -1059,11 +1068,11 @@ void Ppmd8_UpdateModel(CPpmd8 *p); -MY_NO_INLINE +Z7_NO_INLINE void Ppmd8_UpdateModel(CPpmd8 *p) { CPpmd_Void_Ref maxSuccessor, minSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; + PPMD8_CTX_PTR c; unsigned s0, ns, fFreq = p->FoundState->Freq; Byte flag, fSymbol = p->FoundState->Symbol; { @@ -1096,7 +1105,7 @@ if (s[0].Freq >= s[-1].Freq) { - SwapStates(&s[0], &s[-1]); + SWAP_STATES(&s[0], &s[-1]); s--; } } @@ -1112,14 +1121,14 @@ c = p->MaxContext; if (p->OrderFall == 0 && minSuccessor) { - CTX_PTR cs = CreateSuccessors(p, True, s, p->MinContext); + PPMD8_CTX_PTR cs = Ppmd8_CreateSuccessors(p, True, s, p->MinContext); if (!cs) { - SetSuccessor(p->FoundState, 0); + Ppmd8State_SetSuccessor(p->FoundState, 0); RESTORE_MODEL(c, CTX(minSuccessor)); return; } - SetSuccessor(p->FoundState, REF(cs)); + Ppmd8State_SetSuccessor(p->FoundState, REF(cs)); p->MinContext = p->MaxContext = cs; return; } @@ -1141,7 +1150,7 @@ if (!minSuccessor) { - CTX_PTR cs = ReduceOrder(p, s, p->MinContext); + PPMD8_CTX_PTR cs = ReduceOrder(p, s, p->MinContext); if (!cs) { RESTORE_MODEL(c, NULL); @@ -1151,7 +1160,7 @@ } else if ((Byte *)Ppmd8_GetPtr(p, minSuccessor) < p->UnitsStart) { - CTX_PTR cs = CreateSuccessors(p, False, s, p->MinContext); + PPMD8_CTX_PTR cs = Ppmd8_CreateSuccessors(p, False, s, p->MinContext); if (!cs) { RESTORE_MODEL(c, NULL); @@ -1169,7 +1178,7 @@ else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) { maxSuccessor = minSuccessor; - RESET_TEXT(0); + RESET_TEXT(0) p->OrderFall = 0; } #endif @@ -1215,11 +1224,11 @@ if ((ns1 & 1) != 0) { /* Expand for one UNIT */ - unsigned oldNU = (ns1 + 1) >> 1; - unsigned i = U2I(oldNU); + const unsigned oldNU = (ns1 + 1) >> 1; + const unsigned i = U2I(oldNU); if (i != U2I((size_t)oldNU + 1)) { - void *ptr = AllocUnits(p, i + 1); + void *ptr = Ppmd8_AllocUnits(p, i + 1); void *oldPtr; if (!ptr) { @@ -1227,15 +1236,15 @@ return; } oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); + MEM_12_CPY(ptr, oldPtr, oldNU) + Ppmd8_InsertNode(p, oldPtr, i); c->Union4.Stats = STATS_REF(ptr); } } sum = c->Union2.SummFreq; /* max increase of Escape_Freq is 1 here. an average increase is 1/3 per symbol */ - sum += (3 * ns1 + 1 < ns); + sum += (UInt32)(unsigned)(3 * ns1 + 1 < ns); /* original PPMdH uses 16-bit variable for (sum) here. But (sum < ???). Do we need to truncate (sum) to 16-bit */ // sum = (UInt16)sum; @@ -1243,7 +1252,7 @@ else { - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); + CPpmd_State *s = (CPpmd_State*)Ppmd8_AllocUnits(p, 0); if (!s) { RESTORE_MODEL(c, CTX(minSuccessor)); @@ -1255,7 +1264,7 @@ s->Symbol = c->Union2.State2.Symbol; s->Successor_0 = c->Union4.State4.Successor_0; s->Successor_1 = c->Union4.State4.Successor_1; - // SetSuccessor(s, c->Union4.Stats); // call it only for debug purposes to check the order of + // Ppmd8State_SetSuccessor(s, c->Union4.Stats); // call it only for debug purposes to check the order of // (Successor_0 and Successor_1) in LE/BE. c->Union4.Stats = REF(s); if (freq < MAX_FREQ / 4 - 1) @@ -1265,7 +1274,7 @@ s->Freq = (Byte)freq; - sum = freq + p->InitEsc + (ns > 2); // Ppmd8 (> 2) + sum = (UInt32)(freq + p->InitEsc + (ns > 2)); // Ppmd8 (> 2) } } @@ -1275,7 +1284,7 @@ UInt32 sf = (UInt32)s0 + sum; s->Symbol = fSymbol; c->NumStats = (Byte)(ns1 + 1); - SetSuccessor(s, maxSuccessor); + Ppmd8State_SetSuccessor(s, maxSuccessor); c->Flags |= flag; if (cf < 6 * sf) { @@ -1299,8 +1308,8 @@ -MY_NO_INLINE -static void Rescale(CPpmd8 *p) +Z7_NO_INLINE +static void Ppmd8_Rescale(CPpmd8 *p) { unsigned i, adder, sumFreq, escFreq; CPpmd_State *stats = STATS(p->MinContext); @@ -1389,7 +1398,7 @@ *s = *stats; s->Freq = (Byte)freq; p->FoundState = s; - InsertNode(p, stats, U2I(n0)); + Ppmd8_InsertNode(p, stats, U2I(n0)); return; } @@ -1437,10 +1446,10 @@ { // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ - unsigned summ = (UInt16)see->Summ; // & 0xFFFF - unsigned r = (summ >> see->Shift); + const unsigned summ = (UInt16)see->Summ; // & 0xFFFF + const unsigned r = (summ >> see->Shift); see->Summ = (UInt16)(summ - r); - *escFreq = r + (r == 0); + *escFreq = (UInt32)(r + (r == 0)); } } else @@ -1452,9 +1461,9 @@ } -static void NextContext(CPpmd8 *p) +static void Ppmd8_NextContext(CPpmd8 *p) { - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + PPMD8_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart) p->MaxContext = p->MinContext = c; else @@ -1471,12 +1480,12 @@ s->Freq = (Byte)freq; if (freq > s[-1].Freq) { - SwapStates(s, &s[-1]); + SWAP_STATES(s, &s[-1]); p->FoundState = --s; if (freq > MAX_FREQ) - Rescale(p); + Ppmd8_Rescale(p); } - NextContext(p); + Ppmd8_NextContext(p); } @@ -1485,15 +1494,15 @@ CPpmd_State *s = p->FoundState; CPpmd8_Context *mc = p->MinContext; unsigned freq = s->Freq; - unsigned summFreq = mc->Union2.SummFreq; + const unsigned summFreq = mc->Union2.SummFreq; p->PrevSuccess = (2 * freq >= summFreq); // Ppmd8 (>=) - p->RunLength += (int)p->PrevSuccess; + p->RunLength += (Int32)p->PrevSuccess; mc->Union2.SummFreq = (UInt16)(summFreq + 4); freq += 4; s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); - NextContext(p); + Ppmd8_Rescale(p); + Ppmd8_NextContext(p); } @@ -1504,7 +1513,7 @@ p->FoundState->Freq = (Byte)(freq + (freq < 196)); // Ppmd8 (196) p->PrevSuccess = 1; p->RunLength++; - NextContext(p); + Ppmd8_NextContext(p); } */ @@ -1517,7 +1526,7 @@ p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); + Ppmd8_Rescale(p); Ppmd8_UpdateModel(p); } @@ -1526,7 +1535,7 @@ GlueCount, and Glue method BinSum See / EscFreq - CreateSuccessors updates more suffix contexts + Ppmd8_CreateSuccessors updates more suffix contexts Ppmd8_UpdateModel consts. PrevSuccess Update @@ -1535,3 +1544,31 @@ (1 << 3) - there is symbol in Stats with (sym >= 0x40) in (1 << 4) - main symbol of context is (sym >= 0x40) */ + +#undef RESET_TEXT +#undef FLAG_RESCALED +#undef FLAG_PREV_HIGH +#undef HiBits_Prepare +#undef HiBits_Convert_3 +#undef HiBits_Convert_4 +#undef PPMD8_HiBitsFlag_3 +#undef PPMD8_HiBitsFlag_4 +#undef RESTORE_MODEL + +#undef MAX_FREQ +#undef UNIT_SIZE +#undef U2B +#undef U2I +#undef I2U + +#undef REF +#undef STATS_REF +#undef CTX +#undef STATS +#undef ONE_STATE +#undef SUFFIX +#undef NODE +#undef EMPTY_NODE +#undef MEM_12_CPY +#undef SUCCESSOR +#undef SWAP_STATES diff -Nru 7zip-22.01+dfsg/C/Ppmd8.h 7zip-22.01+really25.01+dfsg/C/Ppmd8.h --- 7zip-22.01+dfsg/C/Ppmd8.h 2021-04-13 18:42:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd8.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,11 +1,11 @@ /* Ppmd8.h -- Ppmd8 (PPMdI) compression codec -2021-04-13 : Igor Pavlov : Public domain +2023-04-02 : Igor Pavlov : Public domain This code is based on: PPMd var.I (2002): Dmitry Shkarin : Public domain Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ -#ifndef __PPMD8_H -#define __PPMD8_H +#ifndef ZIP7_INC_PPMD8_H +#define ZIP7_INC_PPMD8_H #include "Ppmd.h" @@ -87,8 +87,8 @@ UInt32 Low; union { - IByteIn *In; - IByteOut *Out; + IByteInPtr In; + IByteOutPtr Out; } Stream; Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment diff -Nru 7zip-22.01+dfsg/C/Ppmd8Dec.c 7zip-22.01+really25.01+dfsg/C/Ppmd8Dec.c --- 7zip-22.01+dfsg/C/Ppmd8Dec.c 2021-04-13 19:22:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd8Dec.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd8Dec.c -- Ppmd8 (PPMdI) Decoder -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on: PPMd var.I (2002): Dmitry Shkarin : Public domain Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ @@ -8,8 +8,8 @@ #include "Ppmd8.h" -#define kTop (1 << 24) -#define kBot (1 << 15) +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) #define READ_BYTE(p) IByteIn_Read((p)->Stream.In) @@ -37,9 +37,9 @@ #define R p -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd8_RD_Decode(CPpmd8 *p, UInt32 start, UInt32 size) { start *= R->Range; R->Low += start; @@ -48,17 +48,17 @@ RC_NORM_LOCAL(R) } -#define RC_Decode(start, size) RangeDec_Decode(p, start, size); -#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) -#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) +#define RC_Decode(start, size) Ppmd8_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) #define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) -typedef CPpmd8_Context * CTX_PTR; +// typedef CPpmd8_Context * CTX_PTR; #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd8_UpdateModel(CPpmd8 *p); -#define MASK(sym) ((unsigned char *)charMask)[sym] +#define MASK(sym) ((Byte *)charMask)[sym] int Ppmd8_DecodeSymbol(CPpmd8 *p) @@ -81,7 +81,7 @@ if ((Int32)(count -= s->Freq) < 0) { Byte sym; - RC_DecodeFinal(0, s->Freq); + RC_DecodeFinal(0, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd8_Update1_0(p); @@ -96,7 +96,7 @@ if ((Int32)(count -= (++s)->Freq) < 0) { Byte sym; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd8_Update1(p); @@ -109,10 +109,10 @@ return PPMD8_SYM_ERROR; hiCnt -= count; - RC_Decode(hiCnt, summFreq - hiCnt); + RC_Decode(hiCnt, summFreq - hiCnt) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // i = p->MinContext->NumStats - 1; // do { MASK((--s)->Symbol) = 0; } while (--i); { @@ -120,8 +120,8 @@ MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -152,7 +152,7 @@ // Ppmd8_UpdateBin(p); { unsigned freq = s->Freq; - CTX_PTR c = CTX(SUCCESSOR(s)); + CPpmd8_Context *c = CTX(SUCCESSOR(s)); sym = s->Symbol; p->FoundState = s; p->PrevSuccess = 1; @@ -176,7 +176,7 @@ R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0; RC_NORM_LOCAL(R) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; p->PrevSuccess = 0; } @@ -209,17 +209,17 @@ unsigned num2 = num / 2; num &= 1; - hiCnt = (s->Freq & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num); + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); s += num; p->MinContext = mc; do { - unsigned sym0 = s[0].Symbol; - unsigned sym1 = s[1].Symbol; + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; s += 2; - hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0))); - hiCnt += (s[-1].Freq & (unsigned)(MASK(sym1))); + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); } while (--num2); } @@ -227,7 +227,7 @@ see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); freqSum += hiCnt; freqSum2 = freqSum; - PPMD8_CORRECT_SUM_RANGE(R, freqSum2); + PPMD8_CORRECT_SUM_RANGE(R, freqSum2) count = RC_GetThreshold(freqSum2); @@ -235,7 +235,7 @@ if (count < hiCnt) { Byte sym; - // Ppmd_See_Update(see); // new (see->Summ) value can overflow over 16-bits in some rare cases + // Ppmd_See_UPDATE(see) // new (see->Summ) value can overflow over 16-bits in some rare cases s = Ppmd8_GetStats(p, p->MinContext); hiCnt = count; @@ -243,15 +243,15 @@ { for (;;) { - count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; } } s--; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) // new (see->Summ) value can overflow over 16-bits in some rare cases - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sym = s->Symbol; Ppmd8_Update2(p); @@ -261,7 +261,7 @@ if (count >= freqSum2) return PPMD8_SYM_ERROR; - RC_Decode(hiCnt, freqSum2 - hiCnt); + RC_Decode(hiCnt, freqSum2 - hiCnt) // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. // new (see->Summ) value can overflow over 16-bits in some rare cases @@ -277,3 +277,19 @@ while (s != s2); } } + +#undef kTop +#undef kBot +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru 7zip-22.01+dfsg/C/Ppmd8Enc.c 7zip-22.01+really25.01+dfsg/C/Ppmd8Enc.c --- 7zip-22.01+dfsg/C/Ppmd8Enc.c 2021-04-13 19:22:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Ppmd8Enc.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Ppmd8Enc.c -- Ppmd8 (PPMdI) Encoder -2021-04-13 : Igor Pavlov : Public domain +2023-09-07 : Igor Pavlov : Public domain This code is based on: PPMd var.I (2002): Dmitry Shkarin : Public domain Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ @@ -8,8 +8,8 @@ #include "Ppmd8.h" -#define kTop (1 << 24) -#define kBot (1 << 15) +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) #define WRITE_BYTE(p) IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24)) @@ -54,13 +54,13 @@ -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd8_RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total) { R->Low += start * (R->Range /= total); R->Range *= size; - RC_NORM_LOCAL(R); + RC_NORM_LOCAL(R) } @@ -72,19 +72,19 @@ -#define RC_Encode(start, size, total) RangeEnc_Encode(p, start, size, total); -#define RC_EncodeFinal(start, size, total) RC_Encode(start, size, total); RC_NORM_REMOTE(p); +#define RC_Encode(start, size, total) Ppmd8_RangeEnc_Encode(p, start, size, total); +#define RC_EncodeFinal(start, size, total) RC_Encode(start, size, total) RC_NORM_REMOTE(p) #define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) -typedef CPpmd8_Context * CTX_PTR; +// typedef CPpmd8_Context * CTX_PTR; #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd8_UpdateModel(CPpmd8 *p); -#define MASK(sym) ((unsigned char *)charMask)[sym] +#define MASK(sym) ((Byte *)charMask)[sym] -// MY_FORCE_INLINE +// Z7_FORCE_INLINE // static void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol) { @@ -104,7 +104,7 @@ if (s->Symbol == symbol) { - RC_EncodeFinal(0, s->Freq, summFreq); + RC_EncodeFinal(0, s->Freq, summFreq) p->FoundState = s; Ppmd8_Update1_0(p); return; @@ -117,7 +117,7 @@ if ((++s)->Symbol == symbol) { - RC_EncodeFinal(sum, s->Freq, summFreq); + RC_EncodeFinal(sum, s->Freq, summFreq) p->FoundState = s; Ppmd8_Update1(p); return; @@ -127,10 +127,10 @@ while (--i); - RC_Encode(sum, summFreq - sum, summFreq); + RC_Encode(sum, summFreq - sum, summFreq) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // MASK(s->Symbol) = 0; // i = p->MinContext->NumStats; // do { MASK((--s)->Symbol) = 0; } while (--i); @@ -139,8 +139,8 @@ MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -153,20 +153,20 @@ UInt16 *prob = Ppmd8_GetBinSumm(p); CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); UInt32 pr = *prob; - UInt32 bound = (R->Range >> 14) * pr; + const UInt32 bound = (R->Range >> 14) * pr; pr = PPMD_UPDATE_PROB_1(pr); if (s->Symbol == symbol) { *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); // RangeEnc_EncodeBit_0(p, bound); R->Range = bound; - RC_NORM(R); + RC_NORM(R) // p->FoundState = s; // Ppmd8_UpdateBin(p); { - unsigned freq = s->Freq; - CTX_PTR c = CTX(SUCCESSOR(s)); + const unsigned freq = s->Freq; + CPpmd8_Context *c = CTX(SUCCESSOR(s)); p->FoundState = s; p->PrevSuccess = 1; p->RunLength++; @@ -187,7 +187,7 @@ R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - bound; RC_NORM_LOCAL(R) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(s->Symbol) = 0; p->PrevSuccess = 0; } @@ -248,14 +248,14 @@ do { - unsigned cur = s->Symbol; + const unsigned cur = s->Symbol; if ((int)cur == symbol) { - UInt32 low = sum; - UInt32 freq = s->Freq; + const UInt32 low = sum; + const UInt32 freq = s->Freq; unsigned num2; - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sum += escFreq; @@ -265,21 +265,20 @@ if (num2 != 0) { s += i; - for (;;) + do { - unsigned sym0 = s[0].Symbol; - unsigned sym1 = s[1].Symbol; + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; s += 2; sum += (s[-2].Freq & (unsigned)(MASK(sym0))); sum += (s[-1].Freq & (unsigned)(MASK(sym1))); - if (--num2 == 0) - break; } + while (--num2); } - PPMD8_CORRECT_SUM_RANGE(p, sum); + PPMD8_CORRECT_SUM_RANGE(p, sum) - RC_EncodeFinal(low, freq, sum); + RC_EncodeFinal(low, freq, sum) Ppmd8_Update2(p); return; } @@ -291,19 +290,19 @@ { UInt32 total = sum + escFreq; see->Summ = (UInt16)(see->Summ + total); - PPMD8_CORRECT_SUM_RANGE(p, total); + PPMD8_CORRECT_SUM_RANGE(p, total) - RC_Encode(sum, total - sum, total); + RC_Encode(sum, total - sum, total) } { - CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); + const CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); s--; MASK(s->Symbol) = 0; do { - unsigned sym0 = s2[0].Symbol; - unsigned sym1 = s2[1].Symbol; + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; s2 += 2; MASK(sym0) = 0; MASK(sym1) = 0; @@ -312,3 +311,27 @@ } } } + + + + + + + + + +#undef kTop +#undef kBot +#undef WRITE_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Encode +#undef RC_EncodeFinal + +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru 7zip-22.01+dfsg/C/Precomp.h 7zip-22.01+really25.01+dfsg/C/Precomp.h --- 7zip-22.01+dfsg/C/Precomp.h 2013-11-12 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Precomp.h 2024-01-26 11:00:00.000000000 +0000 @@ -1,10 +1,127 @@ -/* Precomp.h -- StdAfx -2013-11-12 : Igor Pavlov : Public domain */ +/* Precomp.h -- precompilation file +2024-01-25 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H +#ifndef ZIP7_INC_PRECOMP_H +#define ZIP7_INC_PRECOMP_H + +/* + this file must be included before another *.h files and before . + this file is included from the following files: + C\*.c + C\Util\*\Precomp.h <- C\Util\*\*.c + CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp + + this file can set the following macros: + Z7_LARGE_PAGES 1 + Z7_LONG_PATH 1 + Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip + _WIN32_WINNT 0x0500 (or higher) + WINVER _WIN32_WINNT + UNICODE 1 + _UNICODE 1 +*/ #include "Compiler.h" -/* #include "7zTypes.h" */ + +#ifdef _MSC_VER +// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#if _MSC_VER >= 1912 +// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception. +#endif +#endif + +/* +// for debug: +#define UNICODE 1 +#define _UNICODE 1 +#define _WIN32_WINNT 0x0500 // win2000 +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +*/ + +#ifdef _WIN32 +/* + this "Precomp.h" file must be included before , + if we want to define _WIN32_WINNT before . +*/ + +#ifndef Z7_LARGE_PAGES +#ifndef Z7_NO_LARGE_PAGES +#define Z7_LARGE_PAGES 1 +#endif +#endif + +#ifndef Z7_LONG_PATH +#ifndef Z7_NO_LONG_PATH +#define Z7_LONG_PATH 1 +#endif +#endif + +#ifndef Z7_DEVICE_FILE +#ifndef Z7_NO_DEVICE_FILE +// #define Z7_DEVICE_FILE 1 +#endif +#endif + +// we don't change macros if included after +#ifndef _WINDOWS_ + +#ifndef Z7_WIN32_WINNT_MIN + #if defined(_M_ARM64) || defined(__aarch64__) + // #define Z7_WIN32_WINNT_MIN 0x0a00 // win10 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT) + // #define Z7_WIN32_WINNT_MIN 0x0602 // win8 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64) + #define Z7_WIN32_WINNT_MIN 0x0503 // win2003 + // #elif defined(_M_IX86) || defined(__i386__) + // #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + #else // x86 and another(old) systems + #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + // #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug + #endif +#endif // Z7_WIN32_WINNT_MIN + + +#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT +#ifdef _WIN32_WINNT + // #error Stop_Compiling_Bad_WIN32_WINNT +#else + #ifndef Z7_NO_DEFINE_WIN32_WINNT +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define _WIN32_WINNT Z7_WIN32_WINNT_MIN +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + #endif +#endif // _WIN32_WINNT + +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT + + +#ifndef _MBCS +#ifndef Z7_NO_UNICODE +// UNICODE and _UNICODE are used by and by 7-zip code. + +#ifndef UNICODE +#define UNICODE 1 +#endif + +#ifndef _UNICODE +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _UNICODE 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // Z7_NO_UNICODE +#endif // _MBCS +#endif // _WINDOWS_ + +// #include "7zWindows.h" + +#endif // _WIN32 #endif diff -Nru 7zip-22.01+dfsg/C/RotateDefs.h 7zip-22.01+really25.01+dfsg/C/RotateDefs.h --- 7zip-22.01+dfsg/C/RotateDefs.h 2015-03-25 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/RotateDefs.h 2023-06-18 11:00:00.000000000 +0000 @@ -1,14 +1,14 @@ /* RotateDefs.h -- Rotate functions -2015-03-25 : Igor Pavlov : Public domain */ +2023-06-18 : Igor Pavlov : Public domain */ -#ifndef __ROTATE_DEFS_H -#define __ROTATE_DEFS_H +#ifndef ZIP7_INC_ROTATE_DEFS_H +#define ZIP7_INC_ROTATE_DEFS_H #ifdef _MSC_VER #include -/* don't use _rotl with MINGW. It can insert slow call to function. */ +/* don't use _rotl with old MINGW. It can insert slow call to function. */ /* #if (_MSC_VER >= 1200) */ #pragma intrinsic(_rotl) @@ -18,12 +18,32 @@ #define rotlFixed(x, n) _rotl((x), (n)) #define rotrFixed(x, n) _rotr((x), (n)) +#if (_MSC_VER >= 1300) +#define Z7_ROTL64(x, n) _rotl64((x), (n)) +#define Z7_ROTR64(x, n) _rotr64((x), (n)) +#else +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + #else /* new compilers can translate these macros to fast commands. */ +#if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5) +/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63))) +#else +/* for old GCC / clang: */ #define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) #define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif #endif diff -Nru 7zip-22.01+dfsg/C/Sha1.c 7zip-22.01+really25.01+dfsg/C/Sha1.c --- 7zip-22.01+dfsg/C/Sha1.c 2021-07-13 09:52:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha1.c 2024-10-29 18:00:00.000000000 +0000 @@ -1,64 +1,60 @@ /* Sha1.c -- SHA-1 Hash -2021-07-13 : Igor Pavlov : Public domain +: Igor Pavlov : Public domain This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ #include "Precomp.h" #include -#include "CpuArch.h" -#include "RotateDefs.h" #include "Sha1.h" - -#if defined(_MSC_VER) && (_MSC_VER < 1900) -// #define USE_MY_MM -#endif +#include "RotateDefs.h" +#include "CpuArch.h" #ifdef MY_CPU_X86_OR_AMD64 - #ifdef _MSC_VER - #if _MSC_VER >= 1200 - #define _SHA_SUPPORTED - #endif - #elif defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define _SHA_SUPPORTED - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 8) // fix that check - #define _SHA_SUPPORTED - #endif - #elif defined(__INTEL_COMPILER) - #if (__INTEL_COMPILER >= 1800) // fix that check - #define _SHA_SUPPORTED - #endif + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) \ + || defined(_MSC_VER) && (_MSC_VER >= 1200) + #define Z7_COMPILER_SHA1_SUPPORTED #endif -#elif defined(MY_CPU_ARM_OR_ARM64) - #ifdef _MSC_VER - #if _MSC_VER >= 1910 && _MSC_VER >= 1929 && _MSC_FULL_VER >= 192930037 - #define _SHA_SUPPORTED +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \ + && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037)) + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define Z7_COMPILER_SHA1_SUPPORTED + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define Z7_COMPILER_SHA1_SUPPORTED #endif - #elif defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define _SHA_SUPPORTED #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define _SHA_SUPPORTED #endif #endif #endif -void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); -#ifdef _SHA_SUPPORTED - void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); +#ifdef Z7_COMPILER_SHA1_SUPPORTED + void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); - static SHA1_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks; - static SHA1_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS_HW; + static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks; + static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW; - #define UPDATE_BLOCKS(p) p->func_UpdateBlocks + #define SHA1_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks #else - #define UPDATE_BLOCKS(p) Sha1_UpdateBlocks + #define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks #endif @@ -66,16 +62,16 @@ { SHA1_FUNC_UPDATE_BLOCKS func = Sha1_UpdateBlocks; - #ifdef _SHA_SUPPORTED + #ifdef Z7_COMPILER_SHA1_SUPPORTED if (algo != SHA1_ALGO_SW) { if (algo == SHA1_ALGO_DEFAULT) - func = g_FUNC_UPDATE_BLOCKS; + func = g_SHA1_FUNC_UPDATE_BLOCKS; else { if (algo != SHA1_ALGO_HW) return False; - func = g_FUNC_UPDATE_BLOCKS_HW; + func = g_SHA1_FUNC_UPDATE_BLOCKS_HW; if (!func) return False; } @@ -85,27 +81,28 @@ return False; #endif - p->func_UpdateBlocks = func; + p->v.vars.func_UpdateBlocks = func; return True; } /* define it for speed optimization */ -// #define _SHA1_UNROLL +// #define Z7_SHA1_UNROLL // allowed unroll steps: (1, 2, 4, 5, 20) -#ifdef _SHA1_UNROLL +#undef Z7_SHA1_BIG_W +#ifdef Z7_SHA1_UNROLL #define STEP_PRE 20 #define STEP_MAIN 20 #else - #define _SHA1_BIG_W + #define Z7_SHA1_BIG_W #define STEP_PRE 5 #define STEP_MAIN 5 #endif -#ifdef _SHA1_BIG_W +#ifdef Z7_SHA1_BIG_W #define kNumW 80 #define w(i) W[i] #else @@ -150,11 +147,11 @@ */ #define M5(i, fx, wx0, wx1) \ - T5 ( a,b,c,d,e, fx, wx0((i) ) ); \ - T5 ( e,a,b,c,d, fx, wx1((i)+1) ); \ - T5 ( d,e,a,b,c, fx, wx1((i)+2) ); \ - T5 ( c,d,e,a,b, fx, wx1((i)+3) ); \ - T5 ( b,c,d,e,a, fx, wx1((i)+4) ); \ + T5 ( a,b,c,d,e, fx, wx0((i) ) ) \ + T5 ( e,a,b,c,d, fx, wx1((i)+1) ) \ + T5 ( d,e,a,b,c, fx, wx1((i)+2) ) \ + T5 ( c,d,e,a,b, fx, wx1((i)+3) ) \ + T5 ( b,c,d,e,a, fx, wx1((i)+4) ) \ #define R5(i, fx, wx) \ M5 ( i, fx, wx, wx) \ @@ -163,17 +160,17 @@ #if STEP_PRE > 5 #define R20_START \ - R5 ( 0, f0, w0); \ - R5 ( 5, f0, w0); \ - R5 ( 10, f0, w0); \ - M5 ( 15, f0, w0, w1); \ + R5 ( 0, f0, w0) \ + R5 ( 5, f0, w0) \ + R5 ( 10, f0, w0) \ + M5 ( 15, f0, w0, w1) \ #elif STEP_PRE == 5 #define R20_START \ { size_t i; for (i = 0; i < 15; i += STEP_PRE) \ - { R5(i, f0, w0); } } \ - M5 ( 15, f0, w0, w1); \ + { R5(i, f0, w0) } } \ + M5 ( 15, f0, w0, w1) \ #else @@ -187,8 +184,8 @@ #define R20_START \ { size_t i; for (i = 0; i < 16; i += STEP_PRE) \ - { R_PRE(i, f0, w0); } } \ - R4 ( 16, f0, w1); \ + { R_PRE(i, f0, w0) } } \ + R4 ( 16, f0, w1) \ #endif @@ -197,10 +194,10 @@ #if STEP_MAIN > 5 #define R20(ii, fx) \ - R5 ( (ii) , fx, w1); \ - R5 ( (ii) + 5 , fx, w1); \ - R5 ( (ii) + 10, fx, w1); \ - R5 ( (ii) + 15, fx, w1); \ + R5 ( (ii) , fx, w1) \ + R5 ( (ii) + 5 , fx, w1) \ + R5 ( (ii) + 10, fx, w1) \ + R5 ( (ii) + 15, fx, w1) \ #else @@ -216,7 +213,7 @@ #define R20(ii, fx) \ { size_t i; for (i = (ii); i < (ii) + 20; i += STEP_MAIN) \ - { R_MAIN(i, fx, w1); } } \ + { R_MAIN(i, fx, w1) } } \ #endif @@ -224,7 +221,7 @@ void Sha1_InitState(CSha1 *p) { - p->count = 0; + p->v.vars.count = 0; p->state[0] = 0x67452301; p->state[1] = 0xEFCDAB89; p->state[2] = 0x98BADCFE; @@ -234,9 +231,9 @@ void Sha1_Init(CSha1 *p) { - p->func_UpdateBlocks = - #ifdef _SHA_SUPPORTED - g_FUNC_UPDATE_BLOCKS; + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA1_SUPPORTED + g_SHA1_FUNC_UPDATE_BLOCKS; #else NULL; #endif @@ -244,12 +241,12 @@ } -MY_NO_INLINE -void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks) +Z7_NO_INLINE +void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks) { UInt32 a, b, c, d, e; UInt32 W[kNumW]; - // if (numBlocks != 0x1264378347) return; + if (numBlocks == 0) return; @@ -266,9 +263,9 @@ #endif R20_START - R20(20, f1); - R20(40, f2); - R20(60, f3); + R20(20, f1) + R20(40, f2) + R20(60, f3) a += state[0]; b += state[1]; @@ -282,32 +279,27 @@ state[3] = d; state[4] = e; - data += 64; + data += SHA1_BLOCK_SIZE; } while (--numBlocks); } -#define Sha1_UpdateBlock(p) UPDATE_BLOCKS(p)(p->state, p->buffer, 1) +#define Sha1_UpdateBlock(p) SHA1_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) void Sha1_Update(CSha1 *p, const Byte *data, size_t size) { if (size == 0) return; - { - unsigned pos = (unsigned)p->count & 0x3F; - unsigned num; - - p->count += size; - - num = 64 - pos; + const unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1); + const unsigned num = SHA1_BLOCK_SIZE - pos; + p->v.vars.count += size; if (num > size) { memcpy(p->buffer + pos, data, size); return; } - if (pos != 0) { size -= num; @@ -317,9 +309,10 @@ } } { - size_t numBlocks = size >> 6; - UPDATE_BLOCKS(p)(p->state, data, numBlocks); - size &= 0x3F; + const size_t numBlocks = size >> 6; + // if (numBlocks) + SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA1_BLOCK_SIZE - 1; if (size == 0) return; data += (numBlocks << 6); @@ -330,64 +323,40 @@ void Sha1_Final(CSha1 *p, Byte *digest) { - unsigned pos = (unsigned)p->count & 0x3F; - - + unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1); p->buffer[pos++] = 0x80; - - if (pos > (64 - 8)) + if (pos > (SHA1_BLOCK_SIZE - 4 * 2)) { - while (pos != 64) { p->buffer[pos++] = 0; } - // memset(&p->buf.buffer[pos], 0, 64 - pos); + while (pos != SHA1_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA1_BLOCK_SIZE - pos); Sha1_UpdateBlock(p); pos = 0; } - - /* - if (pos & 3) - { - p->buffer[pos] = 0; - p->buffer[pos + 1] = 0; - p->buffer[pos + 2] = 0; - pos += 3; - pos &= ~3; - } - { - for (; pos < 64 - 8; pos += 4) - *(UInt32 *)(&p->buffer[pos]) = 0; - } - */ - - memset(&p->buffer[pos], 0, (64 - 8) - pos); - + memset(&p->buffer[pos], 0, (SHA1_BLOCK_SIZE - 4 * 2) - pos); { - UInt64 numBits = (p->count << 3); - SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); - SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); + const UInt64 numBits = p->v.vars.count << 3; + SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32)) + SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 1, (UInt32)(numBits)) } - Sha1_UpdateBlock(p); - SetBe32(digest, p->state[0]); - SetBe32(digest + 4, p->state[1]); - SetBe32(digest + 8, p->state[2]); - SetBe32(digest + 12, p->state[3]); - SetBe32(digest + 16, p->state[4]); + SetBe32(digest, p->state[0]) + SetBe32(digest + 4, p->state[1]) + SetBe32(digest + 8, p->state[2]) + SetBe32(digest + 12, p->state[3]) + SetBe32(digest + 16, p->state[4]) - - - Sha1_InitState(p); } void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size) { - const UInt64 numBits = (p->count + size) << 3; - SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32)); - SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits)); + const UInt64 numBits = (p->v.vars.count + size) << 3; + SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32)) + SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits)) // SetBe32((UInt32 *)(block + size), 0x80000000); - SetUi32((UInt32 *)(void *)(block + size), 0x80); + SetUi32((UInt32 *)(void *)(block + size), 0x80) size += 4; while (size != (SHA1_NUM_BLOCK_WORDS - 2) * 4) { @@ -407,67 +376,66 @@ st[3] = p->state[3]; st[4] = p->state[4]; - UPDATE_BLOCKS(p)(st, data, 1); + SHA1_UPDATE_BLOCKS(p)(st, data, 1); - SetBe32(destDigest + 0 , st[0]); - SetBe32(destDigest + 1 * 4, st[1]); - SetBe32(destDigest + 2 * 4, st[2]); - SetBe32(destDigest + 3 * 4, st[3]); - SetBe32(destDigest + 4 * 4, st[4]); + SetBe32(destDigest + 0 , st[0]) + SetBe32(destDigest + 1 * 4, st[1]) + SetBe32(destDigest + 2 * 4, st[2]) + SetBe32(destDigest + 3 * 4, st[3]) + SetBe32(destDigest + 4 * 4, st[4]) } -void Sha1Prepare() +void Sha1Prepare(void) { - #ifdef _SHA_SUPPORTED +#ifdef Z7_COMPILER_SHA1_SUPPORTED SHA1_FUNC_UPDATE_BLOCKS f, f_hw; f = Sha1_UpdateBlocks; f_hw = NULL; - #ifdef MY_CPU_X86_OR_AMD64 - #ifndef USE_MY_MM +#ifdef MY_CPU_X86_OR_AMD64 if (CPU_IsSupported_SHA() && CPU_IsSupported_SSSE3() - // && CPU_IsSupported_SSE41() ) - #endif - #else +#else if (CPU_IsSupported_SHA1()) - #endif +#endif { // printf("\n========== HW SHA1 ======== \n"); - #if defined(MY_CPU_ARM_OR_ARM64) && defined(_MSC_VER) +#if 1 && defined(MY_CPU_ARM_OR_ARM64) && defined(Z7_MSC_VER_ORIGINAL) && (_MSC_FULL_VER < 192930037) /* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037). - It generated incorrect SHA-1 code. - 21.03 : we test sha1-hardware code at runtime initialization */ - - #pragma message("== SHA1 code: MSC compiler : failure-check code was inserted") - - UInt32 state[5] = { 0, 1, 2, 3, 4 } ; - Byte data[64]; - unsigned i; - for (i = 0; i < sizeof(data); i += 2) - { - data[i ] = (Byte)(i); - data[i + 1] = (Byte)(i + 1); - } - - Sha1_UpdateBlocks_HW(state, data, sizeof(data) / 64); - - if ( state[0] != 0x9acd7297 - || state[1] != 0x4624d898 - || state[2] != 0x0bf079f0 - || state[3] != 0x031e61b3 - || state[4] != 0x8323fe20) - { - // printf("\n========== SHA-1 hardware version failure ======== \n"); - } - else - #endif + It generated incorrect SHA-1 code. */ + #pragma message("== SHA1 code can work incorrectly with this compiler") + #error Stop_Compiling_MSC_Compiler_BUG_SHA1 +#endif { f = f_hw = Sha1_UpdateBlocks_HW; } } - g_FUNC_UPDATE_BLOCKS = f; - g_FUNC_UPDATE_BLOCKS_HW = f_hw; - #endif + g_SHA1_FUNC_UPDATE_BLOCKS = f; + g_SHA1_FUNC_UPDATE_BLOCKS_HW = f_hw; +#endif } + +#undef kNumW +#undef w +#undef w0 +#undef w1 +#undef f0 +#undef f1 +#undef f2 +#undef f3 +#undef T1 +#undef T5 +#undef M5 +#undef R1 +#undef R2 +#undef R4 +#undef R5 +#undef R20_START +#undef R_PRE +#undef R_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA1_BIG_W +#undef Z7_SHA1_UNROLL +#undef Z7_COMPILER_SHA1_SUPPORTED diff -Nru 7zip-22.01+dfsg/C/Sha1.h 7zip-22.01+really25.01+dfsg/C/Sha1.h --- 7zip-22.01+dfsg/C/Sha1.h 2021-02-09 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha1.h 2024-10-28 10:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Sha1.h -- SHA-1 Hash -2021-02-08 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __7Z_SHA1_H -#define __7Z_SHA1_H +#ifndef ZIP7_INC_SHA1_H +#define ZIP7_INC_SHA1_H #include "7zTypes.h" @@ -14,7 +14,10 @@ #define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4) #define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4) -typedef void (MY_FAST_CALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks); + + + +typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks); /* if (the system supports different SHA1 code implementations) @@ -32,11 +35,18 @@ typedef struct { - SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks; - UInt64 count; - UInt64 __pad_2[2]; + union + { + struct + { + SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[4]; + void *_pad_align_ptr[2]; + } v; UInt32 state[SHA1_NUM_DIGEST_WORDS]; - UInt32 __pad_3[3]; + UInt32 _pad_3[3]; Byte buffer[SHA1_BLOCK_SIZE]; } CSha1; @@ -62,7 +72,7 @@ void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size); void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest); -// void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); +// void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); /* call Sha1Prepare() once at program start. diff -Nru 7zip-22.01+dfsg/C/Sha1Opt.c 7zip-22.01+really25.01+dfsg/C/Sha1Opt.c --- 7zip-22.01+dfsg/C/Sha1Opt.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha1Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -1,71 +1,53 @@ /* Sha1Opt.c -- SHA-1 optimized code for SHA-1 hardware instructions -2021-04-01 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" - -#if defined(_MSC_VER) -#if (_MSC_VER < 1900) && (_MSC_VER >= 1200) -// #define USE_MY_MM -#endif -#endif - +#include "Compiler.h" #include "CpuArch.h" +// #define Z7_USE_HW_SHA_STUB // for debug #ifdef MY_CPU_X86_OR_AMD64 - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check #define USE_HW_SHA - #ifndef __SHA__ - #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) - #if defined(_MSC_VER) - // SSSE3: for clang-cl: - #include - #define __SHA__ - #endif - #endif - #pragma clang diagnostic ignored "-Wvector-conversion" - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 8) // fix that check + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) #define USE_HW_SHA - #ifndef __SHA__ + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA__) || !defined(__SSSE3__) #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) - // #pragma GCC target("sha,ssse3") #endif - #endif - #elif defined(__INTEL_COMPILER) - #if (__INTEL_COMPILER >= 1800) // fix that check - #define USE_HW_SHA - #endif + #endif #elif defined(_MSC_VER) - #ifdef USE_MY_MM - #define USE_VER_MIN 1300 - #else - #define USE_VER_MIN 1910 - #endif - #if _MSC_VER >= USE_VER_MIN + #if (_MSC_VER >= 1900) #define USE_HW_SHA + #else + #define Z7_USE_HW_SHA_STUB #endif #endif // #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif #ifdef USE_HW_SHA // #pragma message("Sha1 HW") -// #include -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -#include -#else -#include -#if defined(_MSC_VER) && (_MSC_VER >= 1600) -// #include -#endif -#ifdef USE_MY_MM -#include "My_mm.h" -#endif + +// sse/sse2/ssse3: +#include +// sha*: +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__SHA__) + #include + #endif +#else #endif @@ -87,86 +69,71 @@ _mm_sha1* */ -#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); #define XOR_SI128(dest, src) dest = _mm_xor_si128(dest, src); #define SHUFFLE_EPI8(dest, mask) dest = _mm_shuffle_epi8(dest, mask); #define SHUFFLE_EPI32(dest, mask) dest = _mm_shuffle_epi32(dest, mask); - -#define SHA1_RND4(abcd, e0, f) abcd = _mm_sha1rnds4_epu32(abcd, e0, f); -#define SHA1_NEXTE(e, m) e = _mm_sha1nexte_epu32(e, m); - - - - - -#define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src); -#define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src); - +#ifdef __clang__ +#define SHA1_RNDS4_RET_TYPE_CAST (__m128i) +#else +#define SHA1_RNDS4_RET_TYPE_CAST +#endif +#define SHA1_RND4(abcd, e0, f) abcd = SHA1_RNDS4_RET_TYPE_CAST _mm_sha1rnds4_epu32(abcd, e0, f); +#define SHA1_NEXTE(e, m) e = _mm_sha1nexte_epu32(e, m); +#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); +#define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src); +#define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src); #define LOAD_SHUFFLE(m, k) \ m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \ - SHUFFLE_EPI8(m, mask); \ + SHUFFLE_EPI8(m, mask) \ + +#define NNN(m0, m1, m2, m3) #define SM1(m0, m1, m2, m3) \ - SHA1_MSG1(m0, m1); \ + SHA1_MSG1(m0, m1) \ #define SM2(m0, m1, m2, m3) \ - XOR_SI128(m3, m1); \ - SHA1_MSG2(m3, m2); \ + XOR_SI128(m3, m1) \ + SHA1_MSG2(m3, m2) \ #define SM3(m0, m1, m2, m3) \ - XOR_SI128(m3, m1); \ + XOR_SI128(m3, m1) \ SM1(m0, m1, m2, m3) \ - SHA1_MSG2(m3, m2); \ - -#define NNN(m0, m1, m2, m3) - - - - - - - - - - - - - - + SHA1_MSG2(m3, m2) \ +#define R4(k, m0, m1, m2, m3, e0, e1, OP) \ + e1 = abcd; \ + SHA1_RND4(abcd, e0, (k) / 5) \ + SHA1_NEXTE(e1, m1) \ + OP(m0, m1, m2, m3) \ -#define R4(k, e0, e1, m0, m1, m2, m3, OP) \ - e1 = abcd; \ - SHA1_RND4(abcd, e0, (k) / 5); \ - SHA1_NEXTE(e1, m1); \ - OP(m0, m1, m2, m3); \ #define R16(k, mx, OP0, OP1, OP2, OP3) \ - R4 ( (k)*4+0, e0,e1, m0,m1,m2,m3, OP0 ) \ - R4 ( (k)*4+1, e1,e0, m1,m2,m3,m0, OP1 ) \ - R4 ( (k)*4+2, e0,e1, m2,m3,m0,m1, OP2 ) \ - R4 ( (k)*4+3, e1,e0, m3,mx,m1,m2, OP3 ) \ + R4 ( (k)*4+0, m0,m1,m2,m3, e0,e1, OP0 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, e1,e0, OP1 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, e0,e1, OP2 ) \ + R4 ( (k)*4+3, m3,mx,m1,m2, e1,e0, OP3 ) \ #define PREPARE_STATE \ - SHUFFLE_EPI32 (abcd, 0x1B); \ - SHUFFLE_EPI32 (e0, 0x1B); \ + SHUFFLE_EPI32 (abcd, 0x1B) \ + SHUFFLE_EPI32 (e0, 0x1B) \ -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); #ifdef ATTRIB_SHA ATTRIB_SHA #endif -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) { const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f); - __m128i abcd, e0; + __m128i abcd, e0; + if (numBlocks == 0) return; @@ -190,15 +157,15 @@ LOAD_SHUFFLE (m2, 2) LOAD_SHUFFLE (m3, 3) - ADD_EPI32(e0, m0); + ADD_EPI32(e0, m0) - R16 ( 0, m0, SM1, SM3, SM3, SM3 ); - R16 ( 1, m0, SM3, SM3, SM3, SM3 ); - R16 ( 2, m0, SM3, SM3, SM3, SM3 ); - R16 ( 3, m0, SM3, SM3, SM3, SM3 ); - R16 ( 4, e2, SM2, NNN, NNN, NNN ); + R16 ( 0, m0, SM1, SM3, SM3, SM3 ) + R16 ( 1, m0, SM3, SM3, SM3, SM3 ) + R16 ( 2, m0, SM3, SM3, SM3, SM3 ) + R16 ( 3, m0, SM3, SM3, SM3, SM3 ) + R16 ( 4, e2, SM2, NNN, NNN, NNN ) - ADD_EPI32(abcd, abcd_save); + ADD_EPI32(abcd, abcd_save) data += 64; } @@ -207,78 +174,155 @@ PREPARE_STATE _mm_storeu_si128((__m128i *) (void *) state, abcd); - *(state+4) = (UInt32)_mm_cvtsi128_si32(e0); + *(state + 4) = (UInt32)_mm_cvtsi128_si32(e0); } #endif // USE_HW_SHA -#elif defined(MY_CPU_ARM_OR_ARM64) - - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \ + && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037)) + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_SHA + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) #define USE_HW_SHA #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_SHA #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_SHA #endif #endif #ifdef USE_HW_SHA // #pragma message("=== Sha1 HW === ") +// __ARM_FEATURE_CRYPTO macro is deprecated in favor of the finer grained feature macro __ARM_FEATURE_SHA2 #if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_SHA __attribute__((__target__("crypto"))) +#else #define ATTRIB_SHA __attribute__((__target__("+crypto"))) +#endif #else +#if defined(__clang__) && (__clang_major__ >= 1) + #define ATTRIB_SHA __attribute__((__target__("armv8-a,sha2"))) +#else #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif #endif +#endif #else // _MSC_VER // for arm32 #define _ARM_USE_NEW_NEON_INTRINSICS #endif -#if defined(_MSC_VER) && defined(MY_CPU_ARM64) +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) #include #else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_SHA2 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + #include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_SHA2) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_SHA2 + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") #endif +#endif // Z7_MSC_VER_ORIGINAL + typedef uint32x4_t v128; // typedef __n128 v128; // MSVC +// the bug in clang 3.8.1: +// __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); +#if defined(__clang__) && (__clang_major__ <= 9) +#pragma GCC diagnostic ignored "-Wvector-conversion" +#endif #ifdef MY_CPU_BE - #define MY_rev32_for_LE(x) + #define MY_rev32_for_LE(x) x #else - #define MY_rev32_for_LE(x) x = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(x))) + #define MY_rev32_for_LE(x) vrev32q_u8(x) #endif -#define LOAD_128(_p) (*(const v128 *)(const void *)(_p)) -#define STORE_128(_p, _v) *(v128 *)(void *)(_p) = (_v) +#define LOAD_128_32(_p) vld1q_u32(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_32(_p, _v) vst1q_u32(_p, _v) #define LOAD_SHUFFLE(m, k) \ - m = LOAD_128((data + (k) * 16)); \ - MY_rev32_for_LE(m); \ - -#define SU0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3); -#define SU1(dest, src) dest = vsha1su1q_u32(dest, src); -#define C(e) abcd = vsha1cq_u32(abcd, e, t); -#define P(e) abcd = vsha1pq_u32(abcd, e, t); -#define M(e) abcd = vsha1mq_u32(abcd, e, t); + m = vreinterpretq_u32_u8( \ + MY_rev32_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ + +#define N0(dest, src2, src3) +#define N1(dest, src) +#define U0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3); +#define U1(dest, src) dest = vsha1su1q_u32(dest, src); +#define C(e) abcd = vsha1cq_u32(abcd, e, t) +#define P(e) abcd = vsha1pq_u32(abcd, e, t) +#define M(e) abcd = vsha1mq_u32(abcd, e, t) #define H(e) e = vsha1h_u32(vgetq_lane_u32(abcd, 0)) #define T(m, c) t = vaddq_u32(m, c) -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#define R16(d0,d1,d2,d3, f0,z0, f1,z1, f2,z2, f3,z3, w0,w1,w2,w3) \ + T(m0, d0); f0(m3, m0, m1) z0(m2, m1) H(e1); w0(e0); \ + T(m1, d1); f1(m0, m1, m2) z1(m3, m2) H(e0); w1(e1); \ + T(m2, d2); f2(m1, m2, m3) z2(m0, m3) H(e1); w2(e0); \ + T(m3, d3); f3(m2, m3, m0) z3(m1, m0) H(e0); w3(e1); \ + + +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); #ifdef ATTRIB_SHA ATTRIB_SHA #endif -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) { v128 abcd; v128 c0, c1, c2, c3; @@ -292,7 +336,7 @@ c2 = vdupq_n_u32(0x8f1bbcdc); c3 = vdupq_n_u32(0xca62c1d6); - abcd = LOAD_128(&state[0]); + abcd = LOAD_128_32(&state[0]); e0 = state[4]; do @@ -310,26 +354,11 @@ LOAD_SHUFFLE (m2, 2) LOAD_SHUFFLE (m3, 3) - T(m0, c0); H(e1); C(e0); - T(m1, c0); SU0(m0, m1, m2); H(e0); C(e1); - T(m2, c0); SU0(m1, m2, m3); SU1(m0, m3); H(e1); C(e0); - T(m3, c0); SU0(m2, m3, m0); SU1(m1, m0); H(e0); C(e1); - T(m0, c0); SU0(m3, m0, m1); SU1(m2, m1); H(e1); C(e0); - T(m1, c1); SU0(m0, m1, m2); SU1(m3, m2); H(e0); P(e1); - T(m2, c1); SU0(m1, m2, m3); SU1(m0, m3); H(e1); P(e0); - T(m3, c1); SU0(m2, m3, m0); SU1(m1, m0); H(e0); P(e1); - T(m0, c1); SU0(m3, m0, m1); SU1(m2, m1); H(e1); P(e0); - T(m1, c1); SU0(m0, m1, m2); SU1(m3, m2); H(e0); P(e1); - T(m2, c2); SU0(m1, m2, m3); SU1(m0, m3); H(e1); M(e0); - T(m3, c2); SU0(m2, m3, m0); SU1(m1, m0); H(e0); M(e1); - T(m0, c2); SU0(m3, m0, m1); SU1(m2, m1); H(e1); M(e0); - T(m1, c2); SU0(m0, m1, m2); SU1(m3, m2); H(e0); M(e1); - T(m2, c2); SU0(m1, m2, m3); SU1(m0, m3); H(e1); M(e0); - T(m3, c3); SU0(m2, m3, m0); SU1(m1, m0); H(e0); P(e1); - T(m0, c3); SU0(m3, m0, m1); SU1(m2, m1); H(e1); P(e0); - T(m1, c3); SU1(m3, m2); H(e0); P(e1); - T(m2, c3); H(e1); P(e0); - T(m3, c3); H(e0); P(e1); + R16 ( c0,c0,c0,c0, N0,N1, U0,N1, U0,U1, U0,U1, C,C,C,C ) + R16 ( c0,c1,c1,c1, U0,U1, U0,U1, U0,U1, U0,U1, C,P,P,P ) + R16 ( c1,c1,c2,c2, U0,U1, U0,U1, U0,U1, U0,U1, P,P,M,M ) + R16 ( c2,c2,c2,c3, U0,U1, U0,U1, U0,U1, U0,U1, M,M,M,P ) + R16 ( c3,c3,c3,c3, U0,U1, N0,U1, N0,N1, N0,N1, P,P,P,P ) abcd = vaddq_u32(abcd, abcd_save); e0 += e0_save; @@ -338,7 +367,7 @@ } while (--numBlocks); - STORE_128(&state[0], abcd); + STORE_128_32(&state[0], abcd); state[4] = e0; } @@ -346,19 +375,16 @@ #endif // MY_CPU_ARM_OR_ARM64 - -#ifndef USE_HW_SHA - +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) // #error Stop_Compiling_UNSUPPORTED_SHA // #include - // #include "Sha1.h" -void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); - +// #if defined(_MSC_VER) #pragma message("Sha1 HW-SW stub was used") - -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); -void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) +// #endif +void Z7_FASTCALL Sha1_UpdateBlocks (UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) { Sha1_UpdateBlocks(state, data, numBlocks); /* @@ -369,5 +395,30 @@ return; */ } - #endif + +#undef U0 +#undef U1 +#undef N0 +#undef N1 +#undef C +#undef P +#undef M +#undef H +#undef T +#undef MY_rev32_for_LE +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 +#undef SM3 +#undef NNN +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru 7zip-22.01+dfsg/C/Sha256.c 7zip-22.01+really25.01+dfsg/C/Sha256.c --- 7zip-22.01+dfsg/C/Sha256.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha256.c 2024-10-29 11:00:00.000000000 +0000 @@ -1,64 +1,60 @@ /* Sha256.c -- SHA-256 Hash -2021-04-01 : Igor Pavlov : Public domain +: Igor Pavlov : Public domain This code is based on public domain code from Wei Dai's Crypto++ library. */ #include "Precomp.h" #include -#include "CpuArch.h" -#include "RotateDefs.h" #include "Sha256.h" - -#if defined(_MSC_VER) && (_MSC_VER < 1900) -// #define USE_MY_MM -#endif +#include "RotateDefs.h" +#include "CpuArch.h" #ifdef MY_CPU_X86_OR_AMD64 - #ifdef _MSC_VER - #if _MSC_VER >= 1200 - #define _SHA_SUPPORTED - #endif - #elif defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define _SHA_SUPPORTED - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 8) // fix that check - #define _SHA_SUPPORTED - #endif - #elif defined(__INTEL_COMPILER) - #if (__INTEL_COMPILER >= 1800) // fix that check - #define _SHA_SUPPORTED - #endif + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) \ + || defined(_MSC_VER) && (_MSC_VER >= 1200) + #define Z7_COMPILER_SHA256_SUPPORTED #endif -#elif defined(MY_CPU_ARM_OR_ARM64) - #ifdef _MSC_VER - #if _MSC_VER >= 1910 - #define _SHA_SUPPORTED +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define Z7_COMPILER_SHA256_SUPPORTED + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define Z7_COMPILER_SHA256_SUPPORTED #endif - #elif defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define _SHA_SUPPORTED #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define _SHA_SUPPORTED #endif #endif #endif -void MY_FAST_CALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); -#ifdef _SHA_SUPPORTED - void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef Z7_COMPILER_SHA256_SUPPORTED + void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); - static SHA256_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; - static SHA256_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS_HW; + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW; - #define UPDATE_BLOCKS(p) p->func_UpdateBlocks + #define SHA256_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks #else - #define UPDATE_BLOCKS(p) Sha256_UpdateBlocks + #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks #endif @@ -66,16 +62,16 @@ { SHA256_FUNC_UPDATE_BLOCKS func = Sha256_UpdateBlocks; - #ifdef _SHA_SUPPORTED + #ifdef Z7_COMPILER_SHA256_SUPPORTED if (algo != SHA256_ALGO_SW) { if (algo == SHA256_ALGO_DEFAULT) - func = g_FUNC_UPDATE_BLOCKS; + func = g_SHA256_FUNC_UPDATE_BLOCKS; else { if (algo != SHA256_ALGO_HW) return False; - func = g_FUNC_UPDATE_BLOCKS_HW; + func = g_SHA256_FUNC_UPDATE_BLOCKS_HW; if (!func) return False; } @@ -85,24 +81,25 @@ return False; #endif - p->func_UpdateBlocks = func; + p->v.vars.func_UpdateBlocks = func; return True; } /* define it for speed optimization */ -#ifdef _SFX +#ifdef Z7_SFX #define STEP_PRE 1 #define STEP_MAIN 1 #else #define STEP_PRE 2 #define STEP_MAIN 4 - // #define _SHA256_UNROLL + // #define Z7_SHA256_UNROLL #endif +#undef Z7_SHA256_BIG_W #if STEP_MAIN != 16 - #define _SHA256_BIG_W + #define Z7_SHA256_BIG_W #endif @@ -110,7 +107,7 @@ void Sha256_InitState(CSha256 *p) { - p->count = 0; + p->v.vars.count = 0; p->state[0] = 0x6a09e667; p->state[1] = 0xbb67ae85; p->state[2] = 0x3c6ef372; @@ -121,21 +118,28 @@ p->state[7] = 0x5be0cd19; } + + + + + + + void Sha256_Init(CSha256 *p) { - p->func_UpdateBlocks = - #ifdef _SHA_SUPPORTED - g_FUNC_UPDATE_BLOCKS; + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA256_SUPPORTED + g_SHA256_FUNC_UPDATE_BLOCKS; #else NULL; #endif Sha256_InitState(p); } -#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) -#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x,22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x,25)) #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) -#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >>10)) #define Ch(x,y,z) (z^(x&(y^z))) #define Maj(x,y,z) ((x&y)|(z&(x|y))) @@ -145,7 +149,7 @@ #define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15)) -#ifdef _SHA256_BIG_W +#ifdef Z7_SHA256_BIG_W // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned. #define w(j, i) W[(size_t)(j) + i] #define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i)) @@ -176,7 +180,7 @@ #define R1_PRE(i) T1( W_PRE, i) #define R1_MAIN(i) T1( W_MAIN, i) -#if (!defined(_SHA256_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) +#if (!defined(Z7_SHA256_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) #define R2_MAIN(i) \ R1_MAIN(i) \ R1_MAIN(i + 1) \ @@ -185,7 +189,7 @@ -#if defined(_SHA256_UNROLL) && STEP_MAIN >= 8 +#if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 #define T4( a,b,c,d,e,f,g,h, wx, i) \ h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ @@ -223,14 +227,10 @@ #endif -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); -// static -extern MY_ALIGN(64) -const UInt32 SHA256_K_ARRAY[64]; - -MY_ALIGN(64) -const UInt32 SHA256_K_ARRAY[64] = { +extern +MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64]; +MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, @@ -249,27 +249,29 @@ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; -#define K SHA256_K_ARRAY -MY_NO_INLINE -void MY_FAST_CALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) + + +#define K SHA256_K_ARRAY + +Z7_NO_INLINE +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) { UInt32 W - #ifdef _SHA256_BIG_W +#ifdef Z7_SHA256_BIG_W [64]; - #else +#else [16]; - #endif - +#endif unsigned j; - UInt32 a,b,c,d,e,f,g,h; - - #if !defined(_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) +#if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) UInt32 tmp; - #endif +#endif + if (numBlocks == 0) return; + a = state[0]; b = state[1]; c = state[2]; @@ -279,7 +281,7 @@ g = state[6]; h = state[7]; - while (numBlocks) + do { for (j = 0; j < 16; j += STEP_PRE) @@ -297,12 +299,12 @@ #else - R1_PRE(0); + R1_PRE(0) #if STEP_PRE >= 2 - R1_PRE(1); + R1_PRE(1) #if STEP_PRE >= 4 - R1_PRE(2); - R1_PRE(3); + R1_PRE(2) + R1_PRE(3) #endif #endif @@ -311,32 +313,32 @@ for (j = 16; j < 64; j += STEP_MAIN) { - #if defined(_SHA256_UNROLL) && STEP_MAIN >= 8 + #if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 #if STEP_MAIN < 8 - R4_MAIN(0); + R4_MAIN(0) #else - R8_MAIN(0); + R8_MAIN(0) #if STEP_MAIN == 16 - R8_MAIN(8); + R8_MAIN(8) #endif #endif #else - R1_MAIN(0); + R1_MAIN(0) #if STEP_MAIN >= 2 - R1_MAIN(1); + R1_MAIN(1) #if STEP_MAIN >= 4 - R2_MAIN(2); + R2_MAIN(2) #if STEP_MAIN >= 8 - R2_MAIN(4); - R2_MAIN(6); + R2_MAIN(4) + R2_MAIN(6) #if STEP_MAIN >= 16 - R2_MAIN(8); - R2_MAIN(10); - R2_MAIN(12); - R2_MAIN(14); + R2_MAIN(8) + R2_MAIN(10) + R2_MAIN(12) + R2_MAIN(14) #endif #endif #endif @@ -353,40 +355,27 @@ g += state[6]; state[6] = g; h += state[7]; state[7] = h; - data += 64; - numBlocks--; + data += SHA256_BLOCK_SIZE; } - - /* Wipe variables */ - /* memset(W, 0, sizeof(W)); */ + while (--numBlocks); } -#undef S0 -#undef S1 -#undef s0 -#undef s1 -#undef K -#define Sha256_UpdateBlock(p) UPDATE_BLOCKS(p)(p->state, p->buffer, 1) +#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) void Sha256_Update(CSha256 *p, const Byte *data, size_t size) { if (size == 0) return; - { - unsigned pos = (unsigned)p->count & 0x3F; - unsigned num; - - p->count += size; - - num = 64 - pos; + const unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); + const unsigned num = SHA256_BLOCK_SIZE - pos; + p->v.vars.count += size; if (num > size) { memcpy(p->buffer + pos, data, size); return; } - if (pos != 0) { size -= num; @@ -396,9 +385,10 @@ } } { - size_t numBlocks = size >> 6; - UPDATE_BLOCKS(p)(p->state, data, numBlocks); - size &= 0x3F; + const size_t numBlocks = size >> 6; + // if (numBlocks) + SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA256_BLOCK_SIZE - 1; if (size == 0) return; data += (numBlocks << 6); @@ -409,78 +399,94 @@ void Sha256_Final(CSha256 *p, Byte *digest) { - unsigned pos = (unsigned)p->count & 0x3F; - unsigned i; - + unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); p->buffer[pos++] = 0x80; - - if (pos > (64 - 8)) + if (pos > (SHA256_BLOCK_SIZE - 4 * 2)) { - while (pos != 64) { p->buffer[pos++] = 0; } - // memset(&p->buf.buffer[pos], 0, 64 - pos); + while (pos != SHA256_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA256_BLOCK_SIZE - pos); Sha256_UpdateBlock(p); pos = 0; } - - /* - if (pos & 3) + memset(&p->buffer[pos], 0, (SHA256_BLOCK_SIZE - 4 * 2) - pos); { - p->buffer[pos] = 0; - p->buffer[pos + 1] = 0; - p->buffer[pos + 2] = 0; - pos += 3; - pos &= ~3; + const UInt64 numBits = p->v.vars.count << 3; + SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32)) + SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 1, (UInt32)(numBits)) } + Sha256_UpdateBlock(p); +#if 1 && defined(MY_CPU_BE) + memcpy(digest, p->state, SHA256_DIGEST_SIZE); +#else { - for (; pos < 64 - 8; pos += 4) - *(UInt32 *)(&p->buffer[pos]) = 0; + unsigned i; + for (i = 0; i < 8; i += 2) + { + const UInt32 v0 = p->state[i]; + const UInt32 v1 = p->state[(size_t)i + 1]; + SetBe32(digest , v0) + SetBe32(digest + 4, v1) + digest += 4 * 2; + } } - */ - memset(&p->buffer[pos], 0, (64 - 8) - pos); - { - UInt64 numBits = (p->count << 3); - SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); - SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); - } - - Sha256_UpdateBlock(p); - for (i = 0; i < 8; i += 2) - { - UInt32 v0 = p->state[i]; - UInt32 v1 = p->state[(size_t)i + 1]; - SetBe32(digest , v0); - SetBe32(digest + 4, v1); - digest += 8; - } - + +#endif Sha256_InitState(p); } -void Sha256Prepare() +void Sha256Prepare(void) { - #ifdef _SHA_SUPPORTED +#ifdef Z7_COMPILER_SHA256_SUPPORTED SHA256_FUNC_UPDATE_BLOCKS f, f_hw; f = Sha256_UpdateBlocks; f_hw = NULL; - #ifdef MY_CPU_X86_OR_AMD64 - #ifndef USE_MY_MM +#ifdef MY_CPU_X86_OR_AMD64 if (CPU_IsSupported_SHA() && CPU_IsSupported_SSSE3() - // && CPU_IsSupported_SSE41() ) - #endif - #else +#else if (CPU_IsSupported_SHA2()) - #endif +#endif { // printf("\n========== HW SHA256 ======== \n"); f = f_hw = Sha256_UpdateBlocks_HW; } - g_FUNC_UPDATE_BLOCKS = f; - g_FUNC_UPDATE_BLOCKS_HW = f_hw; - #endif + g_SHA256_FUNC_UPDATE_BLOCKS = f; + g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw; +#endif } + +#undef U64C +#undef K +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef Ch +#undef Maj +#undef W_MAIN +#undef W_PRE +#undef w +#undef blk2_main +#undef blk2 +#undef T1 +#undef T4 +#undef T8 +#undef R1_PRE +#undef R1_MAIN +#undef R2_MAIN +#undef R4 +#undef R4_PRE +#undef R4_MAIN +#undef R8 +#undef R8_PRE +#undef R8_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA256_BIG_W +#undef Z7_SHA256_UNROLL +#undef Z7_COMPILER_SHA256_SUPPORTED diff -Nru 7zip-22.01+dfsg/C/Sha256.h 7zip-22.01+really25.01+dfsg/C/Sha256.h --- 7zip-22.01+dfsg/C/Sha256.h 2021-01-01 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha256.h 2024-10-29 18:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* Sha256.h -- SHA-256 Hash -2021-01-01 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __7Z_SHA256_H -#define __7Z_SHA256_H +#ifndef ZIP7_INC_SHA256_H +#define ZIP7_INC_SHA256_H #include "7zTypes.h" @@ -14,7 +14,10 @@ #define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4) #define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4) -typedef void (MY_FAST_CALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks); + + + +typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks); /* if (the system supports different SHA256 code implementations) @@ -32,9 +35,16 @@ typedef struct { - SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks; - UInt64 count; - UInt64 __pad_2[2]; + union + { + struct + { + SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[4]; + void *_pad_align_ptr[2]; + } v; UInt32 state[SHA256_NUM_DIGEST_WORDS]; Byte buffer[SHA256_BLOCK_SIZE]; @@ -62,7 +72,7 @@ -// void MY_FAST_CALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); +// void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); /* call Sha256Prepare() once at program start. diff -Nru 7zip-22.01+dfsg/C/Sha256Opt.c 7zip-22.01+really25.01+dfsg/C/Sha256Opt.c --- 7zip-22.01+dfsg/C/Sha256Opt.c 2021-04-01 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha256Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -1,71 +1,53 @@ /* Sha256Opt.c -- SHA-256 optimized code for SHA-256 hardware instructions -2021-04-01 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" - -#if defined(_MSC_VER) -#if (_MSC_VER < 1900) && (_MSC_VER >= 1200) -// #define USE_MY_MM -#endif -#endif - +#include "Compiler.h" #include "CpuArch.h" +// #define Z7_USE_HW_SHA_STUB // for debug #ifdef MY_CPU_X86_OR_AMD64 - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check #define USE_HW_SHA - #ifndef __SHA__ - #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) - #if defined(_MSC_VER) - // SSSE3: for clang-cl: - #include - #define __SHA__ - #endif - #endif - - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 8) // fix that check + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) #define USE_HW_SHA - #ifndef __SHA__ + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA__) || !defined(__SSSE3__) #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) - // #pragma GCC target("sha,ssse3") #endif - #endif - #elif defined(__INTEL_COMPILER) - #if (__INTEL_COMPILER >= 1800) // fix that check - #define USE_HW_SHA - #endif + #endif #elif defined(_MSC_VER) - #ifdef USE_MY_MM - #define USE_VER_MIN 1300 - #else - #define USE_VER_MIN 1910 - #endif - #if _MSC_VER >= USE_VER_MIN + #if (_MSC_VER >= 1900) #define USE_HW_SHA + #else + #define Z7_USE_HW_SHA_STUB #endif #endif // #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif #ifdef USE_HW_SHA // #pragma message("Sha256 HW") -// #include -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -#include -#else -#include -#if defined(_MSC_VER) && (_MSC_VER >= 1600) -// #include -#endif -#ifdef USE_MY_MM -#include "My_mm.h" -#endif + +// sse/sse2/ssse3: +#include +// sha*: +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__SHA__) + #include + #endif +#else #endif @@ -94,60 +76,44 @@ extern MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64]; - #define K SHA256_K_ARRAY -#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); -#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src); -#define SHA25G_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src); - +#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); +#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src); +#define SHA256_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src); #define LOAD_SHUFFLE(m, k) \ m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \ m = _mm_shuffle_epi8(m, mask); \ -#define SM1(g0, g1, g2, g3) \ - SHA256_MSG1(g3, g0); \ - -#define SM2(g0, g1, g2, g3) \ - tmp = _mm_alignr_epi8(g1, g0, 4); \ - ADD_EPI32(g2, tmp); \ - SHA25G_MSG2(g2, g1); \ - -// #define LS0(k, g0, g1, g2, g3) LOAD_SHUFFLE(g0, k) -// #define LS1(k, g0, g1, g2, g3) LOAD_SHUFFLE(g1, k+1) +#define NNN(m0, m1, m2, m3) +#define SM1(m1, m2, m3, m0) \ + SHA256_MSG1(m0, m1); \ -#define NNN(g0, g1, g2, g3) - +#define SM2(m2, m3, m0, m1) \ + ADD_EPI32(m0, _mm_alignr_epi8(m3, m2, 4)) \ + SHA256_MSG2(m0, m3); \ #define RND2(t0, t1) \ t0 = _mm_sha256rnds2_epu32(t0, t1, msg); -#define RND2_0(m, k) \ - msg = _mm_add_epi32(m, *(const __m128i *) (const void *) &K[(k) * 4]); \ - RND2(state0, state1); \ - msg = _mm_shuffle_epi32(msg, 0x0E); \ -#define RND2_1 \ +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = _mm_add_epi32(m0, *(const __m128i *) (const void *) &K[(k) * 4]); \ + RND2(state0, state1); \ + msg = _mm_shuffle_epi32(msg, 0x0E); \ + OP0(m0, m1, m2, m3) \ RND2(state1, state0); \ - - -// We use scheme with 3 rounds ahead for SHA256_MSG1 / 2 rounds ahead for SHA256_MSG2 - -#define R4(k, g0, g1, g2, g3, OP0, OP1) \ - RND2_0(g0, k); \ - OP0(g0, g1, g2, g3); \ - RND2_1; \ - OP1(g0, g1, g2, g3); \ + OP1(m0, m1, m2, m3) \ #define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ - R4 ( (k)*4+0, m0, m1, m2, m3, OP0, OP1 ) \ - R4 ( (k)*4+1, m1, m2, m3, m0, OP2, OP3 ) \ - R4 ( (k)*4+2, m2, m3, m0, m1, OP4, OP5 ) \ - R4 ( (k)*4+3, m3, m0, m1, m2, OP6, OP7 ) \ + R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \ #define PREPARE_STATE \ tmp = _mm_shuffle_epi32(state0, 0x1B); /* abcd */ \ @@ -157,15 +123,16 @@ state1 = _mm_unpackhi_epi64(state1, tmp); /* abef */ \ -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); #ifdef ATTRIB_SHA ATTRIB_SHA #endif -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) { const __m128i mask = _mm_set_epi32(0x0c0d0e0f, 0x08090a0b, 0x04050607, 0x00010203); - __m128i tmp; - __m128i state0, state1; + + + __m128i tmp, state0, state1; if (numBlocks == 0) return; @@ -192,13 +159,13 @@ - R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ); - R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); - R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); - R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ); + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) - ADD_EPI32(state0, state0_save); - ADD_EPI32(state1, state1_save); + ADD_EPI32(state0, state0_save) + ADD_EPI32(state1, state1_save) data += 64; } @@ -212,19 +179,28 @@ #endif // USE_HW_SHA -#elif defined(MY_CPU_ARM_OR_ARM64) - - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_SHA + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) #define USE_HW_SHA #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_SHA #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_SHA #endif #endif @@ -232,63 +208,144 @@ // #pragma message("=== Sha256 HW === ") + #if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_SHA __attribute__((__target__("crypto"))) +#else #define ATTRIB_SHA __attribute__((__target__("+crypto"))) +#endif #else +#if defined(__clang__) && (__clang_major__ >= 1) + #define ATTRIB_SHA __attribute__((__target__("armv8-a,sha2"))) +#else #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif #endif +#endif #else // _MSC_VER // for arm32 #define _ARM_USE_NEW_NEON_INTRINSICS #endif -#if defined(_MSC_VER) && defined(MY_CPU_ARM64) +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) #include #else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_SHA2 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + #include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_SHA2) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_SHA2 + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") #endif +#endif // Z7_MSC_VER_ORIGINAL + typedef uint32x4_t v128; // typedef __n128 v128; // MSVC #ifdef MY_CPU_BE - #define MY_rev32_for_LE(x) + #define MY_rev32_for_LE(x) x #else - #define MY_rev32_for_LE(x) x = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(x))) + #define MY_rev32_for_LE(x) vrev32q_u8(x) #endif -#define LOAD_128(_p) (*(const v128 *)(const void *)(_p)) -#define STORE_128(_p, _v) *(v128 *)(void *)(_p) = (_v) +#if 1 // 0 for debug +// for arm32: it works slower by some reason than direct code +/* +for arm32 it generates: +MSVC-2022, GCC-9: + vld1.32 {d18,d19}, [r10] + vst1.32 {d4,d5}, [r3] + vld1.8 {d20-d21}, [r4] +there is no align hint (like [r10:128]). So instruction allows unaligned access +*/ +#define LOAD_128_32(_p) vld1q_u32(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_32(_p, _v) vst1q_u32(_p, _v) +#else +/* +for arm32: +MSVC-2022: + vldm r10,{d18,d19} + vstm r3,{d4,d5} + does it require strict alignment? +GCC-9: + vld1.64 {d30-d31}, [r0:64] + vldr d28, [r0, #16] + vldr d29, [r0, #24] + vst1.64 {d30-d31}, [r0:64] + vstr d28, [r0, #16] + vstr d29, [r0, #24] +there is hint [r0:64], so does it requires 64-bit alignment. +*/ +#define LOAD_128_32(_p) (*(const v128 *)(const void *)(_p)) +#define LOAD_128_8(_p) vreinterpretq_u8_u32(*(const v128 *)(const void *)(_p)) +#define STORE_128_32(_p, _v) *(v128 *)(void *)(_p) = (_v) +#endif #define LOAD_SHUFFLE(m, k) \ - m = LOAD_128((data + (k) * 16)); \ - MY_rev32_for_LE(m); \ + m = vreinterpretq_u32_u8( \ + MY_rev32_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ // K array must be aligned for 16-bytes at least. extern MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64]; - #define K SHA256_K_ARRAY - #define SHA256_SU0(dest, src) dest = vsha256su0q_u32(dest, src); -#define SHA25G_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3); +#define SHA256_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3); -#define SM1(g0, g1, g2, g3) SHA256_SU0(g3, g0) -#define SM2(g0, g1, g2, g3) SHA25G_SU1(g2, g0, g1) -#define NNN(g0, g1, g2, g3) +#define SM1(m0, m1, m2, m3) SHA256_SU0(m3, m0) +#define SM2(m0, m1, m2, m3) SHA256_SU1(m2, m0, m1) +#define NNN(m0, m1, m2, m3) - -#define R4(k, g0, g1, g2, g3, OP0, OP1) \ - msg = vaddq_u32(g0, *(const v128 *) (const void *) &K[(k) * 4]); \ +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = vaddq_u32(m0, *(const v128 *) (const void *) &K[(k) * 4]); \ tmp = state0; \ state0 = vsha256hq_u32( state0, state1, msg ); \ state1 = vsha256h2q_u32( state1, tmp, msg ); \ - OP0(g0, g1, g2, g3); \ - OP1(g0, g1, g2, g3); \ + OP0(m0, m1, m2, m3); \ + OP1(m0, m1, m2, m3); \ #define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ @@ -298,19 +355,19 @@ R4 ( (k)*4+3, m3, m0, m1, m2, OP6, OP7 ) \ -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); #ifdef ATTRIB_SHA ATTRIB_SHA #endif -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) { v128 state0, state1; if (numBlocks == 0) return; - state0 = LOAD_128(&state[0]); - state1 = LOAD_128(&state[4]); + state0 = LOAD_128_32(&state[0]); + state1 = LOAD_128_32(&state[4]); do { @@ -326,10 +383,10 @@ LOAD_SHUFFLE (m2, 2) LOAD_SHUFFLE (m3, 3) - R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ); - R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); - R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); - R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ); + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) state0 = vaddq_u32(state0, state0_save); state1 = vaddq_u32(state1, state1_save); @@ -338,8 +395,8 @@ } while (--numBlocks); - STORE_128(&state[0], state0); - STORE_128(&state[4], state1); + STORE_128_32(&state[0], state0); + STORE_128_32(&state[4], state1); } #endif // USE_HW_SHA @@ -347,18 +404,19 @@ #endif // MY_CPU_ARM_OR_ARM64 -#ifndef USE_HW_SHA - +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) // #error Stop_Compiling_UNSUPPORTED_SHA // #include - +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. // #include "Sha256.h" -void MY_FAST_CALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); - +// #if defined(_MSC_VER) #pragma message("Sha256 HW-SW stub was used") - -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); -void MY_FAST_CALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +// #endif +void Z7_FASTCALL Sha256_UpdateBlocks (UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) { Sha256_UpdateBlocks(state, data, numBlocks); /* @@ -369,5 +427,25 @@ return; */ } - #endif + + +#undef K +#undef RND2 +#undef MY_rev32_for_LE + +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 + + +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru 7zip-22.01+dfsg/C/Sha3.c 7zip-22.01+really25.01+dfsg/C/Sha3.c --- 7zip-22.01+dfsg/C/Sha3.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha3.c 2024-11-26 10:00:00.000000000 +0000 @@ -0,0 +1,359 @@ +/* Sha3.c -- SHA-3 Hash +: Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha3.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#define U64C(x) UINT64_CONST(x) + +static +MY_ALIGN(64) +const UInt64 SHA3_K_ARRAY[24] = +{ + U64C(0x0000000000000001), U64C(0x0000000000008082), + U64C(0x800000000000808a), U64C(0x8000000080008000), + U64C(0x000000000000808b), U64C(0x0000000080000001), + U64C(0x8000000080008081), U64C(0x8000000000008009), + U64C(0x000000000000008a), U64C(0x0000000000000088), + U64C(0x0000000080008009), U64C(0x000000008000000a), + U64C(0x000000008000808b), U64C(0x800000000000008b), + U64C(0x8000000000008089), U64C(0x8000000000008003), + U64C(0x8000000000008002), U64C(0x8000000000000080), + U64C(0x000000000000800a), U64C(0x800000008000000a), + U64C(0x8000000080008081), U64C(0x8000000000008080), + U64C(0x0000000080000001), U64C(0x8000000080008008) +}; + +void Sha3_Init(CSha3 *p) +{ + p->count = 0; + memset(p->state, 0, sizeof(p->state)); +} + +#define GET_state(i, a) UInt64 a = state[i]; +#define SET_state(i, a) state[i] = a; + +#define LS_5(M, i, a0,a1,a2,a3,a4) \ + M ((i) * 5 , a0) \ + M ((i) * 5 + 1, a1) \ + M ((i) * 5 + 2, a2) \ + M ((i) * 5 + 3, a3) \ + M ((i) * 5 + 4, a4) \ + +#define LS_25(M) \ + LS_5 (M, 0, a50, a51, a52, a53, a54) \ + LS_5 (M, 1, a60, a61, a62, a63, a64) \ + LS_5 (M, 2, a70, a71, a72, a73, a74) \ + LS_5 (M, 3, a80, a81, a82, a83, a84) \ + LS_5 (M, 4, a90, a91, a92, a93, a94) \ + + +#define XOR_1(i, a0) \ + a0 ^= GetUi64(data + (i) * 8); \ + +#define XOR_4(i, a0,a1,a2,a3) \ + XOR_1 ((i) , a0); \ + XOR_1 ((i) + 1, a1); \ + XOR_1 ((i) + 2, a2); \ + XOR_1 ((i) + 3, a3); \ + +#define D(d,b1,b2) \ + d = b1 ^ Z7_ROTL64(b2, 1); + +#define D5 \ + D (d0, c4, c1) \ + D (d1, c0, c2) \ + D (d2, c1, c3) \ + D (d3, c2, c4) \ + D (d4, c3, c0) \ + +#define C0(c,a,d) \ + c = a ^ d; \ + +#define C(c,a,d,k) \ + c = a ^ d; \ + c = Z7_ROTL64(c, k); \ + +#define E4(e1,e2,e3,e4) \ + e1 = c1 ^ (~c2 & c3); \ + e2 = c2 ^ (~c3 & c4); \ + e3 = c3 ^ (~c4 & c0); \ + e4 = c4 ^ (~c0 & c1); \ + +#define CK( v0,w0, \ + v1,w1,k1, \ + v2,w2,k2, \ + v3,w3,k3, \ + v4,w4,k4, e0,e1,e2,e3,e4, keccak_c) \ + C0(c0,v0,w0) \ + C (c1,v1,w1,k1) \ + C (c2,v2,w2,k2) \ + C (c3,v3,w3,k3) \ + C (c4,v4,w4,k4) \ + e0 = c0 ^ (~c1 & c2) ^ keccak_c; \ + E4(e1,e2,e3,e4) \ + +#define CE( v0,w0,k0, \ + v1,w1,k1, \ + v2,w2,k2, \ + v3,w3,k3, \ + v4,w4,k4, e0,e1,e2,e3,e4) \ + C (c0,v0,w0,k0) \ + C (c1,v1,w1,k1) \ + C (c2,v2,w2,k2) \ + C (c3,v3,w3,k3) \ + C (c4,v4,w4,k4) \ + e0 = c0 ^ (~c1 & c2); \ + E4(e1,e2,e3,e4) \ + +// numBlocks != 0 +static +Z7_NO_INLINE +void Z7_FASTCALL Sha3_UpdateBlocks(UInt64 state[SHA3_NUM_STATE_WORDS], + const Byte *data, size_t numBlocks, size_t blockSize) +{ + LS_25 (GET_state) + + do + { + unsigned round; + XOR_4 ( 0, a50, a51, a52, a53) + XOR_4 ( 4, a54, a60, a61, a62) + XOR_1 ( 8, a63) + if (blockSize > 8 * 9) { XOR_4 ( 9, a64, a70, a71, a72) // sha3-384 + if (blockSize > 8 * 13) { XOR_4 (13, a73, a74, a80, a81) // sha3-256 + if (blockSize > 8 * 17) { XOR_1 (17, a82) // sha3-224 + if (blockSize > 8 * 18) { XOR_1 (18, a83) // shake128 + XOR_1 (19, a84) + XOR_1 (20, a90) }}}} + data += blockSize; + + for (round = 0; round < 24; round += 2) + { + UInt64 c0, c1, c2, c3, c4; + UInt64 d0, d1, d2, d3, d4; + UInt64 e50, e51, e52, e53, e54; + UInt64 e60, e61, e62, e63, e64; + UInt64 e70, e71, e72, e73, e74; + UInt64 e80, e81, e82, e83, e84; + UInt64 e90, e91, e92, e93, e94; + + c0 = a50^a60^a70^a80^a90; + c1 = a51^a61^a71^a81^a91; + c2 = a52^a62^a72^a82^a92; + c3 = a53^a63^a73^a83^a93; + c4 = a54^a64^a74^a84^a94; + D5 + CK( a50, d0, + a61, d1, 44, + a72, d2, 43, + a83, d3, 21, + a94, d4, 14, e50, e51, e52, e53, e54, SHA3_K_ARRAY[round]) + CE( a53, d3, 28, + a64, d4, 20, + a70, d0, 3, + a81, d1, 45, + a92, d2, 61, e60, e61, e62, e63, e64) + CE( a51, d1, 1, + a62, d2, 6, + a73, d3, 25, + a84, d4, 8, + a90, d0, 18, e70, e71, e72, e73, e74) + CE( a54, d4, 27, + a60, d0, 36, + a71, d1, 10, + a82, d2, 15, + a93, d3, 56, e80, e81, e82, e83, e84) + CE( a52, d2, 62, + a63, d3, 55, + a74, d4, 39, + a80, d0, 41, + a91, d1, 2, e90, e91, e92, e93, e94) + + // ---------- ROUND + 1 ---------- + + c0 = e50^e60^e70^e80^e90; + c1 = e51^e61^e71^e81^e91; + c2 = e52^e62^e72^e82^e92; + c3 = e53^e63^e73^e83^e93; + c4 = e54^e64^e74^e84^e94; + D5 + CK( e50, d0, + e61, d1, 44, + e72, d2, 43, + e83, d3, 21, + e94, d4, 14, a50, a51, a52, a53, a54, SHA3_K_ARRAY[(size_t)round + 1]) + CE( e53, d3, 28, + e64, d4, 20, + e70, d0, 3, + e81, d1, 45, + e92, d2, 61, a60, a61, a62, a63, a64) + CE( e51, d1, 1, + e62, d2, 6, + e73, d3, 25, + e84, d4, 8, + e90, d0, 18, a70, a71, a72, a73, a74) + CE (e54, d4, 27, + e60, d0, 36, + e71, d1, 10, + e82, d2, 15, + e93, d3, 56, a80, a81, a82, a83, a84) + CE (e52, d2, 62, + e63, d3, 55, + e74, d4, 39, + e80, d0, 41, + e91, d1, 2, a90, a91, a92, a93, a94) + } + } + while (--numBlocks); + + LS_25 (SET_state) +} + + +#define Sha3_UpdateBlock(p) \ + Sha3_UpdateBlocks(p->state, p->buffer, 1, p->blockSize) + +void Sha3_Update(CSha3 *p, const Byte *data, size_t size) +{ +/* + for (;;) + { + if (size == 0) + return; + unsigned cur = p->blockSize - p->count; + if (cur > size) + cur = (unsigned)size; + size -= cur; + unsigned pos = p->count; + p->count = pos + cur; + while (pos & 7) + { + if (cur == 0) + return; + Byte *pb = &(((Byte *)p->state)[pos]); + *pb = (Byte)(*pb ^ *data++); + cur--; + pos++; + } + if (cur >= 8) + { + do + { + *(UInt64 *)(void *)&(((Byte *)p->state)[pos]) ^= GetUi64(data); + data += 8; + pos += 8; + cur -= 8; + } + while (cur >= 8); + } + if (pos != p->blockSize) + { + if (cur) + { + Byte *pb = &(((Byte *)p->state)[pos]); + do + { + *pb = (Byte)(*pb ^ *data++); + pb++; + } + while (--cur); + } + return; + } + Sha3_UpdateBlock(p->state); + p->count = 0; + } +*/ + if (size == 0) + return; + { + const unsigned pos = p->count; + const unsigned num = p->blockSize - pos; + if (num > size) + { + p->count = pos + (unsigned)size; + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha3_UpdateBlock(p); + } + } + if (size >= p->blockSize) + { + const size_t numBlocks = size / p->blockSize; + const Byte *dataOld = data; + data += numBlocks * p->blockSize; + size = (size_t)(dataOld + size - data); + Sha3_UpdateBlocks(p->state, dataOld, numBlocks, p->blockSize); + } + p->count = (unsigned)size; + if (size) + memcpy(p->buffer, data, size); +} + + +// we support only (digestSize % 4 == 0) cases +void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake) +{ + memset(p->buffer + p->count, 0, p->blockSize - p->count); + // we write bits markers from low to higher in current byte: + // - if sha-3 : 2 bits : 0,1 + // - if shake : 4 bits : 1111 + // then we write bit 1 to same byte. + // And we write bit 1 to highest bit of last byte of block. + p->buffer[p->count] = (Byte)(shake ? 0x1f : 0x06); + // we need xor operation (^= 0x80) here because we must write 0x80 bit + // to same byte as (0x1f : 0x06), if (p->count == p->blockSize - 1) !!! + p->buffer[p->blockSize - 1] ^= 0x80; +/* + ((Byte *)p->state)[p->count] ^= (Byte)(shake ? 0x1f : 0x06); + ((Byte *)p->state)[p->blockSize - 1] ^= 0x80; +*/ + Sha3_UpdateBlock(p); +#if 1 && defined(MY_CPU_LE) + memcpy(digest, p->state, digestSize); +#else + { + const unsigned numWords = digestSize >> 3; + unsigned i; + for (i = 0; i < numWords; i++) + { + const UInt64 v = p->state[i]; + SetUi64(digest, v) + digest += 8; + } + if (digestSize & 4) // for SHA3-224 + { + const UInt32 v = (UInt32)p->state[numWords]; + SetUi32(digest, v) + } + } +#endif + Sha3_Init(p); +} + +#undef GET_state +#undef SET_state +#undef LS_5 +#undef LS_25 +#undef XOR_1 +#undef XOR_4 +#undef D +#undef D5 +#undef C0 +#undef C +#undef E4 +#undef CK +#undef CE diff -Nru 7zip-22.01+dfsg/C/Sha3.h 7zip-22.01+really25.01+dfsg/C/Sha3.h --- 7zip-22.01+dfsg/C/Sha3.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha3.h 2024-11-26 10:00:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* Sha3.h -- SHA-3 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MD5_H +#define ZIP7_INC_MD5_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA3_NUM_STATE_WORDS 25 + +#define SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize) \ + (SHA3_NUM_STATE_WORDS * 8 - (digestSize) * 2) + +typedef struct +{ + UInt32 count; // < blockSize + UInt32 blockSize; // <= SHA3_NUM_STATE_WORDS * 8 + UInt64 _pad1[3]; + // we want 32-bytes alignment here + UInt64 state[SHA3_NUM_STATE_WORDS]; + UInt64 _pad2[3]; + // we want 64-bytes alignment here + Byte buffer[SHA3_NUM_STATE_WORDS * 8]; // last bytes will be unused with predefined blockSize values +} CSha3; + +#define Sha3_SET_blockSize(p, blockSize) { (p)->blockSize = (blockSize); } + +void Sha3_Init(CSha3 *p); +void Sha3_Update(CSha3 *p, const Byte *data, size_t size); +void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake); + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/Sha512.c 7zip-22.01+really25.01+dfsg/C/Sha512.c --- 7zip-22.01+dfsg/C/Sha512.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha512.c 2024-12-03 11:00:00.000000000 +0000 @@ -0,0 +1,711 @@ +/* Sha512.c -- SHA-512 Hash +: Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha512.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) \ + || defined(_MSC_VER) && (_MSC_VER >= 1940) + #define Z7_COMPILER_SHA512_SUPPORTED + #endif +#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE) + #if defined(__ARM_FEATURE_SHA512) + #define Z7_COMPILER_SHA512_SUPPORTED + #else + #if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it + #define Z7_COMPILER_SHA512_SUPPORTED + #endif + #endif +#endif + + + + + + + + + + + + + + +void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks); + +#ifdef Z7_COMPILER_SHA512_SUPPORTED + void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); + + static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS = Sha512_UpdateBlocks; + static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS_HW; + + #define SHA512_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks +#else + #define SHA512_UPDATE_BLOCKS(p) Sha512_UpdateBlocks +#endif + + +BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo) +{ + SHA512_FUNC_UPDATE_BLOCKS func = Sha512_UpdateBlocks; + + #ifdef Z7_COMPILER_SHA512_SUPPORTED + if (algo != SHA512_ALGO_SW) + { + if (algo == SHA512_ALGO_DEFAULT) + func = g_SHA512_FUNC_UPDATE_BLOCKS; + else + { + if (algo != SHA512_ALGO_HW) + return False; + func = g_SHA512_FUNC_UPDATE_BLOCKS_HW; + if (!func) + return False; + } + } + #else + if (algo > 1) + return False; + #endif + + p->v.vars.func_UpdateBlocks = func; + return True; +} + + +/* define it for speed optimization */ + +#if 0 // 1 for size optimization + #define STEP_PRE 1 + #define STEP_MAIN 1 +#else + #define STEP_PRE 2 + #define STEP_MAIN 4 + // #define Z7_SHA512_UNROLL +#endif + +#undef Z7_SHA512_BIG_W +#if STEP_MAIN != 16 + #define Z7_SHA512_BIG_W +#endif + + +#define U64C(x) UINT64_CONST(x) + +static MY_ALIGN(64) const UInt64 SHA512_INIT_ARRAYS[4][8] = { +{ U64C(0x8c3d37c819544da2), U64C(0x73e1996689dcd4d6), U64C(0x1dfab7ae32ff9c82), U64C(0x679dd514582f9fcf), + U64C(0x0f6d2b697bd44da8), U64C(0x77e36f7304c48942), U64C(0x3f9d85a86a1d36c8), U64C(0x1112e6ad91d692a1) +}, +{ U64C(0x22312194fc2bf72c), U64C(0x9f555fa3c84c64c2), U64C(0x2393b86b6f53b151), U64C(0x963877195940eabd), + U64C(0x96283ee2a88effe3), U64C(0xbe5e1e2553863992), U64C(0x2b0199fc2c85b8aa), U64C(0x0eb72ddc81c52ca2) +}, +{ U64C(0xcbbb9d5dc1059ed8), U64C(0x629a292a367cd507), U64C(0x9159015a3070dd17), U64C(0x152fecd8f70e5939), + U64C(0x67332667ffc00b31), U64C(0x8eb44a8768581511), U64C(0xdb0c2e0d64f98fa7), U64C(0x47b5481dbefa4fa4) +}, +{ U64C(0x6a09e667f3bcc908), U64C(0xbb67ae8584caa73b), U64C(0x3c6ef372fe94f82b), U64C(0xa54ff53a5f1d36f1), + U64C(0x510e527fade682d1), U64C(0x9b05688c2b3e6c1f), U64C(0x1f83d9abfb41bd6b), U64C(0x5be0cd19137e2179) +}}; + +void Sha512_InitState(CSha512 *p, unsigned digestSize) +{ + p->v.vars.count = 0; + memcpy(p->state, SHA512_INIT_ARRAYS[(size_t)(digestSize >> 4) - 1], sizeof(p->state)); +} + +void Sha512_Init(CSha512 *p, unsigned digestSize) +{ + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA512_SUPPORTED + g_SHA512_FUNC_UPDATE_BLOCKS; + #else + NULL; + #endif + Sha512_InitState(p, digestSize); +} + +#define S0(x) (Z7_ROTR64(x,28) ^ Z7_ROTR64(x,34) ^ Z7_ROTR64(x,39)) +#define S1(x) (Z7_ROTR64(x,14) ^ Z7_ROTR64(x,18) ^ Z7_ROTR64(x,41)) +#define s0(x) (Z7_ROTR64(x, 1) ^ Z7_ROTR64(x, 8) ^ (x >> 7)) +#define s1(x) (Z7_ROTR64(x,19) ^ Z7_ROTR64(x,61) ^ (x >> 6)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + + +#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe64(data + ((size_t)(j) + i) * 8)) + +#define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15)) + +#ifdef Z7_SHA512_BIG_W + // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned. + #define w(j, i) W[(size_t)(j) + i] + #define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i)) +#else + #if STEP_MAIN == 16 + #define w(j, i) W[(i) & 15] + #else + #define w(j, i) W[((size_t)(j) + (i)) & 15] + #endif + #define blk2(j, i) (w(j, i) += blk2_main(j, i)) +#endif + +#define W_MAIN(i) blk2(j, i) + + +#define T1(wx, i) \ + tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + h = g; \ + g = f; \ + f = e; \ + e = d + tmp; \ + tmp += S0(a) + Maj(a, b, c); \ + d = c; \ + c = b; \ + b = a; \ + a = tmp; \ + +#define R1_PRE(i) T1( W_PRE, i) +#define R1_MAIN(i) T1( W_MAIN, i) + +#if (!defined(Z7_SHA512_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) +#define R2_MAIN(i) \ + R1_MAIN(i) \ + R1_MAIN(i + 1) \ + +#endif + + + +#if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8 + +#define T4( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + tmp = h; \ + h += d; \ + d = tmp + S0(a) + Maj(a, b, c); \ + +#define R4( wx, i) \ + T4 ( a,b,c,d,e,f,g,h, wx, (i )); \ + T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \ + T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \ + T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \ + +#define R4_PRE(i) R4( W_PRE, i) +#define R4_MAIN(i) R4( W_MAIN, i) + + +#define T8( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + d += h; \ + h += S0(a) + Maj(a, b, c); \ + +#define R8( wx, i) \ + T8 ( a,b,c,d,e,f,g,h, wx, i ); \ + T8 ( h,a,b,c,d,e,f,g, wx, i+1); \ + T8 ( g,h,a,b,c,d,e,f, wx, i+2); \ + T8 ( f,g,h,a,b,c,d,e, wx, i+3); \ + T8 ( e,f,g,h,a,b,c,d, wx, i+4); \ + T8 ( d,e,f,g,h,a,b,c, wx, i+5); \ + T8 ( c,d,e,f,g,h,a,b, wx, i+6); \ + T8 ( b,c,d,e,f,g,h,a, wx, i+7); \ + +#define R8_PRE(i) R8( W_PRE, i) +#define R8_MAIN(i) R8( W_MAIN, i) + +#endif + + +extern +MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80]; +MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80] = { + U64C(0x428a2f98d728ae22), U64C(0x7137449123ef65cd), U64C(0xb5c0fbcfec4d3b2f), U64C(0xe9b5dba58189dbbc), + U64C(0x3956c25bf348b538), U64C(0x59f111f1b605d019), U64C(0x923f82a4af194f9b), U64C(0xab1c5ed5da6d8118), + U64C(0xd807aa98a3030242), U64C(0x12835b0145706fbe), U64C(0x243185be4ee4b28c), U64C(0x550c7dc3d5ffb4e2), + U64C(0x72be5d74f27b896f), U64C(0x80deb1fe3b1696b1), U64C(0x9bdc06a725c71235), U64C(0xc19bf174cf692694), + U64C(0xe49b69c19ef14ad2), U64C(0xefbe4786384f25e3), U64C(0x0fc19dc68b8cd5b5), U64C(0x240ca1cc77ac9c65), + U64C(0x2de92c6f592b0275), U64C(0x4a7484aa6ea6e483), U64C(0x5cb0a9dcbd41fbd4), U64C(0x76f988da831153b5), + U64C(0x983e5152ee66dfab), U64C(0xa831c66d2db43210), U64C(0xb00327c898fb213f), U64C(0xbf597fc7beef0ee4), + U64C(0xc6e00bf33da88fc2), U64C(0xd5a79147930aa725), U64C(0x06ca6351e003826f), U64C(0x142929670a0e6e70), + U64C(0x27b70a8546d22ffc), U64C(0x2e1b21385c26c926), U64C(0x4d2c6dfc5ac42aed), U64C(0x53380d139d95b3df), + U64C(0x650a73548baf63de), U64C(0x766a0abb3c77b2a8), U64C(0x81c2c92e47edaee6), U64C(0x92722c851482353b), + U64C(0xa2bfe8a14cf10364), U64C(0xa81a664bbc423001), U64C(0xc24b8b70d0f89791), U64C(0xc76c51a30654be30), + U64C(0xd192e819d6ef5218), U64C(0xd69906245565a910), U64C(0xf40e35855771202a), U64C(0x106aa07032bbd1b8), + U64C(0x19a4c116b8d2d0c8), U64C(0x1e376c085141ab53), U64C(0x2748774cdf8eeb99), U64C(0x34b0bcb5e19b48a8), + U64C(0x391c0cb3c5c95a63), U64C(0x4ed8aa4ae3418acb), U64C(0x5b9cca4f7763e373), U64C(0x682e6ff3d6b2b8a3), + U64C(0x748f82ee5defb2fc), U64C(0x78a5636f43172f60), U64C(0x84c87814a1f0ab72), U64C(0x8cc702081a6439ec), + U64C(0x90befffa23631e28), U64C(0xa4506cebde82bde9), U64C(0xbef9a3f7b2c67915), U64C(0xc67178f2e372532b), + U64C(0xca273eceea26619c), U64C(0xd186b8c721c0c207), U64C(0xeada7dd6cde0eb1e), U64C(0xf57d4f7fee6ed178), + U64C(0x06f067aa72176fba), U64C(0x0a637dc5a2c898a6), U64C(0x113f9804bef90dae), U64C(0x1b710b35131c471b), + U64C(0x28db77f523047d84), U64C(0x32caab7b40c72493), U64C(0x3c9ebe0a15c9bebc), U64C(0x431d67c49c100d4c), + U64C(0x4cc5d4becb3e42b6), U64C(0x597f299cfc657e2a), U64C(0x5fcb6fab3ad6faec), U64C(0x6c44198c4a475817) +}; + +#define K SHA512_K_ARRAY + +Z7_NO_INLINE +void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + UInt64 W +#ifdef Z7_SHA512_BIG_W + [80]; +#else + [16]; +#endif + unsigned j; + UInt64 a,b,c,d,e,f,g,h; +#if !defined(Z7_SHA512_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) + UInt64 tmp; +#endif + + if (numBlocks == 0) return; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + do + { + + for (j = 0; j < 16; j += STEP_PRE) + { + #if STEP_PRE > 4 + + #if STEP_PRE < 8 + R4_PRE(0); + #else + R8_PRE(0); + #if STEP_PRE == 16 + R8_PRE(8); + #endif + #endif + + #else + + R1_PRE(0) + #if STEP_PRE >= 2 + R1_PRE(1) + #if STEP_PRE >= 4 + R1_PRE(2) + R1_PRE(3) + #endif + #endif + + #endif + } + + for (j = 16; j < 80; j += STEP_MAIN) + { + #if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8 + + #if STEP_MAIN < 8 + R4_MAIN(0) + #else + R8_MAIN(0) + #if STEP_MAIN == 16 + R8_MAIN(8) + #endif + #endif + + #else + + R1_MAIN(0) + #if STEP_MAIN >= 2 + R1_MAIN(1) + #if STEP_MAIN >= 4 + R2_MAIN(2) + #if STEP_MAIN >= 8 + R2_MAIN(4) + R2_MAIN(6) + #if STEP_MAIN >= 16 + R2_MAIN(8) + R2_MAIN(10) + R2_MAIN(12) + R2_MAIN(14) + #endif + #endif + #endif + #endif + #endif + } + + a += state[0]; state[0] = a; + b += state[1]; state[1] = b; + c += state[2]; state[2] = c; + d += state[3]; state[3] = d; + e += state[4]; state[4] = e; + f += state[5]; state[5] = f; + g += state[6]; state[6] = g; + h += state[7]; state[7] = h; + + data += SHA512_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Sha512_UpdateBlock(p) SHA512_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Sha512_Update(CSha512 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1); + const unsigned num = SHA512_BLOCK_SIZE - pos; + p->v.vars.count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha512_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 7; + // if (numBlocks) + SHA512_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA512_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 7); + memcpy(p->buffer, data, size); + } +} + + +void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize) +{ + unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (SHA512_BLOCK_SIZE - 8 * 2)) + { + while (pos != SHA512_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA512_BLOCK_SIZE - pos); + Sha512_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (SHA512_BLOCK_SIZE - 8 * 2) - pos); + { + const UInt64 numBits = p->v.vars.count << 3; + SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 2, 0) // = (p->v.vars.count >> (64 - 3)); (high 64-bits) + SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 1, numBits) + } + Sha512_UpdateBlock(p); +#if 1 && defined(MY_CPU_BE) + memcpy(digest, p->state, digestSize); +#else + { + const unsigned numWords = digestSize >> 3; + unsigned i; + for (i = 0; i < numWords; i++) + { + const UInt64 v = p->state[i]; + SetBe64(digest, v) + digest += 8; + } + if (digestSize & 4) // digestSize == SHA512_224_DIGEST_SIZE + { + const UInt32 v = (UInt32)((p->state[numWords]) >> 32); + SetBe32(digest, v) + } + } +#endif + Sha512_InitState(p, digestSize); +} + + + +// #define Z7_SHA512_PROBE_DEBUG // for debug + +#if defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED) + +#if defined(Z7_SHA512_PROBE_DEBUG) \ + || defined(_WIN32) && defined(MY_CPU_ARM64) +#ifndef Z7_SHA512_USE_PROBE +#define Z7_SHA512_USE_PROBE +#endif +#endif + +#ifdef Z7_SHA512_USE_PROBE + +#ifdef Z7_SHA512_PROBE_DEBUG +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#if 0 || !defined(_MSC_VER) // 1 || : for debug LONGJMP mode +// MINGW doesn't support __try. So we use signal() / longjmp(). +// Note: signal() / longjmp() probably is not thread-safe. +// So we must call Sha512Prepare() from main thread at program start. +#ifndef Z7_SHA512_USE_LONGJMP +#define Z7_SHA512_USE_LONGJMP +#endif +#endif + +#ifdef Z7_SHA512_USE_LONGJMP +#include +#include +static jmp_buf g_Sha512_jmp_buf; +// static int g_Sha512_Unsupported; + +#if defined(__GNUC__) && (__GNUC__ >= 8) \ + || defined(__clang__) && (__clang_major__ >= 3) + __attribute__((noreturn)) +#endif +static void Z7_CDECL Sha512_signal_Handler(int v) +{ + PRF(printf("======== Sha512_signal_Handler = %x\n", (unsigned)v);) + // g_Sha512_Unsupported = 1; + longjmp(g_Sha512_jmp_buf, 1); +} +#endif // Z7_SHA512_USE_LONGJMP + + +#if defined(_WIN32) +#include "7zWindows.h" +#endif + +#if defined(MY_CPU_ARM64) +// #define Z7_SHA512_USE_SIMPLIFIED_PROBE // for debug +#endif + +#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE +#include +#if defined(__clang__) + __attribute__((__target__("sha3"))) +#elif !defined(_MSC_VER) + __attribute__((__target__("arch=armv8.2-a+sha3"))) +#endif +#endif +static BoolInt CPU_IsSupported_SHA512_Probe(void) +{ + PRF(printf("\n== CPU_IsSupported_SHA512_Probe\n");) +#if defined(_WIN32) && defined(MY_CPU_ARM64) + // we have no SHA512 flag for IsProcessorFeaturePresent() still. + if (!CPU_IsSupported_CRYPTO()) + return False; + PRF(printf("==== Registry check\n");) + { + // we can't read ID_AA64ISAR0_EL1 register from application. + // but ID_AA64ISAR0_EL1 register is mapped to "CP 4030" registry value. + HKEY key = NULL; + LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), + 0, KEY_READ, &key); + if (res != ERROR_SUCCESS) + return False; + { + DWORD type = 0; + DWORD count = sizeof(UInt64); + UInt64 val = 0; + res = RegQueryValueEx(key, TEXT("CP 4030"), NULL, + &type, (LPBYTE)&val, &count); + RegCloseKey(key); + if (res != ERROR_SUCCESS + || type != REG_QWORD + || count != sizeof(UInt64) + || ((unsigned)(val >> 12) & 0xf) != 2) + return False; + // we parse SHA2 field of ID_AA64ISAR0_EL1 register: + // 0 : No SHA2 instructions implemented + // 1 : SHA256 implemented + // 2 : SHA256 and SHA512 implemented + } + } +#endif // defined(_WIN32) && defined(MY_CPU_ARM64) + + +#if 1 // 0 for debug to disable SHA512 PROBE code + +/* +----- SHA512 PROBE ----- + +We suppose that "CP 4030" registry reading is enough. +But we use additional SHA512 PROBE code, because +we can catch exception here, and we don't catch exceptions, +if we call Sha512 functions from main code. + +NOTE: arm64 PROBE code doesn't work, if we call it via Wine in linux-arm64. +The program just stops. +Also x64 version of PROBE code doesn't work, if we run it via Intel SDE emulator +without SHA512 support (-skl switch), +The program stops, and we have message from SDE: + TID 0 SDE-ERROR: Executed instruction not valid for specified chip (SKYLAKE): vsha512msg1 +But we still want to catch that exception instead of process stopping. +Does this PROBE code work in native Windows-arm64 (with/without sha512 hw instructions)? +Are there any ways to fix the problems with arm64-wine and x64-SDE cases? +*/ + + PRF(printf("==== CPU_IsSupported_SHA512 PROBE\n");) + { + BoolInt isSupported = False; +#ifdef Z7_SHA512_USE_LONGJMP + void (Z7_CDECL *signal_prev)(int); + /* + if (g_Sha512_Unsupported) + { + PRF(printf("==== g_Sha512_Unsupported\n");) + return False; + } + */ + printf("====== signal(SIGILL)\n"); + signal_prev = signal(SIGILL, Sha512_signal_Handler); + if (signal_prev == SIG_ERR) + { + PRF(printf("====== signal fail\n");) + return False; + } + // PRF(printf("==== signal_prev = %p\n", (void *)signal_prev);) + // docs: Before the specified function is executed, + // the value of func is set to SIG_DFL. + // So we can exit if (setjmp(g_Sha512_jmp_buf) != 0). + PRF(printf("====== setjmp\n");) + if (!setjmp(g_Sha512_jmp_buf)) +#else // Z7_SHA512_USE_LONGJMP + +#ifdef _MSC_VER +#ifdef __clang_major__ + #pragma GCC diagnostic ignored "-Wlanguage-extension-token" +#endif + __try +#endif +#endif // Z7_SHA512_USE_LONGJMP + + { +#if defined(Z7_COMPILER_SHA512_SUPPORTED) +#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE + // simplified sha512 check for arm64: + const uint64x2_t a = vdupq_n_u64(1); + const uint64x2_t b = vsha512hq_u64(a, a, a); + PRF(printf("======== vsha512hq_u64 probe\n");) + if ((UInt32)vgetq_lane_u64(b, 0) == 0x11800002) +#else + MY_ALIGN(16) + UInt64 temp[SHA512_NUM_DIGEST_WORDS + SHA512_NUM_BLOCK_WORDS]; + memset(temp, 0x5a, sizeof(temp)); + PRF(printf("======== Sha512_UpdateBlocks_HW\n");) + Sha512_UpdateBlocks_HW(temp, + (const Byte *)(const void *)(temp + SHA512_NUM_DIGEST_WORDS), 1); + // PRF(printf("======== t = %x\n", (UInt32)temp[0]);) + if ((UInt32)temp[0] == 0xa33cfdf7) +#endif + { + PRF(printf("======== PROBE SHA512: SHA512 is supported\n");) + isSupported = True; + } +#else // Z7_COMPILER_SHA512_SUPPORTED + // for debug : we generate bad instrction or raise exception. + // __except() doesn't catch raise() calls. +#ifdef Z7_SHA512_USE_LONGJMP + PRF(printf("====== raise(SIGILL)\n");) + raise(SIGILL); +#else +#if defined(_MSC_VER) && defined(MY_CPU_X86) + __asm ud2 +#endif +#endif // Z7_SHA512_USE_LONGJMP +#endif // Z7_COMPILER_SHA512_SUPPORTED + } + +#ifdef Z7_SHA512_USE_LONGJMP + PRF(printf("====== restore signal SIGILL\n");) + signal(SIGILL, signal_prev); +#elif _MSC_VER + __except (EXCEPTION_EXECUTE_HANDLER) + { + PRF(printf("==== CPU_IsSupported_SHA512 __except(EXCEPTION_EXECUTE_HANDLER)\n");) + } +#endif + PRF(printf("== return (sha512 supported) = %d\n", isSupported);) + return isSupported; + } +#else + // without SHA512 PROBE code + return True; +#endif +} + +#endif // Z7_SHA512_USE_PROBE +#endif // defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED) + + +void Sha512Prepare(void) +{ +#ifdef Z7_COMPILER_SHA512_SUPPORTED + SHA512_FUNC_UPDATE_BLOCKS f, f_hw; + f = Sha512_UpdateBlocks; + f_hw = NULL; +#ifdef Z7_SHA512_USE_PROBE + if (CPU_IsSupported_SHA512_Probe()) +#elif defined(MY_CPU_X86_OR_AMD64) + if (CPU_IsSupported_SHA512() && CPU_IsSupported_AVX2()) +#else + if (CPU_IsSupported_SHA512()) +#endif + { + // printf("\n========== HW SHA512 ======== \n"); + f = f_hw = Sha512_UpdateBlocks_HW; + } + g_SHA512_FUNC_UPDATE_BLOCKS = f; + g_SHA512_FUNC_UPDATE_BLOCKS_HW = f_hw; +#elif defined(Z7_SHA512_PROBE_DEBUG) + CPU_IsSupported_SHA512_Probe(); // for debug +#endif +} + + +#undef K +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef Ch +#undef Maj +#undef W_MAIN +#undef W_PRE +#undef w +#undef blk2_main +#undef blk2 +#undef T1 +#undef T4 +#undef T8 +#undef R1_PRE +#undef R1_MAIN +#undef R2_MAIN +#undef R4 +#undef R4_PRE +#undef R4_MAIN +#undef R8 +#undef R8_PRE +#undef R8_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA512_BIG_W +#undef Z7_SHA512_UNROLL +#undef Z7_COMPILER_SHA512_SUPPORTED diff -Nru 7zip-22.01+dfsg/C/Sha512.h 7zip-22.01+really25.01+dfsg/C/Sha512.h --- 7zip-22.01+dfsg/C/Sha512.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha512.h 2024-10-29 18:00:00.000000000 +0000 @@ -0,0 +1,86 @@ +/* Sha512.h -- SHA-512 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SHA512_H +#define ZIP7_INC_SHA512_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA512_NUM_BLOCK_WORDS 16 +#define SHA512_NUM_DIGEST_WORDS 8 + +#define SHA512_BLOCK_SIZE (SHA512_NUM_BLOCK_WORDS * 8) +#define SHA512_DIGEST_SIZE (SHA512_NUM_DIGEST_WORDS * 8) +#define SHA512_224_DIGEST_SIZE (224 / 8) +#define SHA512_256_DIGEST_SIZE (256 / 8) +#define SHA512_384_DIGEST_SIZE (384 / 8) + +typedef void (Z7_FASTCALL *SHA512_FUNC_UPDATE_BLOCKS)(UInt64 state[8], const Byte *data, size_t numBlocks); + +/* + if (the system supports different SHA512 code implementations) + { + (CSha512::func_UpdateBlocks) will be used + (CSha512::func_UpdateBlocks) can be set by + Sha512_Init() - to default (fastest) + Sha512_SetFunction() - to any algo + } + else + { + (CSha512::func_UpdateBlocks) is ignored. + } +*/ + +typedef struct +{ + union + { + struct + { + SHA512_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[8]; + void *_pad_align_ptr[2]; + } v; + UInt64 state[SHA512_NUM_DIGEST_WORDS]; + + Byte buffer[SHA512_BLOCK_SIZE]; +} CSha512; + + +#define SHA512_ALGO_DEFAULT 0 +#define SHA512_ALGO_SW 1 +#define SHA512_ALGO_HW 2 + +/* +Sha512_SetFunction() +return: + 0 - (algo) value is not supported, and func_UpdateBlocks was not changed + 1 - func_UpdateBlocks was set according (algo) value. +*/ + +BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo); +// we support only these (digestSize) values: 224/8, 256/8, 384/8, 512/8 +void Sha512_InitState(CSha512 *p, unsigned digestSize); +void Sha512_Init(CSha512 *p, unsigned digestSize); +void Sha512_Update(CSha512 *p, const Byte *data, size_t size); +void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize); + + + + +// void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks); + +/* +call Sha512Prepare() once at program start. +It prepares all supported implementations, and detects the fastest implementation. +*/ + +void Sha512Prepare(void); + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/Sha512Opt.c 7zip-22.01+really25.01+dfsg/C/Sha512Opt.c --- 7zip-22.01+dfsg/C/Sha512Opt.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sha512Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -0,0 +1,395 @@ +/* Sha512Opt.c -- SHA-512 optimized code for SHA-512 hardware instructions +: Igor Pavlov : Public domain */ + +#include "Precomp.h" +#include "Compiler.h" +#include "CpuArch.h" + +// #define Z7_USE_HW_SHA_STUB // for debug +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) // fix it + #define USE_HW_SHA + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000) + #define USE_HW_SHA + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA512__) || !defined(__AVX2__) + #define ATTRIB_SHA512 __attribute__((__target__("sha512,avx2"))) + #endif + #endif + #elif defined(Z7_MSC_VER_ORIGINAL) + #if (_MSC_VER >= 1940) + #define USE_HW_SHA + #else + // #define Z7_USE_HW_SHA_STUB + #endif + #endif +// #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif + +#ifdef USE_HW_SHA + +// #pragma message("Sha512 HW") + +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__AVX__) + #include + #endif + #if !defined(__AVX2__) + #include + #endif + #if !defined(__SHA512__) + #include + #endif +#else + +#endif + +/* +SHA512 uses: +AVX: + _mm256_loadu_si256 (vmovdqu) + _mm256_storeu_si256 + _mm256_set_epi32 (unused) +AVX2: + _mm256_add_epi64 : vpaddq + _mm256_shuffle_epi8 : vpshufb + _mm256_shuffle_epi32 : pshufd + _mm256_blend_epi32 : vpblendd + _mm256_permute4x64_epi64 : vpermq : 3c + _mm256_permute2x128_si256: vperm2i128 : 3c + _mm256_extracti128_si256 : vextracti128 : 3c +SHA512: + _mm256_sha512* +*/ + +// K array must be aligned for 32-bytes at least. +// The compiler can look align attribute and selects +// vmovdqu - for code without align attribute +// vmovdqa - for code with align attribute +extern +MY_ALIGN(64) +const UInt64 SHA512_K_ARRAY[80]; +#define K SHA512_K_ARRAY + + +#define ADD_EPI64(dest, src) dest = _mm256_add_epi64(dest, src); +#define SHA512_MSG1(dest, src) dest = _mm256_sha512msg1_epi64(dest, _mm256_extracti128_si256(src, 0)); +#define SHA512_MSG2(dest, src) dest = _mm256_sha512msg2_epi64(dest, src); + +#define LOAD_SHUFFLE(m, k) \ + m = _mm256_loadu_si256((const __m256i *)(const void *)(data + (k) * 32)); \ + m = _mm256_shuffle_epi8(m, mask); \ + +#define NNN(m0, m1, m2, m3) + +#define SM1(m1, m2, m3, m0) \ + SHA512_MSG1(m0, m1); \ + +#define SM2(m2, m3, m0, m1) \ + ADD_EPI64(m0, _mm256_permute4x64_epi64(_mm256_blend_epi32(m2, m3, 3), 0x39)); \ + SHA512_MSG2(m0, m3); \ + +#define RND2(t0, t1, lane) \ + t0 = _mm256_sha512rnds2_epi64(t0, t1, _mm256_extracti128_si256(msg, lane)); + + + +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = _mm256_add_epi64(m0, *(const __m256i *) (const void *) &K[(k) * 4]); \ + RND2(state0, state1, 0); OP0(m0, m1, m2, m3) \ + RND2(state1, state0, 1); OP1(m0, m1, m2, m3) \ + + + + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \ + +#define PREPARE_STATE \ + state0 = _mm256_shuffle_epi32(state0, 0x4e); /* cdab */ \ + state1 = _mm256_shuffle_epi32(state1, 0x4e); /* ghef */ \ + tmp = state0; \ + state0 = _mm256_permute2x128_si256(state0, state1, 0x13); /* cdgh */ \ + state1 = _mm256_permute2x128_si256(tmp, state1, 2); /* abef */ \ + + +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA512 +ATTRIB_SHA512 +#endif +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + const __m256i mask = _mm256_set_epi32( + 0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607, + 0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607); + __m256i tmp, state0, state1; + + if (numBlocks == 0) + return; + + state0 = _mm256_loadu_si256((const __m256i *) (const void *) &state[0]); + state1 = _mm256_loadu_si256((const __m256i *) (const void *) &state[4]); + + PREPARE_STATE + + do + { + __m256i state0_save, state1_save; + __m256i m0, m1, m2, m3; + __m256i msg; + // #define msg tmp + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 4, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) + ADD_EPI64(state0, state0_save) + ADD_EPI64(state1, state1_save) + + data += 128; + } + while (--numBlocks); + + PREPARE_STATE + + _mm256_storeu_si256((__m256i *) (void *) &state[0], state0); + _mm256_storeu_si256((__m256i *) (void *) &state[4], state1); +} + +#endif // USE_HW_SHA + +// gcc 8.5 also supports sha512, but we need also support in assembler that is called by gcc +#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA512) + #define USE_HW_SHA + #else + #if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it + #define USE_HW_SHA + #endif + #endif + +#ifdef USE_HW_SHA + +// #pragma message("=== Sha512 HW === ") + + +#if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA512) +// #pragma message("=== we define SHA3 ATTRIB_SHA512 === ") +#if defined(__clang__) + #define ATTRIB_SHA512 __attribute__((__target__("sha3"))) // "armv8.2-a,sha3" +#else + #define ATTRIB_SHA512 __attribute__((__target__("arch=armv8.2-a+sha3"))) +#endif +#endif +#endif + + +#if defined(Z7_MSC_VER_ORIGINAL) +#include +#else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA512) +// #pragma message("=== we set __ARM_FEATURE_SHA512 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_SHA512_WAS_SET 1 + #define __ARM_FEATURE_SHA512 1 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#include + +#if defined(Z7_ARM_FEATURE_SHA512_WAS_SET) && \ + defined(__ARM_FEATURE_SHA512) + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_SHA512 + #undef Z7_ARM_FEATURE_SHA512_WAS_SET + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") +#endif + +#endif // Z7_MSC_VER_ORIGINAL + +typedef uint64x2_t v128_64; +// typedef __n128 v128_64; // MSVC + +#ifdef MY_CPU_BE + #define MY_rev64_for_LE(x) x +#else + #define MY_rev64_for_LE(x) vrev64q_u8(x) +#endif + +#define LOAD_128_64(_p) vld1q_u64(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_64(_p, _v) vst1q_u64(_p, _v) + +#define LOAD_SHUFFLE(m, k) \ + m = vreinterpretq_u64_u8( \ + MY_rev64_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ + +// K array must be aligned for 16-bytes at least. +extern +MY_ALIGN(64) +const UInt64 SHA512_K_ARRAY[80]; +#define K SHA512_K_ARRAY + +#define NN(m0, m1, m4, m5, m7) +#define SM(m0, m1, m4, m5, m7) \ + m0 = vsha512su1q_u64(vsha512su0q_u64(m0, m1), m7, vextq_u64(m4, m5, 1)); + +#define R2(k, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP) \ + OP(m0, m1, m4, m5, m7) \ + t = vaddq_u64(m0, vld1q_u64(k)); \ + t = vaddq_u64(vextq_u64(t, t, 1), a3); \ + t = vsha512hq_u64(t, vextq_u64(a2, a3, 1), vextq_u64(a1, a2, 1)); \ + a3 = vsha512h2q_u64(t, a1, a0); \ + a1 = vaddq_u64(a1, t); \ + +#define R8(k, m0,m1,m2,m3,m4,m5,m6,m7, OP) \ + R2 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP ) \ + R2 ( (k)+1*2, m1,m2,m3,m4,m5,m6,m7,m0, a3,a0,a1,a2, OP ) \ + R2 ( (k)+2*2, m2,m3,m4,m5,m6,m7,m0,m1, a2,a3,a0,a1, OP ) \ + R2 ( (k)+3*2, m3,m4,m5,m6,m7,m0,m1,m2, a1,a2,a3,a0, OP ) \ + +#define R16(k, OP) \ + R8 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, OP ) \ + R8 ( (k)+4*2, m4,m5,m6,m7,m0,m1,m2,m3, OP ) \ + + +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA512 +ATTRIB_SHA512 +#endif +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + v128_64 a0, a1, a2, a3; + + if (numBlocks == 0) + return; + a0 = LOAD_128_64(&state[0]); + a1 = LOAD_128_64(&state[2]); + a2 = LOAD_128_64(&state[4]); + a3 = LOAD_128_64(&state[6]); + do + { + v128_64 a0_save, a1_save, a2_save, a3_save; + v128_64 m0, m1, m2, m3, m4, m5, m6, m7; + v128_64 t; + unsigned i; + const UInt64 *k_ptr; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + LOAD_SHUFFLE (m4, 4) + LOAD_SHUFFLE (m5, 5) + LOAD_SHUFFLE (m6, 6) + LOAD_SHUFFLE (m7, 7) + + a0_save = a0; + a1_save = a1; + a2_save = a2; + a3_save = a3; + + R16 ( K, NN ) + k_ptr = K + 16; + for (i = 0; i < 4; i++) + { + R16 ( k_ptr, SM ) + k_ptr += 16; + } + + a0 = vaddq_u64(a0, a0_save); + a1 = vaddq_u64(a1, a1_save); + a2 = vaddq_u64(a2, a2_save); + a3 = vaddq_u64(a3, a3_save); + + data += 128; + } + while (--numBlocks); + + STORE_128_64(&state[0], a0); + STORE_128_64(&state[2], a1); + STORE_128_64(&state[4], a2); + STORE_128_64(&state[6], a3); +} + +#endif // USE_HW_SHA + +#endif // MY_CPU_ARM_OR_ARM64 + + +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) +// #error Stop_Compiling_UNSUPPORTED_SHA +// #include +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. +// #include "Sha512.h" +// #if defined(_MSC_VER) +#pragma message("Sha512 HW-SW stub was used") +// #endif +void Z7_FASTCALL Sha512_UpdateBlocks (UInt64 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + Sha512_UpdateBlocks(state, data, numBlocks); + /* + UNUSED_VAR(state); + UNUSED_VAR(data); + UNUSED_VAR(numBlocks); + exit(1); + return; + */ +} +#endif + + +#undef K +#undef RND2 +#undef MY_rev64_for_LE +#undef NN +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 +#undef SM +#undef R2 +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA512 +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru 7zip-22.01+dfsg/C/Sort.c 7zip-22.01+really25.01+dfsg/C/Sort.c --- 7zip-22.01+dfsg/C/Sort.c 2014-04-05 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sort.c 2025-01-08 09:00:00.000000000 +0000 @@ -1,141 +1,268 @@ /* Sort.c -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" #include "Sort.h" +#include "CpuArch.h" -#define HeapSortDown(p, k, size, temp) \ - { for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && p[s + 1] > p[s]) s++; \ - if (temp >= p[s]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } +#if ( (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_prefetch)) \ + ) +// the code with prefetch is slow for small arrays on x86. +// So we disable prefetch for x86. +#ifndef MY_CPU_X86 + // #pragma message("Z7_PREFETCH : __builtin_prefetch") + #define Z7_PREFETCH(a) __builtin_prefetch((a)) +#endif -void HeapSort(UInt32 *p, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt32 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt32 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) - } - { - UInt32 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) - { - p[1] = p[2]; - p[2] = temp; - } - else - p[1] = temp; - } +#elif defined(_WIN32) // || defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "7zWindows.h" + +// NOTE: CLANG/GCC/MSVC can define different values for _MM_HINT_T0 / PF_TEMPORAL_LEVEL_1. +// For example, clang-cl can generate "prefetcht2" instruction for +// PreFetchCacheLine(PF_TEMPORAL_LEVEL_1) call. +// But we want to generate "prefetcht0" instruction. +// So for CLANG/GCC we must use __builtin_prefetch() in code branch above +// instead of PreFetchCacheLine() / _mm_prefetch(). + +// New msvc-x86 compiler generates "prefetcht0" instruction for PreFetchCacheLine() call. +// But old x86 cpus don't support "prefetcht0". +// So we will use PreFetchCacheLine(), only if we are sure that +// generated instruction is supported by all cpus of that isa. +#if defined(MY_CPU_AMD64) \ + || defined(MY_CPU_ARM64) \ + || defined(MY_CPU_IA64) +// we need to use additional braces for (a) in PreFetchCacheLine call, because +// PreFetchCacheLine macro doesn't use braces: +// #define PreFetchCacheLine(l, a) _mm_prefetch((CHAR CONST *) a, l) + // #pragma message("Z7_PREFETCH : PreFetchCacheLine") + #define Z7_PREFETCH(a) PreFetchCacheLine(PF_TEMPORAL_LEVEL_1, (a)) +#endif + +#endif // _WIN32 + + +#define PREFETCH_NO(p,k,s,size) + +#ifndef Z7_PREFETCH + #define SORT_PREFETCH(p,k,s,size) +#else + +// #define PREFETCH_LEVEL 2 // use it if cache line is 32-bytes +#define PREFETCH_LEVEL 3 // it is fast for most cases (64-bytes cache line prefetch) +// #define PREFETCH_LEVEL 4 // it can be faster for big array (128-bytes prefetch) + +#if PREFETCH_LEVEL == 0 + + #define SORT_PREFETCH(p,k,s,size) + +#else // PREFETCH_LEVEL != 0 + +/* +if defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + we prefetch one value per cache line. + Use it if array is aligned for cache line size (64 bytes) + or if array is small (less than L1 cache size). + +if !defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + we perfetch all cache lines that can be required. + it can be faster for big unaligned arrays. +*/ + #define USE_PREFETCH_FOR_ALIGNED_ARRAY + +// s == k * 2 +#if 0 && PREFETCH_LEVEL <= 3 && defined(MY_CPU_X86_OR_AMD64) + // x86 supports (lea r1*8+offset) + #define PREFETCH_OFFSET(k,s) ((s) << PREFETCH_LEVEL) +#else + #define PREFETCH_OFFSET(k,s) ((k) << (PREFETCH_LEVEL + 1)) +#endif + +#if 1 && PREFETCH_LEVEL <= 3 && defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + #define PREFETCH_ADD_OFFSET 0 +#else + // last offset that can be reqiured in PREFETCH_LEVEL step: + #define PREFETCH_RANGE ((2 << PREFETCH_LEVEL) - 1) + #define PREFETCH_ADD_OFFSET PREFETCH_RANGE / 2 +#endif + +#if PREFETCH_LEVEL <= 3 + +#ifdef USE_PREFETCH_FOR_ALIGNED_ARRAY + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_ADD_OFFSET; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2)); \ + }} +#else /* for unaligned array */ + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE)); \ + Z7_PREFETCH((p + s2)); \ + }} +#endif + +#else // PREFETCH_LEVEL > 3 + +#ifdef USE_PREFETCH_FOR_ALIGNED_ARRAY + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE - 16 / 2; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - 16)); \ + Z7_PREFETCH((p + s2)); \ + }} +#else /* for unaligned array */ + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE)); \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE / 2)); \ + Z7_PREFETCH((p + s2)); \ + }} +#endif + +#endif // PREFETCH_LEVEL > 3 +#endif // PREFETCH_LEVEL != 0 +#endif // Z7_PREFETCH + + +#if defined(MY_CPU_ARM64) \ + /* || defined(MY_CPU_AMD64) */ \ + /* || defined(MY_CPU_ARM) && !defined(_MSC_VER) */ + // we want to use cmov, if cmov is very fast: + // - this cmov version is slower for clang-x64. + // - this cmov version is faster for gcc-arm64 for some fast arm64 cpus. + #define Z7_FAST_CMOV_SUPPORTED +#endif + +#ifdef Z7_FAST_CMOV_SUPPORTED + // we want to use cmov here, if cmov is fast: new arm64 cpus. + // we want the compiler to use conditional move for this branch + #define GET_MAX_VAL(n0, n1, max_val_slow) if (n0 < n1) n0 = n1; +#else + // use this branch, if cpu doesn't support fast conditional move. + // it uses slow array access reading: + #define GET_MAX_VAL(n0, n1, max_val_slow) n0 = max_val_slow; +#endif + +#define HeapSortDown(p, k, size, temp, macro_prefetch) \ +{ \ + for (;;) { \ + UInt32 n0, n1; \ + size_t s = k * 2; \ + if (s >= size) { \ + if (s == size) { \ + n0 = p[s]; \ + p[k] = n0; \ + if (temp < n0) k = s; \ + } \ + break; \ + } \ + n0 = p[k * 2]; \ + n1 = p[k * 2 + 1]; \ + s += n0 < n1; \ + GET_MAX_VAL(n0, n1, p[s]) \ + if (temp >= n0) break; \ + macro_prefetch(p, k, s, size) \ + p[k] = n0; \ + k = s; \ + } \ + p[k] = temp; \ } -void HeapSort64(UInt64 *p, size_t size) + +/* +stage-1 : O(n) : + we generate intermediate partially sorted binary tree: + p[0] : it's additional item for better alignment of tree structure in memory. + p[1] + p[2] p[3] + p[4] p[5] p[6] p[7] + ... + p[x] >= p[x * 2] + p[x] >= p[x * 2 + 1] + +stage-2 : O(n)*log2(N): + we move largest item p[0] from head of tree to the end of array + and insert last item to sorted binary tree. +*/ + +// (p) must be aligned for cache line size (64-bytes) for best performance + +void Z7_FASTCALL HeapSort(UInt32 *p, size_t size) { - if (size <= 1) + if (size < 2) return; - p--; + if (size == 2) { - size_t i = size / 2; - do - { - UInt64 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt64 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt64 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) + const UInt32 a0 = p[0]; + const UInt32 a1 = p[1]; + const unsigned k = a1 < a0; + p[k] = a0; + p[k ^ 1] = a1; + return; } { - UInt64 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) + // stage-1 : O(n) + // we transform array to partially sorted binary tree. + size_t i = --size / 2; + // (size) now is the index of the last item in tree, + // if (i) + { + do + { + const UInt32 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp, PREFETCH_NO) + } + while (--i); + } { - p[1] = p[2]; - p[2] = temp; + const UInt32 temp = p[0]; + const UInt32 a1 = p[1]; + if (temp < a1) + { + size_t k = 1; + p[0] = a1; + HeapSortDown(p, k, size, temp, PREFETCH_NO) + } } - else - p[1] = temp; } -} - -/* -#define HeapSortRefDown(p, vals, n, size, temp) \ - { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ - if (val >= vals[p[s]]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } -void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) -{ - if (size <= 1) + if (size < 3) + { + // size == 2 + const UInt32 a0 = p[0]; + p[0] = p[2]; + p[2] = a0; return; - p--; + } + if (size != 3) { - size_t i = size / 2; + // stage-2 : O(size) * log2(size): + // we move largest item p[0] from head to the end of array, + // and insert last item to sorted binary tree. do { - UInt32 temp = p[i]; - HeapSortRefDown(p, vals, i, size, temp); + const UInt32 temp = p[size]; + size_t k = p[2] < p[3] ? 3 : 2; + p[size--] = p[0]; + p[0] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp, SORT_PREFETCH) // PREFETCH_NO } - while (--i != 0); + while (size != 3); } - do { - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortRefDown(p, vals, 1, size, temp); + const UInt32 a2 = p[2]; + const UInt32 a3 = p[3]; + const size_t k = a2 < a3; + p[2] = p[1]; + p[3] = p[0]; + p[k] = a3; + p[k ^ 1] = a2; } - while (size > 1); } -*/ diff -Nru 7zip-22.01+dfsg/C/Sort.h 7zip-22.01+really25.01+dfsg/C/Sort.h --- 7zip-22.01+dfsg/C/Sort.h 2014-04-05 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Sort.h 2025-01-06 09:00:00.000000000 +0000 @@ -1,17 +1,14 @@ /* Sort.h -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __7Z_SORT_H -#define __7Z_SORT_H +#ifndef ZIP7_INC_SORT_H +#define ZIP7_INC_SORT_H #include "7zTypes.h" EXTERN_C_BEGIN -void HeapSort(UInt32 *p, size_t size); -void HeapSort64(UInt64 *p, size_t size); - -/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ +void Z7_FASTCALL HeapSort(UInt32 *p, size_t size); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/SwapBytes.c 7zip-22.01+really25.01+dfsg/C/SwapBytes.c --- 7zip-22.01+dfsg/C/SwapBytes.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/SwapBytes.c 2024-03-01 11:00:00.000000000 +0000 @@ -0,0 +1,835 @@ +/* SwapBytes.c -- Byte Swap conversion filter +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Compiler.h" +#include "CpuArch.h" +#include "RotateDefs.h" +#include "SwapBytes.h" + +typedef UInt16 CSwapUInt16; +typedef UInt32 CSwapUInt32; + +// #define k_SwapBytes_Mode_BASE 0 + +#ifdef MY_CPU_X86_OR_AMD64 + +#define k_SwapBytes_Mode_SSE2 1 +#define k_SwapBytes_Mode_SSSE3 2 +#define k_SwapBytes_Mode_AVX2 3 + + // #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #define SWAP_ATTRIB_SSE2 __attribute__((__target__("sse2"))) + #define SWAP_ATTRIB_SSSE3 __attribute__((__target__("ssse3"))) + #define SWAP_ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #elif defined(_MSC_VER) + #if (_MSC_VER == 1900) + #pragma warning(disable : 4752) // found Intel(R) Advanced Vector Extensions; consider using /arch:AVX + #endif + #if (_MSC_VER >= 1900) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #elif (_MSC_VER >= 1500) // (VS2008) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSSE3 + #elif (_MSC_VER >= 1310) // (VS2003) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSE2 + #endif + #endif // _MSC_VER + +/* +// for debug +#ifdef k_SwapBytes_Mode_MAX +#undef k_SwapBytes_Mode_MAX +#endif +*/ + +#ifndef k_SwapBytes_Mode_MAX +#define k_SwapBytes_Mode_MAX 0 +#endif + +#if (k_SwapBytes_Mode_MAX != 0) && defined(MY_CPU_AMD64) + #define k_SwapBytes_Mode_MIN k_SwapBytes_Mode_SSE2 +#else + #define k_SwapBytes_Mode_MIN 0 +#endif + +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_AVX2) + #define USE_SWAP_AVX2 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSSE3) + #define USE_SWAP_SSSE3 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSE2) + #define USE_SWAP_128 +#endif + +#if k_SwapBytes_Mode_MAX <= k_SwapBytes_Mode_MIN || !defined(USE_SWAP_128) +#define FORCE_SWAP_MODE +#endif + + +#ifdef USE_SWAP_128 +/* + MMX + SSE + SSE2 + SSE3 + SSSE3 + SSE4.1 + SSE4.2 + SSE4A + AES + AVX, AVX2, FMA +*/ + +#include // sse2 +// typedef __m128i v128; + +#define SWAP2_128(i) { \ + const __m128i v = *(const __m128i *)(const void *)(items + (i) * 8); \ + *( __m128i *)( void *)(items + (i) * 8) = \ + _mm_or_si128( \ + _mm_slli_epi16(v, 8), \ + _mm_srli_epi16(v, 8)); } +// _mm_or_si128() has more ports to execute than _mm_add_epi16(). + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +/* +// sse2 +#define SWAP4_128_pack(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v0 = _mm_unpacklo_epi8(v, mask); \ + __m128i v1 = _mm_unpackhi_epi8(v, mask); \ + v0 = _mm_shufflelo_epi16(v0, 0x1b); \ + v1 = _mm_shufflelo_epi16(v1, 0x1b); \ + v0 = _mm_shufflehi_epi16(v0, 0x1b); \ + v1 = _mm_shufflehi_epi16(v1, 0x1b); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_packus_epi16(v0, v1); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_pack(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + const __m128i mask = _mm_setzero_si128(); + // const __m128i mask = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, 0); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128_pack(0); items += 1 * 4; + // SWAP4_128_pack(0); SWAP4_128_pack(1); items += 2 * 4; + } + while (items != lim); +} + +// sse2 +#define SWAP4_128_shift(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v2; \ + v2 = _mm_or_si128( \ + _mm_slli_si128(_mm_and_si128(v, mask), 1), \ + _mm_and_si128(_mm_srli_si128(v, 1), mask)); \ + v = _mm_or_si128( \ + _mm_slli_epi32(v, 24), \ + _mm_srli_epi32(v, 24)); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_or_si128(v2, v); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_shift(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + #define M1 0xff00 + const __m128i mask = _mm_set_epi32(M1, M1, M1, M1); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + SWAP4_128_shift(0); items += 1 * 4; + } + while (items != lim); +} +*/ + + +#if defined(USE_SWAP_SSSE3) || defined(USE_SWAP_AVX2) + +#define SWAP_SHUF_REV_SEQ_2_VALS(v) (v)+1, (v) +#define SWAP_SHUF_REV_SEQ_4_VALS(v) (v)+3, (v)+2, (v)+1, (v) + +#define SWAP2_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_2_VALS (0 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (1 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (2 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (3 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (4 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (5 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (6 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (7 * 2) + +#define SWAP4_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_4_VALS (0 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (1 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (2 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (3 * 4) + +#if defined(USE_SWAP_AVX2) +/* if we use 256_BIT_INIT_MASK, each static array mask will be larger for 16 bytes */ +// #define SWAP_USE_256_BIT_INIT_MASK +#endif + +#if defined(SWAP_USE_256_BIT_INIT_MASK) && defined(USE_SWAP_AVX2) +#define SWAP_MASK_INIT_SIZE 32 +#else +#define SWAP_MASK_INIT_SIZE 16 +#endif + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap2[] = +{ + SWAP2_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP2_SHUF_MASK_16_BYTES + #endif +}; + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap4[] = +{ + SWAP4_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP4_SHUF_MASK_16_BYTES + #endif +}; + + +#ifdef USE_SWAP_SSSE3 + +#include // ssse3 + +#define SHUF_128(i) *(items + (i)) = \ + _mm_shuffle_epi8(*(items + (i)), mask); // SSSE3 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_SSSE3 +SWAP_ATTRIB_SSSE3 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_128(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m128i *items = (__m128i *)items8; + const __m128i *lim = (const __m128i *)lim8; + // const __m128i mask = _mm_set_epi8(SHUF_SWAP2_MASK_16_VALS); + // const __m128i mask = _mm_set_epi8(SHUF_SWAP4_MASK_16_VALS); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = *(const __m128i *)(const void *)&(k_ShufMask_Swap4[0]); + const __m128i mask = *(const __m128i *)mask128_ptr; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_128(0) SHUF_128(1) items += 2; + SHUF_128(0) SHUF_128(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_SSSE3 + + + +#ifdef USE_SWAP_AVX2 + +#include // avx, avx2 +#if defined(__clang__) +#include +#include +#endif + +#define SHUF_256(i) *(items + (i)) = \ + _mm256_shuffle_epi8(*(items + (i)), mask); // AVX2 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_AVX2 +SWAP_ATTRIB_AVX2 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_256(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m256i *items = (__m256i *)items8; + const __m256i *lim = (const __m256i *)lim8; + /* + UNUSED_VAR(mask128_ptr) + __m256i mask = + for Swap4: _mm256_setr_epi8(SWAP4_SHUF_MASK_16_BYTES, SWAP4_SHUF_MASK_16_BYTES); + for Swap2: _mm256_setr_epi8(SWAP2_SHUF_MASK_16_BYTES, SWAP2_SHUF_MASK_16_BYTES); + */ + const __m256i mask = + #if SWAP_MASK_INIT_SIZE > 16 + *(const __m256i *)(const void *)mask128_ptr; + #else + /* msvc: broadcastsi128() version reserves the stack for no reason + msvc 19.29-: _mm256_insertf128_si256() / _mm256_set_m128i)) versions use non-avx movdqu xmm0,XMMWORD PTR [r8] + msvc 19.30+ (VS2022): replaces _mm256_set_m128i(m,m) to vbroadcastf128(m) as we want + */ + // _mm256_broadcastsi128_si256(*mask128_ptr); +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 80000) + #define MY_mm256_set_m128i(hi, lo) _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1) +#else + #define MY_mm256_set_m128i _mm256_set_m128i +#endif + MY_mm256_set_m128i( + *(const __m128i *)mask128_ptr, + *(const __m128i *)mask128_ptr); + #endif + + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_256(0) SHUF_256(1) items += 2; + SHUF_256(0) SHUF_256(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_AVX2 +#endif // USE_SWAP_SSSE3 || USE_SWAP_AVX2 +#endif // USE_SWAP_128 + + + +// compile message "NEON intrinsics not available with the soft-float ABI" +#elif defined(MY_CPU_ARM_OR_ARM64) \ + && defined(MY_CPU_LE) \ + && !defined(Z7_DISABLE_ARM_NEON) + + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 6) + #if defined(__ARM_FP) + #if (defined(__ARM_ARCH) && (__ARM_ARCH >= 4)) \ + || defined(MY_CPU_ARM64) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) + #define USE_SWAP_128 + #ifdef MY_CPU_ARM64 + // #define SWAP_ATTRIB_NEON __attribute__((__target__(""))) + #else +#if defined(Z7_CLANG_VERSION) + // #define SWAP_ATTRIB_NEON __attribute__((__target__("neon"))) +#else + // #pragma message("SWAP_ATTRIB_NEON __attribute__((__target__(fpu=neon))") + #define SWAP_ATTRIB_NEON __attribute__((__target__("fpu=neon"))) +#endif + #endif // MY_CPU_ARM64 + #endif // __ARM_NEON + #endif // __ARM_ARCH + #endif // __ARM_FP + + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1910) + #define USE_SWAP_128 + #endif + #endif + + #ifdef USE_SWAP_128 + #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) + #include + #else + +/* +#if !defined(__ARM_NEON) +#if defined(Z7_GCC_VERSION) && (__GNUC__ < 5) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 5) && (Z7_GCC_VERSION < 90201) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 5) && (Z7_GCC_VERSION < 100100) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#pragma message("#define __ARM_NEON 1") +// #define __ARM_NEON 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif +*/ + #include + #endif + #endif + +#ifndef USE_SWAP_128 + #define FORCE_SWAP_MODE +#else + +#ifdef MY_CPU_ARM64 + // for debug : comment it + #define FORCE_SWAP_MODE +#else + #define k_SwapBytes_Mode_NEON 1 +#endif +// typedef uint8x16_t v128; +#define SWAP2_128(i) *(uint8x16_t *) (void *)(items + (i) * 8) = \ + vrev16q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 8)); +#define SWAP4_128(i) *(uint8x16_t *) (void *)(items + (i) * 4) = \ + vrev32q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 4)); + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes4_128(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + } + while (items != lim); +} + +#endif // USE_SWAP_128 + +#else // MY_CPU_ARM_OR_ARM64 +#define FORCE_SWAP_MODE +#endif // MY_CPU_ARM_OR_ARM64 + + + + + + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_X86) + /* _byteswap_ushort() in MSVC x86 32-bit works via slow { mov dh, al; mov dl, ah } + So we use own versions of byteswap function */ + #if (_MSC_VER < 1400 ) // old MSVC-X86 without _rotr16() support + #define SWAP2_16(i) { UInt32 v = items[i]; v += (v << 16); v >>= 8; items[i] = (CSwapUInt16)v; } + #else // is new MSVC-X86 with fast _rotr16() + #include + #define SWAP2_16(i) { items[i] = _rotr16(items[i], 8); } + #endif +#else // is not MSVC-X86 + #define SWAP2_16(i) { CSwapUInt16 v = items[i]; items[i] = Z7_BSWAP16(v); } +#endif // MSVC-X86 + +#if defined(Z7_CPU_FAST_BSWAP_SUPPORTED) + #define SWAP4_32(i) { CSwapUInt32 v = items[i]; items[i] = Z7_BSWAP32(v); } +#else + #define SWAP4_32(i) \ + { UInt32 v = items[i]; \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); \ + v = rotlFixed(v, 16); \ + items[i] = v; } +#endif + + + + +#if defined(FORCE_SWAP_MODE) && defined(USE_SWAP_128) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(MY_CPU_X86_OR_AMD64) + #define DEFAULT_Swap4 SwapBytes4_128 + #endif +#endif + +#if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + +#define SWAP_BASE_FUNCS_PREFIXES \ +Z7_FORCE_INLINE \ +static \ +Z7_ATTRIB_NO_VECTOR \ +void Z7_FASTCALL + + +#if defined(MY_CPU_ARM_OR_ARM64) +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wlanguage-extension-token" +#endif +#endif + + +#ifdef MY_CPU_64BIT + +#if defined(MY_CPU_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 8) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + + #define SWAP2_64_VAR(v) asm ("rev16 %x0,%x0" : "+r" (v)); + #define SWAP4_64_VAR(v) asm ("rev32 %x0,%x0" : "+r" (v)); + +#else // is not ARM64-GNU + +#if !defined(MY_CPU_X86_OR_AMD64) || (k_SwapBytes_Mode_MIN == 0) || !defined(USE_SWAP_128) + #define SWAP2_64_VAR(v) \ + v = ( 0x00ff00ff00ff00ff & (v >> 8)) \ + + ((0x00ff00ff00ff00ff & v) << 8); + /* plus gives faster code in MSVC */ +#endif + +#ifdef Z7_CPU_FAST_BSWAP_SUPPORTED + #define SWAP4_64_VAR(v) \ + v = Z7_BSWAP64(v); \ + v = Z7_ROTL64(v, 32); +#else + #define SWAP4_64_VAR(v) \ + v = ( 0x000000ff000000ff & (v >> 24)) \ + + ((0x000000ff000000ff & v) << 24 ) \ + + ( 0x0000ff000000ff00 & (v >> 8)) \ + + ((0x0000ff000000ff00 & v) << 8 ) \ + ; +#endif + +#endif // ARM64-GNU + + +#ifdef SWAP2_64_VAR + +#define SWAP2_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 4); \ + SWAP2_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 4) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_64(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + } + while (items != lim); +} + + #define DEFAULT_Swap2 SwapBytes2_64 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 + #endif +#else // !defined(SWAP2_64_VAR) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 1 + #endif +#endif // SWAP2_64_VAR + + +#define SWAP4_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 2); \ + SWAP4_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 2) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_64(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + } + while (items != lim); +} + +#define DEFAULT_Swap4 SwapBytes4_64 + +#else // is not 64BIT + + +#if defined(MY_CPU_ARM_OR_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 6) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + +#ifdef MY_CPU_64BIT + #define SWAP2_32_VAR(v) asm ("rev16 %w0,%w0" : "+r" (v)); +#else + #define SWAP2_32_VAR(v) asm ("rev16 %0,%0" : "+r" (v)); // for clang/gcc + // asm ("rev16 %r0,%r0" : "+r" (a)); // for gcc +#endif + +#elif defined(_MSC_VER) && (_MSC_VER < 1300) && defined(MY_CPU_X86) \ + || !defined(Z7_CPU_FAST_BSWAP_SUPPORTED) \ + || !defined(Z7_CPU_FAST_ROTATE_SUPPORTED) + // old msvc doesn't support _byteswap_ulong() + #define SWAP2_32_VAR(v) \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); + +#else // is not ARM and is not old-MSVC-X86 and fast BSWAP/ROTATE are supported + #define SWAP2_32_VAR(v) \ + v = Z7_BSWAP32(v); \ + v = rotlFixed(v, 16); + +#endif // GNU-ARM* + +#define SWAP2_32(i) { \ + UInt32 v = *(const UInt32 *)(const void *)(items + (i) * 2); \ + SWAP2_32_VAR(v); \ + *(UInt32 *)(void *)(items + (i) * 2) = v; } + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_32(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + } + while (items != lim); +} + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_32(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_32(0) SWAP4_32(1) items += 2; + SWAP4_32(0) SWAP4_32(1) items += 2; + } + while (items != lim); +} + +#define DEFAULT_Swap2 SwapBytes2_32 +#define DEFAULT_Swap4 SwapBytes4_32 +#if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 +#endif + +#endif // MY_CPU_64BIT +#endif // if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + + + +#if !defined(FORCE_SWAP_MODE) +static unsigned g_SwapBytes_Mode; +#endif + +/* size of largest unrolled loop iteration: 128 bytes = 4 * 32 bytes (AVX). */ +#define SWAP_ITERATION_BLOCK_SIZE_MAX (1 << 7) + +// 32 bytes for (AVX) or 2 * 16-bytes for NEON. +#define SWAP_VECTOR_ALIGN_SIZE (1 << 5) + +Z7_NO_INLINE +void z7_SwapBytes2(CSwapUInt16 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP2_16(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt16) - 1; + size_t numItems2 = numItems; + CSwapUInt16 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #endif // MY_CPU_X86_OR_AMD64 + #if SWAP2_DEFAULT_MODE == 0 + if (g_SwapBytes_Mode != 0) + SwapBytes2_128(items, lim); + else + #endif + #endif // FORCE_SWAP_MODE + DEFAULT_Swap2(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP2_16(0) + items++; + } +} + + +Z7_NO_INLINE +void z7_SwapBytes4(CSwapUInt32 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP4_32(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt32) - 1; + size_t numItems2 = numItems; + CSwapUInt32 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #else // MY_CPU_X86_OR_AMD64 + + if (g_SwapBytes_Mode != 0) + SwapBytes4_128(items, lim); + else + #endif // MY_CPU_X86_OR_AMD64 + #endif // FORCE_SWAP_MODE + DEFAULT_Swap4(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP4_32(0) + items++; + } +} + + +// #define SHOW_HW_STATUS + +#ifdef SHOW_HW_STATUS +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +void z7_SwapBytesPrepare(void) +{ +#ifndef FORCE_SWAP_MODE + unsigned mode = 0; // k_SwapBytes_Mode_BASE; + +#ifdef MY_CPU_ARM_OR_ARM64 + { + if (CPU_IsSupported_NEON()) + { + // #pragma message ("=== SwapBytes NEON") + PRF(printf("\n=== SwapBytes NEON\n");) + mode = k_SwapBytes_Mode_NEON; + } + } +#else // MY_CPU_ARM_OR_ARM64 + { + #ifdef USE_SWAP_AVX2 + if (CPU_IsSupported_AVX2()) + { + // #pragma message ("=== SwapBytes AVX2") + PRF(printf("\n=== SwapBytes AVX2\n");) + mode = k_SwapBytes_Mode_AVX2; + } + else + #endif + #ifdef USE_SWAP_SSSE3 + if (CPU_IsSupported_SSSE3()) + { + // #pragma message ("=== SwapBytes SSSE3") + PRF(printf("\n=== SwapBytes SSSE3\n");) + mode = k_SwapBytes_Mode_SSSE3; + } + else + #endif + #if !defined(MY_CPU_AMD64) + if (CPU_IsSupported_SSE2()) + #endif + { + // #pragma message ("=== SwapBytes SSE2") + PRF(printf("\n=== SwapBytes SSE2\n");) + mode = k_SwapBytes_Mode_SSE2; + } + } +#endif // MY_CPU_ARM_OR_ARM64 + g_SwapBytes_Mode = mode; + // g_SwapBytes_Mode = 0; // for debug +#endif // FORCE_SWAP_MODE + PRF(printf("\n=== SwapBytesPrepare\n");) +} + +#undef PRF diff -Nru 7zip-22.01+dfsg/C/SwapBytes.h 7zip-22.01+really25.01+dfsg/C/SwapBytes.h --- 7zip-22.01+dfsg/C/SwapBytes.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/SwapBytes.h 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,17 @@ +/* SwapBytes.h -- Byte Swap conversion filter +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SWAP_BYTES_H +#define ZIP7_INC_SWAP_BYTES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void z7_SwapBytes2(UInt16 *data, size_t numItems); +void z7_SwapBytes4(UInt32 *data, size_t numItems); +void z7_SwapBytesPrepare(void); + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/Threads.c 7zip-22.01+really25.01+dfsg/C/Threads.c --- 7zip-22.01+dfsg/C/Threads.c 2021-12-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Threads.c 2025-07-05 09:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Threads.c -- multithreading library -2021-12-21 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -11,9 +11,9 @@ #include "Threads.h" -static WRes GetError() +static WRes GetError(void) { - DWORD res = GetLastError(); + const DWORD res = GetLastError(); return res ? (WRes)res : 1; } @@ -59,6 +59,100 @@ return (res != 0 ? res : res2); } +typedef struct MY_PROCESSOR_NUMBER { + WORD Group; + BYTE Number; + BYTE Reserved; +} MY_PROCESSOR_NUMBER, *MY_PPROCESSOR_NUMBER; + +typedef struct MY_GROUP_AFFINITY { +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 100000) + // KAFFINITY is not defined in old mingw + ULONG_PTR +#else + KAFFINITY +#endif + Mask; + WORD Group; + WORD Reserved[3]; +} MY_GROUP_AFFINITY, *MY_PGROUP_AFFINITY; + +typedef BOOL (WINAPI *Func_SetThreadGroupAffinity)( + HANDLE hThread, + CONST MY_GROUP_AFFINITY *GroupAffinity, + MY_PGROUP_AFFINITY PreviousGroupAffinity); + +typedef BOOL (WINAPI *Func_GetThreadGroupAffinity)( + HANDLE hThread, + MY_PGROUP_AFFINITY GroupAffinity); + +typedef BOOL (WINAPI *Func_GetProcessGroupAffinity)( + HANDLE hProcess, + PUSHORT GroupCount, + PUSHORT GroupArray); + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +#if 0 +#include +#define PRF(x) x +/* +-- + before call of SetThreadGroupAffinity() + GetProcessGroupAffinity return one group. + after call of SetThreadGroupAffinity(): + GetProcessGroupAffinity return more than group, + if SetThreadGroupAffinity() was to another group. +-- + GetProcessAffinityMask MS DOCs: + { + If the calling process contains threads in multiple groups, + the function returns zero for both affinity masks. + } + but tests in win10 with 2 groups (less than 64 cores total): + GetProcessAffinityMask() still returns non-zero affinity masks + even after SetThreadGroupAffinity() calls. +*/ +static void PrintProcess_Info() +{ + { + const + Func_GetProcessGroupAffinity fn_GetProcessGroupAffinity = + (Func_GetProcessGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetProcessGroupAffinity"); + if (fn_GetProcessGroupAffinity) + { + unsigned i; + USHORT GroupCounts[64]; + USHORT GroupCount = Z7_ARRAY_SIZE(GroupCounts); + BOOL boolRes = fn_GetProcessGroupAffinity(GetCurrentProcess(), + &GroupCount, GroupCounts); + printf("\n====== GetProcessGroupAffinity : " + "boolRes=%u GroupCounts = %u :", + boolRes, (unsigned)GroupCount); + for (i = 0; i < GroupCount; i++) + printf(" %u", GroupCounts[i]); + printf("\n"); + } + } + { + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask)) + { + PRF(printf("\n====== GetProcessAffinityMask : " + ": processAffinityMask=%x, systemAffinityMask=%x\n", + (UInt32)processAffinityMask, (UInt32)systemAffinityMask);) + } + else + printf("\n==GetProcessAffinityMask FAIL"); + } +} +#else +#ifndef USE_THREADS_CreateThread +// #define PRF(x) +#endif +#endif + WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) { /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ @@ -72,7 +166,43 @@ unsigned threadId; *p = (HANDLE)(_beginthreadex(NULL, 0, func, param, 0, &threadId)); - + +#if 0 // 1 : for debug + { + DWORD_PTR prevMask; + DWORD_PTR affinity = 1 << 0; + prevMask = SetThreadAffinityMask(*p, (DWORD_PTR)affinity); + prevMask = prevMask; + } +#endif +#if 0 // 1 : for debug + { + /* win10: new thread will be created in same group that is assigned to parent thread + but affinity mask will contain all allowed threads of that group, + even if affinity mask of parent group is not full + win11: what group it will be created, if we have set + affinity of parent thread with ThreadGroupAffinity? + */ + const + Func_GetThreadGroupAffinity fn = + (Func_GetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetThreadGroupAffinity"); + if (fn) + { + // BOOL wres2; + MY_GROUP_AFFINITY groupAffinity; + memset(&groupAffinity, 0, sizeof(groupAffinity)); + /* wres2 = */ fn(*p, &groupAffinity); + PRF(printf("\n==Thread_Create cur = %6u GetThreadGroupAffinity(): " + "wres2_BOOL = %u, group=%u mask=%x\n", + GetCurrentThreadId(), + wres2, + groupAffinity.Group, + (UInt32)groupAffinity.Mask);) + } + } +#endif + #endif /* maybe we must use errno here, but probably GetLastError() is also OK. */ @@ -110,7 +240,84 @@ */ } { - DWORD prevSuspendCount = ResumeThread(h); + const DWORD prevSuspendCount = ResumeThread(h); + /* ResumeThread() returns: + 0 : was_not_suspended + 1 : was_resumed + -1 : error + */ + if (prevSuspendCount == (DWORD)-1) + wres = GetError(); + } + } + + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return wres; + + #endif +} + + +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask) +{ +#ifdef USE_THREADS_CreateThread + + UNUSED_VAR(group) + UNUSED_VAR(affinityMask) + return Thread_Create(p, func, param); + +#else + + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + HANDLE h; + WRes wres; + unsigned threadId; + h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId)); + *p = h; + wres = HandleToWRes(h); + if (h) + { + // PrintProcess_Info(); + { + const + Func_SetThreadGroupAffinity fn = + (Func_SetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "SetThreadGroupAffinity"); + if (fn) + { + // WRes wres2; + MY_GROUP_AFFINITY groupAffinity, prev_groupAffinity; + memset(&groupAffinity, 0, sizeof(groupAffinity)); + // groupAffinity.Mask must use only bits that supported by current group + // (groupAffinity.Mask = 0) means all allowed bits + groupAffinity.Mask = affinityMask; + groupAffinity.Group = (WORD)group; + // wres2 = + fn(h, &groupAffinity, &prev_groupAffinity); + /* + if (groupAffinity.Group == prev_groupAffinity.Group) + wres2 = wres2; + else + wres2 = wres2; + if (wres2 == 0) + { + wres2 = GetError(); + PRF(printf("\n==SetThreadGroupAffinity error: %u\n", wres2);) + } + else + { + PRF(printf("\n==Thread_Create_With_Group::SetThreadGroupAffinity()" + " threadId = %6u" + " group=%u mask=%x\n", + threadId, + prev_groupAffinity.Group, + (UInt32)prev_groupAffinity.Mask);) + } + */ + } + } + { + const DWORD prevSuspendCount = ResumeThread(h); /* ResumeThread() returns: 0 : was_not_suspended 1 : was_resumed @@ -173,6 +380,9 @@ Windows XP, 2003 : can raise a STATUS_NO_MEMORY exception Windows Vista+ : no exceptions */ #ifdef _MSC_VER + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wlanguage-extension-token" + #endif __try #endif { @@ -192,19 +402,26 @@ // ---------- POSIX ---------- -#ifndef __APPLE__ -#ifndef _7ZIP_AFFINITY_DISABLE +#if defined(__linux__) && !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) +#ifndef Z7_AFFINITY_DISABLE // _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET -#define _GNU_SOURCE -#endif -#endif +// clang < 3.6 : unknown warning group '-Wreserved-id-macro' +// clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier" +// clang >= 13 : do not give warning +#if !defined(_GNU_SOURCE) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #define _GNU_SOURCE +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif // !defined(_GNU_SOURCE) +#endif // Z7_AFFINITY_DISABLE +#endif // __linux__ #include "Threads.h" #include #include #include -#ifdef _7ZIP_AFFINITY_SUPPORTED +#ifdef Z7_AFFINITY_SUPPORTED // #include #endif @@ -212,15 +429,12 @@ // #include // #define PRF(p) p #define PRF(p) - -#define Print(s) PRF(printf("\n%s\n", s)) - -// #include +#define Print(s) PRF(printf("\n%s\n", s);) WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet) { // new thread in Posix probably inherits affinity from parrent thread - Print("Thread_Create_With_CpuSet"); + Print("Thread_Create_With_CpuSet") pthread_attr_t attr; int ret; @@ -228,7 +442,7 @@ p->_created = 0; - RINOK(pthread_attr_init(&attr)); + RINOK(pthread_attr_init(&attr)) ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); @@ -236,8 +450,9 @@ { if (cpuSet) { - #ifdef _7ZIP_AFFINITY_SUPPORTED - + // pthread_attr_setaffinity_np() is not supported for MUSL compile. + // so we check for __GLIBC__ here +#if defined(Z7_AFFINITY_SUPPORTED) && defined( __GLIBC__) /* printf("\n affinity :"); unsigned i; @@ -259,7 +474,7 @@ // ret2 = pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet); // if (ret2) ret = ret2; - #endif +#endif } ret = pthread_create(&p->_tid, &attr, func, param); @@ -289,10 +504,17 @@ return Thread_Create_With_CpuSet(p, func, param, NULL); } +/* +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinity) +{ + UNUSED_VAR(group) + return Thread_Create_With_Affinity(p, func, param, affinity); +} +*/ WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity) { - Print("Thread_Create_WithAffinity"); + Print("Thread_Create_WithAffinity") CCpuSet cs; unsigned i; CpuSet_Zero(&cs); @@ -312,7 +534,7 @@ WRes Thread_Close(CThread *p) { - // Print("Thread_Close"); + // Print("Thread_Close") int ret; if (!p->_created) return 0; @@ -326,7 +548,7 @@ WRes Thread_Wait_Close(CThread *p) { - // Print("Thread_Wait_Close"); + // Print("Thread_Wait_Close") void *thread_return; int ret; if (!p->_created) @@ -343,8 +565,8 @@ static WRes Event_Create(CEvent *p, int manualReset, int signaled) { - RINOK(pthread_mutex_init(&p->_mutex, NULL)); - RINOK(pthread_cond_init(&p->_cond, NULL)); + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) p->_manual_reset = manualReset; p->_state = (signaled ? True : False); p->_created = 1; @@ -361,25 +583,32 @@ { return AutoResetEvent_Create(p, 0); } +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) +// freebsd: +#pragma GCC diagnostic ignored "-Wthread-safety-analysis" +#endif + WRes Event_Set(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) p->_state = True; - int res1 = pthread_cond_broadcast(&p->_cond); - int res2 = pthread_mutex_unlock(&p->_mutex); - return (res2 ? res2 : res1); + { + const int res1 = pthread_cond_broadcast(&p->_cond); + const int res2 = pthread_mutex_unlock(&p->_mutex); + return (res2 ? res2 : res1); + } } WRes Event_Reset(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) p->_state = False; return pthread_mutex_unlock(&p->_mutex); } WRes Event_Wait(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) while (p->_state == False) { // ETIMEDOUT @@ -400,8 +629,8 @@ return 0; p->_created = 0; { - int res1 = pthread_mutex_destroy(&p->_mutex); - int res2 = pthread_cond_destroy(&p->_cond); + const int res1 = pthread_mutex_destroy(&p->_mutex); + const int res2 = pthread_cond_destroy(&p->_cond); return (res1 ? res1 : res2); } } @@ -411,8 +640,8 @@ { if (initCount > maxCount || maxCount < 1) return EINVAL; - RINOK(pthread_mutex_init(&p->_mutex, NULL)); - RINOK(pthread_cond_init(&p->_cond, NULL)); + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) p->_count = initCount; p->_maxCount = maxCount; p->_created = 1; @@ -448,7 +677,7 @@ if (releaseCount < 1) return EINVAL; - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) newCount = p->_count + releaseCount; if (newCount > p->_maxCount) @@ -458,13 +687,13 @@ p->_count = newCount; ret = pthread_cond_broadcast(&p->_cond); } - RINOK(pthread_mutex_unlock(&p->_mutex)); + RINOK(pthread_mutex_unlock(&p->_mutex)) return ret; } WRes Semaphore_Wait(CSemaphore *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) while (p->_count < 1) { pthread_cond_wait(&p->_cond, &p->_mutex); @@ -479,8 +708,8 @@ return 0; p->_created = 0; { - int res1 = pthread_mutex_destroy(&p->_mutex); - int res2 = pthread_cond_destroy(&p->_cond); + const int res1 = pthread_mutex_destroy(&p->_mutex); + const int res2 = pthread_cond_destroy(&p->_cond); return (res1 ? res1 : res2); } } @@ -489,7 +718,7 @@ WRes CriticalSection_Init(CCriticalSection *p) { - // Print("CriticalSection_Init"); + // Print("CriticalSection_Init") if (!p) return EINTR; return pthread_mutex_init(&p->_mutex, NULL); @@ -497,7 +726,7 @@ void CriticalSection_Enter(CCriticalSection *p) { - // Print("CriticalSection_Enter"); + // Print("CriticalSection_Enter") if (p) { // int ret = @@ -507,7 +736,7 @@ void CriticalSection_Leave(CCriticalSection *p) { - // Print("CriticalSection_Leave"); + // Print("CriticalSection_Leave") if (p) { // int ret = @@ -517,7 +746,7 @@ void CriticalSection_Delete(CCriticalSection *p) { - // Print("CriticalSection_Delete"); + // Print("CriticalSection_Delete") if (p) { // int ret = @@ -527,14 +756,57 @@ LONG InterlockedIncrement(LONG volatile *addend) { - // Print("InterlockedIncrement"); + // Print("InterlockedIncrement") #ifdef USE_HACK_UNSAFE_ATOMIC LONG val = *addend + 1; *addend = val; return val; #else + + #if defined(__clang__) && (__clang_major__ >= 8) + #pragma GCC diagnostic ignored "-Watomic-implicit-seq-cst" + #endif return __sync_add_and_fetch(addend, 1); #endif } +LONG InterlockedDecrement(LONG volatile *addend) +{ + // Print("InterlockedDecrement") + #ifdef USE_HACK_UNSAFE_ATOMIC + LONG val = *addend - 1; + *addend = val; + return val; + #else + return __sync_sub_and_fetch(addend, 1); + #endif +} + #endif // _WIN32 + +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p) +{ + if (Event_IsCreated(p)) + return Event_Reset(p); + return AutoResetEvent_CreateNotSignaled(p); +} + +void ThreadNextGroup_Init(CThreadNextGroup *p, UInt32 numGroups, UInt32 startGroup) +{ + // printf("\n====== ThreadNextGroup_Init numGroups = %x: startGroup=%x\n", numGroups, startGroup); + if (numGroups == 0) + numGroups = 1; + p->NumGroups = numGroups; + p->NextGroup = startGroup % numGroups; +} + + +UInt32 ThreadNextGroup_GetNext(CThreadNextGroup *p) +{ + const UInt32 next = p->NextGroup; + p->NextGroup = (next + 1) % p->NumGroups; + return next; +} + +#undef PRF +#undef Print diff -Nru 7zip-22.01+dfsg/C/Threads.h 7zip-22.01+really25.01+dfsg/C/Threads.h --- 7zip-22.01+dfsg/C/Threads.h 2021-12-21 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Threads.h 2025-06-30 14:00:00.000000000 +0000 @@ -1,19 +1,29 @@ /* Threads.h -- multithreading library -2021-12-21 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __7Z_THREADS_H -#define __7Z_THREADS_H +#ifndef ZIP7_INC_THREADS_H +#define ZIP7_INC_THREADS_H #ifdef _WIN32 -#include +#include "7zWindows.h" + #else +#include "Compiler.h" + +// #define Z7_AFFINITY_DISABLE #if defined(__linux__) #if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) -#ifndef _7ZIP_AFFINITY_DISABLE -#define _7ZIP_AFFINITY_SUPPORTED -// #pragma message(" ==== _7ZIP_AFFINITY_SUPPORTED") -// #define _GNU_SOURCE +#ifndef Z7_AFFINITY_DISABLE +#define Z7_AFFINITY_SUPPORTED +// #pragma message(" ==== Z7_AFFINITY_SUPPORTED") +#if !defined(_GNU_SOURCE) +// #pragma message(" ==== _GNU_SOURCE set") +// we need _GNU_SOURCE for cpu_set_t, if we compile for MUSL +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _GNU_SOURCE +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif #endif #endif #endif @@ -33,7 +43,7 @@ typedef HANDLE CThread; -#define Thread_Construct(p) { *(p) = NULL; } +#define Thread_CONSTRUCT(p) { *(p) = NULL; } #define Thread_WasCreated(p) (*(p) != NULL) #define Thread_Close(p) HandlePtr_Close(p) // #define Thread_Wait(p) Handle_WaitObject(*(p)) @@ -52,42 +62,46 @@ #endif THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_RET_ZERO 0 + typedef DWORD_PTR CAffinityMask; typedef DWORD_PTR CCpuSet; -#define CpuSet_Zero(p) { *(p) = 0; } -#define CpuSet_Set(p, cpu) { *(p) |= ((DWORD_PTR)1 << (cpu)); } +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((DWORD_PTR)1 << (cpu)) #else // _WIN32 -typedef struct _CThread +typedef struct { pthread_t _tid; int _created; } CThread; -#define Thread_Construct(p) { (p)->_tid = 0; (p)->_created = 0; } -#define Thread_WasCreated(p) ((p)->_created != 0) +#define Thread_CONSTRUCT(p) { (p)->_tid = 0; (p)->_created = 0; } +#define Thread_WasCreated(p) ((p)->_created != 0) WRes Thread_Close(CThread *p); // #define Thread_Wait Thread_Wait_Close typedef void * THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_RET_ZERO NULL + typedef UInt64 CAffinityMask; -#ifdef _7ZIP_AFFINITY_SUPPORTED +#ifdef Z7_AFFINITY_SUPPORTED typedef cpu_set_t CCpuSet; -#define CpuSet_Zero(p) CPU_ZERO(p) -#define CpuSet_Set(p, cpu) CPU_SET(cpu, p) -#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p) +#define CpuSet_Zero(p) CPU_ZERO(p) +#define CpuSet_Set(p, cpu) CPU_SET(cpu, p) +#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p) #else typedef UInt64 CCpuSet; -#define CpuSet_Zero(p) { *(p) = 0; } -#define CpuSet_Set(p, cpu) { *(p) |= ((UInt64)1 << (cpu)); } -#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0) +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((UInt64)1 << (cpu)) +#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0) #endif @@ -95,7 +109,7 @@ #endif // _WIN32 -#define THREAD_FUNC_CALL_TYPE MY_STD_CALL +#define THREAD_FUNC_CALL_TYPE Z7_STDCALL #if defined(_WIN32) && defined(__GNUC__) /* GCC compiler for x86 32-bit uses the rule: @@ -126,12 +140,22 @@ WRes Thread_Wait_Close(CThread *p); #ifdef _WIN32 +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask); #define Thread_Create_With_CpuSet(p, func, param, cs) \ Thread_Create_With_Affinity(p, func, param, *cs) #else WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet); #endif +typedef struct +{ + unsigned NumGroups; + unsigned NextGroup; +} CThreadNextGroup; + +void ThreadNextGroup_Init(CThreadNextGroup *p, unsigned numGroups, unsigned startGroup); +unsigned ThreadNextGroup_GetNext(CThreadNextGroup *p); + #ifdef _WIN32 @@ -168,7 +192,7 @@ #else // _WIN32 -typedef struct _CEvent +typedef struct { int _created; int _manual_reset; @@ -187,13 +211,14 @@ WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); + WRes Event_Set(CEvent *p); WRes Event_Reset(CEvent *p); WRes Event_Wait(CEvent *p); WRes Event_Close(CEvent *p); -typedef struct _CSemaphore +typedef struct { int _created; UInt32 _count; @@ -213,7 +238,7 @@ WRes Semaphore_Close(CSemaphore *p); -typedef struct _CCriticalSection +typedef struct { pthread_mutex_t _mutex; } CCriticalSection; @@ -224,9 +249,12 @@ void CriticalSection_Leave(CCriticalSection *cs); LONG InterlockedIncrement(LONG volatile *addend); +LONG InterlockedDecrement(LONG volatile *addend); #endif // _WIN32 +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p); + EXTERN_C_END #endif diff -Nru 7zip-22.01+dfsg/C/Util/7z/7z.dsp 7zip-22.01+really25.01+dfsg/C/Util/7z/7z.dsp --- 7zip-22.01+dfsg/C/Util/7z/7z.dsp 2015-06-10 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7z/7z.dsp 2024-01-26 14:00:00.000000000 +0000 @@ -42,7 +42,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c +# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "Z7_PPMD_SUPPORT" /D "Z7_EXTRACT_ONLY" /FAcs /Yu"Precomp.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c +# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "Z7_PPMD_SUPPORT" /D "Z7_EXTRACT_ONLY" /Yu"Precomp.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -145,6 +145,10 @@ # End Source File # Begin Source File +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\Bcj2.c # End Source File # Begin Source File @@ -230,6 +234,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + SOURCE=.\Precomp.h # End Source File # End Group diff -Nru 7zip-22.01+dfsg/C/Util/7z/7zMain.c 7zip-22.01+really25.01+dfsg/C/Util/7z/7zMain.c --- 7zip-22.01+dfsg/C/Util/7z/7zMain.c 2021-04-29 11:46:20.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7z/7zMain.c 2024-02-28 16:00:00.000000000 +0000 @@ -1,20 +1,11 @@ /* 7zMain.c - Test application for 7z Decoder -2021-04-29 : Igor Pavlov : Public domain */ +2024-02-28 : Igor Pavlov : Public domain */ #include "Precomp.h" #include #include -#include "../../CpuArch.h" - -#include "../../7z.h" -#include "../../7zAlloc.h" -#include "../../7zBuf.h" -#include "../../7zCrc.h" -#include "../../7zFile.h" -#include "../../7zVersion.h" - #ifndef USE_WINDOWS_FILE /* for mkdir */ #ifdef _WIN32 @@ -32,10 +23,19 @@ #endif #endif +#include "../../7zFile.h" +#include "../../7z.h" +#include "../../7zAlloc.h" +#include "../../7zBuf.h" +#include "../../7zCrc.h" +#include "../../7zVersion.h" + +#include "../../CpuArch.h" #define kInputBufSize ((size_t)1 << 18) static const ISzAlloc g_Alloc = { SzAlloc, SzFree }; +// static const ISzAlloc g_Alloc_temp = { SzAllocTemp, SzFreeTemp }; static void Print(const char *s) @@ -53,19 +53,19 @@ } #ifndef _WIN32 -#define _USE_UTF8 +#define MY_USE_UTF8 #endif -/* #define _USE_UTF8 */ +/* #define MY_USE_UTF8 */ -#ifdef _USE_UTF8 +#ifdef MY_USE_UTF8 -#define _UTF8_START(n) (0x100 - (1 << (7 - (n)))) +#define MY_UTF8_START(n) (0x100 - (1 << (7 - (n)))) -#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) +#define MY_UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) -#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n))))) -#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F))) +#define MY_UTF8_HEAD(n, val) ((Byte)(MY_UTF8_START(n) + (val >> (6 * (n))))) +#define MY_UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F))) static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim) { @@ -82,7 +82,7 @@ if (val < 0x80) continue; - if (val < _UTF8_RANGE(1)) + if (val < MY_UTF8_RANGE(1)) { size++; continue; @@ -90,7 +90,7 @@ if (val >= 0xD800 && val < 0xDC00 && src != srcLim) { - UInt32 c2 = *src; + const UInt32 c2 = *src; if (c2 >= 0xDC00 && c2 < 0xE000) { src++; @@ -119,33 +119,33 @@ continue; } - if (val < _UTF8_RANGE(1)) + if (val < MY_UTF8_RANGE(1)) { - dest[0] = _UTF8_HEAD(1, val); - dest[1] = _UTF8_CHAR(0, val); + dest[0] = MY_UTF8_HEAD(1, val); + dest[1] = MY_UTF8_CHAR(0, val); dest += 2; continue; } if (val >= 0xD800 && val < 0xDC00 && src != srcLim) { - UInt32 c2 = *src; + const UInt32 c2 = *src; if (c2 >= 0xDC00 && c2 < 0xE000) { src++; val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; - dest[0] = _UTF8_HEAD(3, val); - dest[1] = _UTF8_CHAR(2, val); - dest[2] = _UTF8_CHAR(1, val); - dest[3] = _UTF8_CHAR(0, val); + dest[0] = MY_UTF8_HEAD(3, val); + dest[1] = MY_UTF8_CHAR(2, val); + dest[2] = MY_UTF8_CHAR(1, val); + dest[3] = MY_UTF8_CHAR(0, val); dest += 4; continue; } } - dest[0] = _UTF8_HEAD(2, val); - dest[1] = _UTF8_CHAR(1, val); - dest[2] = _UTF8_CHAR(0, val); + dest[0] = MY_UTF8_HEAD(2, val); + dest[1] = MY_UTF8_CHAR(1, val); + dest[2] = MY_UTF8_CHAR(0, val); dest += 3; } } @@ -163,17 +163,17 @@ #endif static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s - #ifndef _USE_UTF8 + #ifndef MY_USE_UTF8 , UINT codePage #endif ) { - unsigned len = 0; + size_t len = 0; for (len = 0; s[len] != 0; len++) {} - #ifndef _USE_UTF8 + #ifndef MY_USE_UTF8 { - const unsigned size = len * 3 + 100; + const size_t size = len * 3 + 100; if (!Buf_EnsureSize(buf, size)) return SZ_ERROR_MEM; { @@ -216,7 +216,7 @@ CBuf buf; WRes res; Buf_Init(&buf); - RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) res = #ifdef _WIN32 @@ -239,7 +239,7 @@ CBuf buf; WRes res; Buf_Init(&buf); - RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) res = OutFile_Open(p, (const char *)buf.data); Buf_Free(&buf, &g_Alloc); return res; @@ -253,7 +253,7 @@ SRes res; Buf_Init(&buf); res = Utf16_To_Char(&buf, s - #ifndef _USE_UTF8 + #ifndef MY_USE_UTF8 , CP_OEMCP #endif ); @@ -320,21 +320,20 @@ // typedef long BOOL; typedef int BOOL; -typedef struct _FILETIME +typedef struct { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; -static LONG TIME_GetBias() +static LONG TIME_GetBias(void) { - time_t utc = time(NULL); + const time_t utc = time(NULL); struct tm *ptm = localtime(&utc); - int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ + const int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ ptm = gmtime(&utc); ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ - LONG bias = (int)(mktime(ptm)-utc); - return bias; + return (int)(mktime(ptm) - utc); } #define TICKS_PER_SEC 10000000 @@ -352,19 +351,19 @@ { UInt64 v = GET_TIME_64(fileTime); v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC); - SET_FILETIME(localFileTime, v); + SET_FILETIME(localFileTime, v) return TRUE; } static const UInt32 kNumTimeQuantumsInSecond = 10000000; static const UInt32 kFileTimeStartYear = 1601; static const UInt32 kUnixTimeStartYear = 1970; -static const UInt64 kUnixTimeOffset = - (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); static Int64 Time_FileTimeToUnixTime64(const FILETIME *ft) { - UInt64 winTime = GET_TIME_64(ft); + const UInt64 kUnixTimeOffset = + (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); + const UInt64 winTime = GET_TIME_64(ft); return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset; } @@ -384,8 +383,10 @@ if (sec2 == sec) { ts->tv_sec = sec2; - UInt64 winTime = GET_TIME_64(ft); - ts->tv_nsec = (long)((winTime % 10000000) * 100);; + { + const UInt64 winTime = GET_TIME_64(ft); + ts->tv_nsec = (long)((winTime % 10000000) * 100); + } return; } } @@ -407,7 +408,7 @@ CBuf buf; int res; Buf_Init(&buf); - RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) FILETIME_To_timespec(NULL, ×[0]); FILETIME_To_timespec(mTime, ×[1]); res = utimensat(AT_FDCWD, (const char *)buf.data, times, flags); @@ -429,7 +430,7 @@ { unsigned year, mon, hour, min, sec; Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - unsigned t; + UInt32 t; UInt32 v; // UInt64 v64 = nt->Low | ((UInt64)nt->High << 32); UInt64 v64; @@ -461,7 +462,7 @@ ms[1] = 29; for (mon = 0;; mon++) { - unsigned d = ms[mon]; + const UInt32 d = ms[mon]; if (v < d) break; v -= d; @@ -474,7 +475,7 @@ UIntToStr_2(s, sec); s[2] = 0; } -static void PrintLF() +static void PrintLF(void) { Print("\n"); } @@ -541,7 +542,7 @@ // #define NUM_PARENTS_MAX 128 -int MY_CDECL main(int numargs, char *args[]) +int Z7_CDECL main(int numargs, char *args[]) { ISzAlloc allocImp; ISzAlloc allocTempImp; @@ -581,6 +582,7 @@ allocImp = g_Alloc; allocTempImp = g_Alloc; + // allocTempImp = g_Alloc_temp; { WRes wres = @@ -611,7 +613,7 @@ { lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; - LookToRead2_Init(&lookStream); + LookToRead2_INIT(&lookStream) } } @@ -767,7 +769,7 @@ } else { - WRes wres = OutFile_OpenUtf16(&outFile, destPath); + const WRes wres = OutFile_OpenUtf16(&outFile, destPath); if (wres != 0) { PrintError_WRes("cannot open output file", wres); @@ -779,7 +781,7 @@ processedSize = outSizeProcessed; { - WRes wres = File_Write(&outFile, outBuffer + offset, &processedSize); + const WRes wres = File_Write(&outFile, outBuffer + offset, &processedSize); if (wres != 0 || processedSize != outSizeProcessed) { PrintError_WRes("cannot write output file", wres); @@ -819,7 +821,7 @@ #endif { - WRes wres = File_Close(&outFile); + const WRes wres = File_Close(&outFile); if (wres != 0) { PrintError_WRes("cannot close output file", wres); diff -Nru 7zip-22.01+dfsg/C/Util/7z/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/7z/Precomp.h --- 7zip-22.01+dfsg/C/Util/7z/Precomp.h 2014-06-16 06:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7z/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -1,10 +1,13 @@ -/* Precomp.h -- StdAfx -2013-06-16 : Igor Pavlov : Public domain */ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "../../Compiler.h" -#include "../../7zTypes.h" +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif + +#include "../../Precomp.h" + +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/7z/makefile 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile --- 7zip-22.01+dfsg/C/Util/7z/makefile 2015-06-10 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile 2024-03-21 09:00:00.000000000 +0000 @@ -1,12 +1,10 @@ -CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT +CFLAGS = $(CFLAGS) -DZ7_PPMD_SUPPORT -DZ7_EXTRACT_ONLY PROG = 7zDec.exe C_OBJS = \ $O\7zAlloc.obj \ $O\7zBuf.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ $O\7zFile.obj \ $O\7zDec.obj \ $O\7zArcIn.obj \ @@ -25,10 +23,14 @@ 7Z_OBJS = \ $O\7zMain.obj \ +!include "../../../CPP/7zip/Crc.mak" +!include "../../../CPP/7zip/LzmaDec.mak" + OBJS = \ $O\Precomp.obj \ $(7Z_OBJS) \ $(C_OBJS) \ + $(ASM_OBJS) \ !include "../../../CPP/Build.mak" @@ -38,3 +40,5 @@ $(CCOMPL_USE) $O\Precomp.obj: Precomp.c $(CCOMPL_PCH) + +!include "../../Asm_c.mak" diff -Nru 7zip-22.01+dfsg/C/Util/7z/makefile.gcc 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile.gcc --- 7zip-22.01+dfsg/C/Util/7z/makefile.gcc 2021-04-29 12:13:06.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7z/makefile.gcc 2023-03-02 16:00:00.000000000 +0000 @@ -1,6 +1,6 @@ PROG = 7zdec -LOCAL_FLAGS = -D_7ZIP_PPMD_SUPPPORT +LOCAL_FLAGS = -DZ7_PPMD_SUPPORT -DZ7_EXTRACT_ONLY include ../../../CPP/7zip/LzmaDec_gcc.mak @@ -19,8 +19,6 @@ $O/Ppmd7Dec.o \ $O/7zCrc.o \ $O/7zCrcOpt.o \ - $O/Sha256.o \ - $O/Sha256Opt.o \ $O/7zAlloc.o \ $O/7zArcIn.o \ $O/7zBuf.o \ diff -Nru 7zip-22.01+dfsg/C/Util/7zipInstall/7zipInstall.c 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.c --- 7zip-22.01+dfsg/C/Util/7zipInstall/7zipInstall.c 2022-07-15 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.c 2024-04-05 03:00:00.000000000 +0000 @@ -1,16 +1,33 @@ /* 7zipInstall.c - 7-Zip Installer -2022-07-15 : Igor Pavlov : Public domain */ +2024-04-05 : Igor Pavlov : Public domain */ #include "Precomp.h" #define SZ_ERROR_ABORT 100 -#ifdef _MSC_VER +#include "../../7zWindows.h" + +#if defined(_MSC_VER) && _MSC_VER < 1600 #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union #endif -#include +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +#ifdef Z7_OLD_WIN_SDK +struct IShellView; +#define SHFOLDERAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE +SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +typedef enum { + SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists + SHGFP_TYPE_DEFAULT = 1, // default value, may not exist +} SHGFP_TYPE; +#endif +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else #include +#endif #include "../../7z.h" #include "../../7zAlloc.h" @@ -22,40 +39,36 @@ #include "resource.h" -#if defined(__GNUC__) && (__GNUC__ >= 8) - #pragma GCC diagnostic ignored "-Wcast-function-type" +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" #endif #define LLL_(quote) L##quote #define LLL(quote) LLL_(quote) -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - #define wcscat lstrcatW -#define wcslen lstrlenW +#define wcslen (size_t)lstrlenW #define wcscpy lstrcpyW // wcsncpy() and lstrcpynW() work differently. We don't use them. - #define kInputBufSize ((size_t)1 << 18) - -#define _7ZIP_CUR_VER ((MY_VER_MAJOR << 16) | MY_VER_MINOR) -#define _7ZIP_DLL_VER_COMPAT ((16 << 16) | 3) +#define Z7_7ZIP_CUR_VER ((MY_VER_MAJOR << 16) | MY_VER_MINOR) +#define Z7_7ZIP_DLL_VER_COMPAT ((16 << 16) | 3) static LPCSTR const k_7zip = "7-Zip"; static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip"; -// #define _64BIT_INSTALLER 1 +// #define Z7_64BIT_INSTALLER 1 #ifdef _WIN64 - #define _64BIT_INSTALLER 1 + #define Z7_64BIT_INSTALLER 1 #endif #define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION) -#ifdef _64BIT_INSTALLER +#ifdef Z7_64BIT_INSTALLER // #define USE_7ZIP_32_DLL @@ -84,24 +97,26 @@ static LPCWSTR const k_Reg_Path = L"Path"; static LPCWSTR const k_Reg_Path32 = L"Path" - #ifdef _64BIT_INSTALLER + #ifdef Z7_64BIT_INSTALLER L"64" #else L"32" #endif ; -#if defined(_64BIT_INSTALLER) && !defined(_WIN64) +#if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) #define k_Reg_WOW_Flag KEY_WOW64_64KEY #else #define k_Reg_WOW_Flag 0 #endif +#ifdef USE_7ZIP_32_DLL #ifdef _WIN64 #define k_Reg_WOW_Flag_32 KEY_WOW64_32KEY #else #define k_Reg_WOW_Flag_32 0 #endif +#endif #define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}" @@ -126,8 +141,6 @@ static WCHAR path[MAX_PATH * 2 + 40]; -// #define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c))) - static void CpyAscii(wchar_t *dest, const char *s) { @@ -200,9 +213,12 @@ return 0; } - my_GetFileVersionInfoSizeW = (Func_GetFileVersionInfoSizeW)GetProcAddress(g_version_dll_hModule, "GetFileVersionInfoSizeW"); - my_GetFileVersionInfoW = (Func_GetFileVersionInfoW)GetProcAddress(g_version_dll_hModule, "GetFileVersionInfoW"); - my_VerQueryValueW = (Func_VerQueryValueW)GetProcAddress(g_version_dll_hModule, "VerQueryValueW"); + my_GetFileVersionInfoSizeW = (Func_GetFileVersionInfoSizeW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "GetFileVersionInfoSizeW"); + my_GetFileVersionInfoW = (Func_GetFileVersionInfoW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "GetFileVersionInfoW"); + my_VerQueryValueW = (Func_VerQueryValueW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "VerQueryValueW"); if (!my_GetFileVersionInfoSizeW || !my_GetFileVersionInfoW @@ -253,7 +269,7 @@ } } -static WRes CreateComplexDir() +static WRes CreateComplexDir(void) { WCHAR s[MAX_PATH + 10]; @@ -287,7 +303,7 @@ { size_t len = wcslen(s); { - int pos = ReverseFind_PathSepar(s); + const int pos = ReverseFind_PathSepar(s); if (pos < 0) return wres; if ((unsigned)pos < prefixSize) @@ -297,7 +313,7 @@ if (len == 1) return 0; s[pos] = 0; - len = pos; + len = (unsigned)pos; } } @@ -309,7 +325,7 @@ break; if (wres == ERROR_ALREADY_EXISTS) { - DWORD attrib = GetFileAttributesW(s); + const DWORD attrib = GetFileAttributesW(s); if (attrib != INVALID_FILE_ATTRIBUTES) if ((attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) return ERROR_ALREADY_EXISTS; @@ -323,7 +339,7 @@ for (;;) { - size_t pos = wcslen(s); + const size_t pos = wcslen(s); if (pos >= len) return 0; s[pos] = CHAR_PATH_SEPARATOR; @@ -339,7 +355,7 @@ { DWORD cnt = MAX_PATH * sizeof(name[0]); DWORD type = 0; - LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, (DWORD *)&cnt); + const LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, &cnt); if (type != REG_SZ) return False; return res == ERROR_SUCCESS; @@ -348,11 +364,11 @@ static int MyRegistry_QueryString2(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) { HKEY key = 0; - LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); if (res != ERROR_SUCCESS) return False; { - BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); RegCloseKey(key); return res2; } @@ -550,7 +566,7 @@ for (;; i++) { - wchar_t c = s[i]; + const wchar_t c = s[i]; if (c == 0) break; if (c == '/') @@ -587,7 +603,7 @@ return NULL; for (i = 0;; i++) { - Byte b = s2[i]; + const char b = s2[i]; if (b == 0) return s1; if (MyWCharLower_Ascii(s1[i]) != (Byte)MyCharLower_Ascii(b)) @@ -610,7 +626,7 @@ static int Install(void); -static void OnClose() +static void OnClose(void) { if (g_Install_was_Pressed && !g_Finished) { @@ -624,7 +640,13 @@ g_HWND = NULL; } -static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { // UNUSED_VAR(hwnd) UNUSED_VAR(lParam) @@ -730,7 +752,7 @@ return res; } -static void SetRegKey_Path() +static void SetRegKey_Path(void) { SetRegKey_Path2(HKEY_CURRENT_USER); SetRegKey_Path2(HKEY_LOCAL_MACHINE); @@ -828,7 +850,7 @@ static LPCWSTR const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; static LPCWSTR const k_7zip_ShellExtension = L"7-Zip Shell Extension"; -static void WriteCLSID() +static void WriteCLSID(void) { HKEY destKey; LONG res; @@ -879,12 +901,12 @@ , "Drive\\shellex\\DragDropHandlers" }; -static void WriteShellEx() +static void WriteShellEx(void) { unsigned i; WCHAR destPath[MAX_PATH + 40]; - for (i = 0; i < ARRAY_SIZE(k_ShellEx_Items); i++) + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) { CpyAscii(destPath, k_ShellEx_Items[i]); CatAscii(destPath, "\\7-Zip"); @@ -968,7 +990,7 @@ quoteMode = !quoteMode; continue; } - if (pos >= ARRAY_SIZE(cmd) - 1) + if (pos >= Z7_ARRAY_SIZE(cmd) - 1) exit(1); cmd[pos++] = c; } @@ -1026,7 +1048,7 @@ for (;;) { { - wchar_t c = *s; + const wchar_t c = *s; if (c == 0) break; if (c == ' ') @@ -1070,11 +1092,12 @@ } } - #if defined(_64BIT_INSTALLER) && !defined(_WIN64) + #if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) { BOOL isWow64 = FALSE; - Func_IsWow64Process func_IsWow64Process = (Func_IsWow64Process) - GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process"); + const Func_IsWow64Process func_IsWow64Process = (Func_IsWow64Process) + Z7_CAST_FUNC_C GetProcAddress(GetModuleHandleW(L"kernel32.dll"), + "IsWow64Process"); if (func_IsWow64Process) func_IsWow64Process(GetCurrentProcess(), &isWow64); @@ -1082,7 +1105,13 @@ if (!isWow64) { if (!g_SilentMode) - PrintErrorMessage("This installation requires Windows " MY_CPU_NAME, NULL); + PrintErrorMessage("This installation requires Windows " + #ifdef MY_CPU_X86_OR_AMD64 + "x64" + #else + "64-bit" + #endif + , NULL); return 1; } } @@ -1093,7 +1122,7 @@ { HKEY key = 0; BoolInt ok = False; - LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, k_Reg_Software_7zip, 0, KEY_READ | k_Reg_WOW_Flag, &key); + const LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, k_Reg_Software_7zip, 0, KEY_READ | k_Reg_WOW_Flag, &key); if (res == ERROR_SUCCESS) { ok = MyRegistry_QueryString(key, k_Reg_Path32, path); @@ -1109,7 +1138,7 @@ CpyAscii(path, "\\Program Files\\"); #else - #ifdef _64BIT_INSTALLER + #ifdef Z7_64BIT_INSTALLER { DWORD ttt = GetEnvironmentVariableW(L"ProgramW6432", path, MAX_PATH); if (ttt == 0 || ttt > MAX_PATH) @@ -1150,7 +1179,7 @@ return 1; { - HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); + const HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); // SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); } @@ -1244,7 +1273,7 @@ allocTempImp.Free = SzFreeTemp; { - DWORD len = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); + const DWORD len = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); if (len == 0 || len > MAX_PATH) return 1; } @@ -1286,7 +1315,7 @@ for (;;) { - wchar_t c = path[i++]; + const wchar_t c = path[i++]; if (c == 0) break; if (c != ' ') @@ -1318,7 +1347,7 @@ { lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; - LookToRead2_Init(&lookStream); + LookToRead2_INIT(&lookStream) } } @@ -1372,7 +1401,7 @@ } { - size_t len = SzArEx_GetFileNameUtf16(&db, i, NULL); + const size_t len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len >= MAX_PATH) { res = SZ_ERROR_FAIL; @@ -1468,8 +1497,8 @@ #endif ) { - DWORD ver = GetFileVersion(path); - fileLevel = ((ver < _7ZIP_DLL_VER_COMPAT || ver > _7ZIP_CUR_VER) ? 2 : 1); + const DWORD ver = GetFileVersion(path); + fileLevel = ((ver < Z7_7ZIP_DLL_VER_COMPAT || ver > Z7_7ZIP_CUR_VER) ? 2 : 1); tempIndex++; continue; } @@ -1537,7 +1566,7 @@ #endif { - SRes winRes2 = File_Close(&outFile); + const WRes winRes2 = File_Close(&outFile); if (res != SZ_OK) break; if (winRes2 != 0) diff -Nru 7zip-22.01+dfsg/C/Util/7zipInstall/7zipInstall.dsp 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.dsp --- 7zip-22.01+dfsg/C/Util/7zipInstall/7zipInstall.dsp 2017-04-04 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/7zipInstall.dsp 2023-04-04 10:00:00.000000000 +0000 @@ -152,6 +152,10 @@ # End Source File # Begin Source File +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\Bcj2.c # End Source File # Begin Source File @@ -220,6 +224,10 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + SOURCE=.\Precomp.c # ADD CPP /Yc"Precomp.h" # End Source File diff -Nru 7zip-22.01+dfsg/C/Util/7zipInstall/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/Precomp.h --- 7zip-22.01+dfsg/C/Util/7zipInstall/Precomp.h 2015-05-24 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -1,11 +1,13 @@ -/* Precomp.h -- StdAfx -2015-05-24 : Igor Pavlov : Public domain */ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H -#include "../../Compiler.h" +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif -#include "../../7zTypes.h" +#include "../../Precomp.h" -#endif +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/7zipInstall/makefile 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/makefile --- 7zip-22.01+dfsg/C/Util/7zipInstall/makefile 2019-02-19 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/makefile 2024-04-29 15:00:00.000000000 +0000 @@ -1,15 +1,16 @@ PROG = 7zipInstall.exe MY_FIXED = 1 -!IFDEF _64BIT_INSTALLER -CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER +!IFDEF Z7_64BIT_INSTALLER +CFLAGS = $(CFLAGS) -DZ7_64BIT_INSTALLER !ENDIF -CFLAGS = $(CFLAGS) -D_LZMA_SIZE_OPT - CFLAGS = $(CFLAGS) \ - -D_7Z_NO_METHOD_LZMA2 \ - -D_7Z_NO_METHODS_FILTERS + -DZ7_LZMA_SIZE_OPT \ + -DZ7_NO_METHOD_LZMA2 \ + -DZ7_NO_METHODS_FILTERS \ + -DZ7_USE_NATIVE_BRANCH_FILTER \ + -DZ7_EXTRACT_ONLY \ MAIN_OBJS = \ $O\7zipInstall.obj \ @@ -18,13 +19,11 @@ $O\7zAlloc.obj \ $O\7zArcIn.obj \ $O\7zBuf.obj \ - $O\7zBuf2.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ $O\7zFile.obj \ $O\7zDec.obj \ $O\7zStream.obj \ $O\Bcj2.obj \ + $O\Bra.obj \ $O\CpuArch.obj \ $O\DllSecur.obj \ $O\LzmaDec.obj \ @@ -32,11 +31,17 @@ OBJS = \ $(MAIN_OBJS) \ $(C_OBJS) \ + $(ASM_OBJS) \ $O\resource.res +!include "../../../CPP/7zip/Crc.mak" +# !include "../../../CPP/7zip/LzmaDec.mak" + !include "../../../CPP/Build.mak" $(MAIN_OBJS): $(*B).c $(COMPL_O1) $(C_OBJS): ../../$(*B).c $(COMPL_O1) + +!include "../../Asm_c.mak" diff -Nru 7zip-22.01+dfsg/C/Util/7zipInstall/resource.rc 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/resource.rc --- 7zip-22.01+dfsg/C/Util/7zipInstall/resource.rc 2015-06-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipInstall/resource.rc 2024-03-21 07:00:00.000000000 +0000 @@ -1,5 +1,6 @@ -#include -#include +#include +// #include +// #include #include #define USE_COPYRIGHT_CR diff -Nru 7zip-22.01+dfsg/C/Util/7zipUninstall/7zipUninstall.c 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.c --- 7zip-22.01+dfsg/C/Util/7zipUninstall/7zipUninstall.c 2022-07-15 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.c 2024-03-21 10:00:00.000000000 +0000 @@ -1,42 +1,58 @@ /* 7zipUninstall.c - 7-Zip Uninstaller -2022-07-15 : Igor Pavlov : Public domain */ +2024-03-21 : Igor Pavlov : Public domain */ #include "Precomp.h" -#ifdef _MSC_VER +// #define SZ_ERROR_ABORT 100 + +#include "../../7zTypes.h" +#include "../../7zWindows.h" + +#if defined(_MSC_VER) && _MSC_VER < 1600 #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -#pragma warning(disable : 4011) // vs2010: identifier truncated to _CRT_SECURE_CPP_OVERLOAD_SECURE #endif -// #define SZ_ERROR_ABORT 100 - -#include +#ifdef Z7_OLD_WIN_SDK +struct IShellView; +#define SHFOLDERAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE +SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +typedef enum { + SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists + SHGFP_TYPE_DEFAULT = 1, // default value, may not exist +} SHGFP_TYPE; +#endif +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else #include +#endif #include "../../7zVersion.h" #include "resource.h" -#if defined(__GNUC__) && (__GNUC__ >= 8) - #pragma GCC diagnostic ignored "-Wcast-function-type" -#endif + + #define LLL_(quote) L##quote #define LLL(quote) LLL_(quote) -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define wcscat lstrcatW +#define wcslen (size_t)lstrlenW +#define wcscpy lstrcpyW // static LPCWSTR const k_7zip = L"7-Zip"; -// #define _64BIT_INSTALLER 1 +// #define Z7_64BIT_INSTALLER 1 #ifdef _WIN64 - #define _64BIT_INSTALLER 1 + #define Z7_64BIT_INSTALLER 1 #endif #define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION) -#ifdef _64BIT_INSTALLER +#ifdef Z7_64BIT_INSTALLER // #define USE_7ZIP_32_DLL @@ -64,24 +80,26 @@ static LPCWSTR const k_Reg_Path = L"Path"; static LPCWSTR const k_Reg_Path32 = L"Path" - #ifdef _64BIT_INSTALLER + #ifdef Z7_64BIT_INSTALLER L"64" #else L"32" #endif ; -#if defined(_64BIT_INSTALLER) && !defined(_WIN64) +#if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) #define k_Reg_WOW_Flag KEY_WOW64_64KEY #else #define k_Reg_WOW_Flag 0 #endif +#ifdef USE_7ZIP_32_DLL #ifdef _WIN64 #define k_Reg_WOW_Flag_32 KEY_WOW64_32KEY #else #define k_Reg_WOW_Flag_32 0 #endif +#endif #define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}" @@ -100,9 +118,19 @@ static HWND g_InfoLine_HWND; static HWND g_Progress_HWND; -// WINADVAPI +// RegDeleteKeyExW is supported starting from win2003sp1/xp-pro-x64 +// Z7_WIN32_WINNT_MIN < 0x0600 // Vista +#if !defined(Z7_WIN32_WINNT_MIN) \ + || Z7_WIN32_WINNT_MIN < 0x0502 /* < win2003 */ \ + || Z7_WIN32_WINNT_MIN == 0x0502 && !defined(_M_AMD64) +#define Z7_USE_DYN_RegDeleteKeyExW +#endif + +#ifdef Z7_USE_DYN_RegDeleteKeyExW +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION typedef LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved); static Func_RegDeleteKeyExW func_RegDeleteKeyExW; +#endif static WCHAR cmd[MAX_PATH + 4]; static WCHAR cmdError[MAX_PATH + 4]; @@ -116,14 +144,14 @@ static LPCWSTR const kUninstallExe = L"Uninstall.exe"; -#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c))) +#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) static void CpyAscii(wchar_t *dest, const char *s) { for (;;) { - Byte b = (Byte)*s++; + const Byte b = (Byte)*s++; *dest++ = b; if (b == 0) return; @@ -173,7 +201,7 @@ for (;;) { wchar_t c1; - wchar_t c2 = *s2++; + const wchar_t c2 = *s2++; if (c2 == 0) return True; c1 = *s1++; @@ -184,7 +212,7 @@ static void NormalizePrefix(WCHAR *s) { - size_t len = wcslen(s); + const size_t len = wcslen(s); if (len != 0) if (s[len - 1] != WCHAR_PATH_SEPARATOR) { @@ -197,7 +225,7 @@ { DWORD cnt = MAX_PATH * sizeof(name[0]); DWORD type = 0; - LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, (DWORD *)&cnt); + const LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, &cnt); if (type != REG_SZ) return False; return res == ERROR_SUCCESS; @@ -206,11 +234,11 @@ static int MyRegistry_QueryString2(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) { HKEY key = 0; - LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); if (res != ERROR_SUCCESS) return False; { - BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); RegCloseKey(key); return res2; } @@ -223,13 +251,18 @@ static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCWSTR name) { - #if k_Reg_WOW_Flag != 0 - if (func_RegDeleteKeyExW) - return func_RegDeleteKeyExW(parentKey, name, k_Reg_WOW_Flag, 0); - return E_FAIL; - #else +#if k_Reg_WOW_Flag != 0 +#ifdef Z7_USE_DYN_RegDeleteKeyExW + if (!func_RegDeleteKeyExW) + return E_FAIL; + return func_RegDeleteKeyExW +#else + return RegDeleteKeyExW +#endif + (parentKey, name, k_Reg_WOW_Flag, 0); +#else return RegDeleteKeyW(parentKey, name); - #endif +#endif } #ifdef USE_7ZIP_32_DLL @@ -237,11 +270,11 @@ static int MyRegistry_QueryString2_32(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) { HKEY key = 0; - LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag_32, &key); + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag_32, &key); if (res != ERROR_SUCCESS) return False; { - BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); RegCloseKey(key); return res2; } @@ -254,13 +287,18 @@ static LONG MyRegistry_DeleteKey_32(HKEY parentKey, LPCWSTR name) { - #if k_Reg_WOW_Flag_32 != 0 - if (func_RegDeleteKeyExW) - return func_RegDeleteKeyExW(parentKey, name, k_Reg_WOW_Flag_32, 0); - return E_FAIL; - #else +#if k_Reg_WOW_Flag_32 != 0 +#ifdef Z7_USE_DYN_RegDeleteKeyExW + if (!func_RegDeleteKeyExW) + return E_FAIL; + return func_RegDeleteKeyExW +#else + return RegDeleteKeyExW +#endif + (parentKey, name, k_Reg_WOW_Flag_32, 0); +#else return RegDeleteKeyW(parentKey, name); - #endif +#endif } #endif @@ -282,7 +320,7 @@ static void SetRegKey_Path2(HKEY parentKey) { HKEY key = 0; - LONG res = MyRegistry_OpenKey_ReadWrite(parentKey, k_Reg_Software_7zip, &key); + const LONG res = MyRegistry_OpenKey_ReadWrite(parentKey, k_Reg_Software_7zip, &key); if (res == ERROR_SUCCESS) { MyReg_DeleteVal_Path_if_Equal(key, k_Reg_Path32); @@ -293,7 +331,7 @@ } } -static void SetRegKey_Path() +static void SetRegKey_Path(void) { SetRegKey_Path2(HKEY_CURRENT_USER); SetRegKey_Path2(HKEY_LOCAL_MACHINE); @@ -426,7 +464,7 @@ return AreStringsEqual_NoCase(s + wcslen(prefix), name); } -static void WriteCLSID() +static void WriteCLSID(void) { WCHAR s[MAX_PATH + 30]; @@ -435,14 +473,14 @@ if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll")) { { - LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); + const LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); if (res == ERROR_SUCCESS) MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip); } { unsigned i; - for (i = 0; i < ARRAY_SIZE(k_ShellEx_Items); i++) + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) { WCHAR destPath[MAX_PATH]; CpyAscii(destPath, k_ShellEx_Items[i]); @@ -454,7 +492,7 @@ { HKEY destKey = 0; - LONG res = MyRegistry_OpenKey_ReadWrite(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); + const LONG res = MyRegistry_OpenKey_ReadWrite(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); if (res == ERROR_SUCCESS) { RegDeleteValueW(destKey, k_7zip_CLSID); @@ -472,14 +510,14 @@ if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll")) { { - LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); + const LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); if (res == ERROR_SUCCESS) MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip); } { unsigned i; - for (i = 0; i < ARRAY_SIZE(k_ShellEx_Items); i++) + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) { WCHAR destPath[MAX_PATH]; CpyAscii(destPath, k_ShellEx_Items[i]); @@ -491,7 +529,7 @@ { HKEY destKey = 0; - LONG res = MyRegistry_OpenKey_ReadWrite_32(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); + const LONG res = MyRegistry_OpenKey_ReadWrite_32(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); if (res == ERROR_SUCCESS) { RegDeleteValueW(destKey, k_7zip_CLSID); @@ -526,7 +564,7 @@ BoolInt quoteMode = False; for (;; s++) { - wchar_t c = *s; + const wchar_t c = *s; if (c == 0 || (c == L' ' && !quoteMode)) break; if (c == L'\"') @@ -534,7 +572,7 @@ quoteMode = !quoteMode; continue; } - if (pos >= ARRAY_SIZE(cmd) - 1) + if (pos >= Z7_ARRAY_SIZE(cmd) - 1) exit(1); cmd[pos++] = c; } @@ -558,7 +596,7 @@ } */ -static BoolInt DoesFileOrDirExist() +static BoolInt DoesFileOrDirExist(void) { return (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES); } @@ -573,7 +611,7 @@ #endif } -static BOOL RemoveFileAfterReboot() +static BOOL RemoveFileAfterReboot(void) { return RemoveFileAfterReboot2(path); } @@ -584,7 +622,7 @@ { for (;;) { - wchar_t c = *s++; + const wchar_t c = *s++; if (c == 0) return False; if (c == ' ') @@ -594,7 +632,7 @@ static void AddPathParam(wchar_t *dest, const wchar_t *src) { - BoolInt needQuote = IsThereSpace(src); + const BoolInt needQuote = IsThereSpace(src); if (needQuote) CatAscii(dest, "\""); wcscat(dest, src); @@ -618,9 +656,9 @@ return True; } -static BOOL RemoveDir() +static BOOL RemoveDir(void) { - DWORD attrib = GetFileAttributesW(path); + const DWORD attrib = GetFileAttributesW(path); if (attrib == INVALID_FILE_ATTRIBUTES) return TRUE; if (RemoveDirectoryW(path)) @@ -670,7 +708,7 @@ -static int Install() +static int Install(void) { SRes res = SZ_OK; WRes winRes = 0; @@ -724,7 +762,7 @@ for (;;) { - char c = *curName; + const char c = *curName; if (c == 0) break; curName++; @@ -743,7 +781,7 @@ SetWindowTextW(g_InfoLine_HWND, temp); { - DWORD attrib = GetFileAttributesW(path); + const DWORD attrib = GetFileAttributesW(path); if (attrib == INVALID_FILE_ATTRIBUTES) continue; if (attrib & FILE_ATTRIBUTE_READONLY) @@ -803,7 +841,7 @@ } -static void OnClose() +static void OnClose(void) { if (g_Install_was_Pressed && !g_Finished) { @@ -817,7 +855,13 @@ g_HWND = NULL; } -static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { UNUSED_VAR(lParam) @@ -900,14 +944,17 @@ UNUSED_VAR(lpCmdLine) UNUSED_VAR(nCmdShow) - #ifndef UNDER_CE +#ifndef UNDER_CE CoInitialize(NULL); - #endif +#endif - #ifndef UNDER_CE - func_RegDeleteKeyExW = (Func_RegDeleteKeyExW) - GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW"); - #endif +#ifndef UNDER_CE +#ifdef Z7_USE_DYN_RegDeleteKeyExW + func_RegDeleteKeyExW = + (Func_RegDeleteKeyExW) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandleW(L"advapi32.dll"), + "RegDeleteKeyExW"); +#endif +#endif { const wchar_t *s = GetCommandLineW(); @@ -976,7 +1023,7 @@ { wchar_t *name; - DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH); + const DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH); if (len == 0 || len > MAX_PATH) return 1; @@ -987,7 +1034,7 @@ wchar_t *s = modulePrefix; for (;;) { - wchar_t c = *s++; + const wchar_t c = *s++; if (c == 0) break; if (c == WCHAR_PATH_SEPARATOR) @@ -1037,7 +1084,7 @@ unsigned k; for (k = 0; k < 8; k++) { - unsigned t = value & 0xF; + const unsigned t = value & 0xF; value >>= 4; s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); } @@ -1134,7 +1181,7 @@ return 1; { - HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); + const HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); // SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); } diff -Nru 7zip-22.01+dfsg/C/Util/7zipUninstall/7zipUninstall.dsp 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.dsp --- 7zip-22.01+dfsg/C/Util/7zipUninstall/7zipUninstall.dsp 2017-02-03 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/7zipUninstall.dsp 2023-04-04 11:00:00.000000000 +0000 @@ -104,6 +104,14 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + SOURCE=.\Precomp.c # ADD CPP /Yc"Precomp.h" # End Source File diff -Nru 7zip-22.01+dfsg/C/Util/7zipUninstall/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/Precomp.h --- 7zip-22.01+dfsg/C/Util/7zipUninstall/Precomp.h 2015-05-24 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -1,11 +1,13 @@ -/* Precomp.h -- StdAfx -2015-05-24 : Igor Pavlov : Public domain */ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H -#include "../../Compiler.h" +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif -#include "../../7zTypes.h" +#include "../../Precomp.h" -#endif +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/7zipUninstall/makefile 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/makefile --- 7zip-22.01+dfsg/C/Util/7zipUninstall/makefile 2018-04-20 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/makefile 2023-04-04 13:00:00.000000000 +0000 @@ -1,8 +1,8 @@ PROG = 7zipUninstall.exe MY_FIXED = 1 -!IFDEF _64BIT_INSTALLER -CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER +!IFDEF Z7_64BIT_INSTALLER +CFLAGS = $(CFLAGS) -DZ7_64BIT_INSTALLER !ENDIF MAIN_OBJS = \ diff -Nru 7zip-22.01+dfsg/C/Util/7zipUninstall/resource.rc 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/resource.rc --- 7zip-22.01+dfsg/C/Util/7zipUninstall/resource.rc 2015-06-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/7zipUninstall/resource.rc 2024-03-21 10:00:00.000000000 +0000 @@ -1,5 +1,6 @@ -#include -#include +#include +// #include +// #include #include #define USE_COPYRIGHT_CR diff -Nru 7zip-22.01+dfsg/C/Util/Lzma/LzmaUtil.c 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.c --- 7zip-22.01+dfsg/C/Util/Lzma/LzmaUtil.c 2021-11-01 11:09:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.c 2023-04-04 19:00:00.000000000 +0000 @@ -1,7 +1,7 @@ /* LzmaUtil.c -- Test application for LZMA compression -2021-11-01 : Igor Pavlov : Public domain */ +2023-03-07 : Igor Pavlov : Public domain */ -#include "../../Precomp.h" +#include "Precomp.h" #include #include @@ -21,48 +21,80 @@ static const char * const kCantAllocateMessage = "Cannot allocate memory"; static const char * const kDataErrorMessage = "Data error"; -static void PrintHelp(char *buffer) +static void Print(const char *s) { - strcat(buffer, - "\nLZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n" - "Usage: lzma inputFile outputFile\n" - " e: encode file\n" - " d: decode file\n"); + fputs(s, stdout); } -static int PrintError(char *buffer, const char *message) +static void PrintHelp(void) { - strcat(buffer, "\nError: "); - strcat(buffer, message); - strcat(buffer, "\n"); + Print( + "\n" "LZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE + "\n" + "\n" "Usage: lzma inputFile outputFile" + "\n" " e: encode file" + "\n" " d: decode file" + "\n"); +} + +static int PrintError(const char *message) +{ + Print("\nError: "); + Print(message); + Print("\n"); return 1; } -static int PrintError_WRes(char *buffer, const char *message, WRes wres) +#define CONVERT_INT_TO_STR(charType, tempSize) \ + unsigned char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = (charType)temp[i]; } \ + *s = 0; \ + return s; + +static char * Convert_unsigned_To_str(unsigned val, char *s) { - strcat(buffer, "\nError: "); - strcat(buffer, message); - sprintf(buffer + strlen(buffer), "\nSystem error code: %d", (unsigned)wres); + CONVERT_INT_TO_STR(char, 32) +} + +static void Print_unsigned(unsigned code) +{ + char str[32]; + Convert_unsigned_To_str(code, str); + Print(str); +} + +static int PrintError_WRes(const char *message, WRes wres) +{ + PrintError(message); + Print("\nSystem error code: "); + Print_unsigned((unsigned)wres); #ifndef _WIN32 { const char *s = strerror(wres); if (s) - sprintf(buffer + strlen(buffer), " : %s", s); + { + Print(" : "); + Print(s); + } } #endif - strcat(buffer, "\n"); + Print("\n"); return 1; } -static int PrintErrorNumber(char *buffer, SRes val) +static int PrintErrorNumber(SRes val) { - sprintf(buffer + strlen(buffer), "\n7-Zip error code: %d\n", (unsigned)val); + Print("\n7-Zip error code: "); + Print_unsigned((unsigned)val); + Print("\n"); return 1; } -static int PrintUserError(char *buffer) +static int PrintUserError(void) { - return PrintError(buffer, "Incorrect command"); + return PrintError("Incorrect command"); } @@ -70,10 +102,10 @@ #define OUT_BUF_SIZE (1 << 16) -static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, +static SRes Decode2(CLzmaDec *state, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, UInt64 unpackSize) { - int thereIsSize = (unpackSize != (UInt64)(Int64)-1); + const int thereIsSize = (unpackSize != (UInt64)(Int64)-1); Byte inBuf[IN_BUF_SIZE]; Byte outBuf[OUT_BUF_SIZE]; size_t inPos = 0, inSize = 0, outPos = 0; @@ -83,7 +115,7 @@ if (inPos == inSize) { inSize = IN_BUF_SIZE; - RINOK(inStream->Read(inStream, inBuf, &inSize)); + RINOK(inStream->Read(inStream, inBuf, &inSize)) inPos = 0; } { @@ -124,7 +156,7 @@ } -static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream) +static SRes Decode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream) { UInt64 unpackSize; int i; @@ -137,27 +169,29 @@ /* Read and parse header */ - RINOK(SeqInStream_Read(inStream, header, sizeof(header))); - + { + size_t size = sizeof(header); + RINOK(SeqInStream_ReadMax(inStream, header, &size)) + if (size != sizeof(header)) + return SZ_ERROR_INPUT_EOF; + } unpackSize = 0; for (i = 0; i < 8; i++) unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8); - LzmaDec_Construct(&state); - RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)); + LzmaDec_CONSTRUCT(&state) + RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)) res = Decode2(&state, outStream, inStream, unpackSize); LzmaDec_Free(&state, &g_Alloc); return res; } -static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs) +static SRes Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, UInt64 fileSize) { CLzmaEncHandle enc; SRes res; CLzmaEncProps props; - UNUSED_VAR(rs); - enc = LzmaEnc_Create(&g_Alloc); if (enc == 0) return SZ_ERROR_MEM; @@ -187,7 +221,7 @@ } -static int main2(int numArgs, const char *args[], char *rs) +int Z7_CDECL main(int numArgs, const char *args[]) { CFileSeqInStream inStream; CFileOutStream outStream; @@ -208,29 +242,31 @@ if (numArgs == 1) { - PrintHelp(rs); + PrintHelp(); return 0; } if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1) - return PrintUserError(rs); + return PrintUserError(); c = args[1][0]; encodeMode = (c == 'e' || c == 'E'); if (!encodeMode && c != 'd' && c != 'D') - return PrintUserError(rs); + return PrintUserError(); + /* { size_t t4 = sizeof(UInt32); size_t t8 = sizeof(UInt64); if (t4 != 4 || t8 != 8) - return PrintError(rs, "Incorrect UInt32 or UInt64"); + return PrintError("Incorrect UInt32 or UInt64"); } + */ { - WRes wres = InFile_Open(&inStream.file, args[2]); + const WRes wres = InFile_Open(&inStream.file, args[2]); if (wres != 0) - return PrintError_WRes(rs, "Cannot open input file", wres); + return PrintError_WRes("Cannot open input file", wres); } if (numArgs > 3) @@ -239,18 +275,18 @@ useOutFile = True; wres = OutFile_Open(&outStream.file, args[3]); if (wres != 0) - return PrintError_WRes(rs, "Cannot open output file", wres); + return PrintError_WRes("Cannot open output file", wres); } else if (encodeMode) - PrintUserError(rs); + PrintUserError(); if (encodeMode) { UInt64 fileSize; - WRes wres = File_GetLength(&inStream.file, &fileSize); + const WRes wres = File_GetLength(&inStream.file, &fileSize); if (wres != 0) - return PrintError_WRes(rs, "Cannot get file length", wres); - res = Encode(&outStream.vt, &inStream.vt, fileSize, rs); + return PrintError_WRes("Cannot get file length", wres); + res = Encode(&outStream.vt, &inStream.vt, fileSize); } else { @@ -264,23 +300,14 @@ if (res != SZ_OK) { if (res == SZ_ERROR_MEM) - return PrintError(rs, kCantAllocateMessage); + return PrintError(kCantAllocateMessage); else if (res == SZ_ERROR_DATA) - return PrintError(rs, kDataErrorMessage); + return PrintError(kDataErrorMessage); else if (res == SZ_ERROR_WRITE) - return PrintError_WRes(rs, kCantWriteMessage, outStream.wres); + return PrintError_WRes(kCantWriteMessage, outStream.wres); else if (res == SZ_ERROR_READ) - return PrintError_WRes(rs, kCantReadMessage, inStream.wres); - return PrintErrorNumber(rs, res); + return PrintError_WRes(kCantReadMessage, inStream.wres); + return PrintErrorNumber(res); } return 0; } - - -int MY_CDECL main(int numArgs, const char *args[]) -{ - char rs[1000] = { 0 }; - int res = main2(numArgs, args, rs); - fputs(rs, stdout); - return res; -} diff -Nru 7zip-22.01+dfsg/C/Util/Lzma/LzmaUtil.dsp 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.dsp --- 7zip-22.01+dfsg/C/Util/Lzma/LzmaUtil.dsp 2021-11-01 11:10:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/Lzma/LzmaUtil.dsp 2025-02-05 06:00:00.000000000 +0000 @@ -106,6 +106,10 @@ # End Source File # Begin Source File +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\Alloc.c # End Source File # Begin Source File @@ -114,6 +118,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + SOURCE=..\..\CpuArch.h # End Source File # Begin Source File @@ -162,6 +174,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# Begin Source File + SOURCE=..\..\Threads.c # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/C/Util/Lzma/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/Lzma/Precomp.h --- 7zip-22.01+dfsg/C/Util/Lzma/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/Lzma/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/LzmaLib/LzmaLib.dsp 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLib.dsp --- 7zip-22.01+dfsg/C/Util/LzmaLib/LzmaLib.dsp 2021-07-20 07:04:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLib.dsp 2025-02-05 06:00:00.000000000 +0000 @@ -43,7 +43,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 @@ -71,7 +71,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -101,6 +101,10 @@ SOURCE=.\LzmaLibExports.c # End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File # End Group # Begin Source File @@ -108,6 +112,10 @@ # End Source File # Begin Source File +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\Alloc.c # End Source File # Begin Source File @@ -116,6 +124,18 @@ # End Source File # Begin Source File +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + SOURCE=..\..\IStream.h # End Source File # Begin Source File @@ -168,6 +188,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + SOURCE=.\resource.rc # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/C/Util/LzmaLib/LzmaLibExports.c 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLibExports.c --- 7zip-22.01+dfsg/C/Util/LzmaLib/LzmaLibExports.c 2015-11-08 11:34:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/LzmaLibExports.c 2023-03-05 17:00:00.000000000 +0000 @@ -1,14 +1,15 @@ /* LzmaLibExports.c -- LZMA library DLL Entry point -2015-11-08 : Igor Pavlov : Public domain */ +2023-03-05 : Igor Pavlov : Public domain */ -#include "../../Precomp.h" +#include "Precomp.h" -#include +#include "../../7zWindows.h" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved); BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { - UNUSED_VAR(hInstance); - UNUSED_VAR(dwReason); - UNUSED_VAR(lpReserved); + UNUSED_VAR(hInstance) + UNUSED_VAR(dwReason) + UNUSED_VAR(lpReserved) return TRUE; } diff -Nru 7zip-22.01+dfsg/C/Util/LzmaLib/Precomp.c 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.c --- 7zip-22.01+dfsg/C/Util/LzmaLib/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.c 2013-01-23 18:00:00.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru 7zip-22.01+dfsg/C/Util/LzmaLib/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.h --- 7zip-22.01+dfsg/C/Util/LzmaLib/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/LzmaLib/makefile 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/makefile --- 7zip-22.01+dfsg/C/Util/LzmaLib/makefile 2021-11-01 11:02:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/LzmaLib/makefile 2024-03-21 10:00:00.000000000 +0000 @@ -14,15 +14,19 @@ $O\CpuArch.obj \ $O\LzFind.obj \ $O\LzFindMt.obj \ - $O\LzFindOpt.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\LzmaLib.obj \ $O\Threads.obj \ +!include "../../../CPP/7zip/LzFindOpt.mak" +!include "../../../CPP/7zip/LzmaDec.mak" + OBJS = \ + $O\Precomp.obj \ $(LIB_OBJS) \ $(C_OBJS) \ + $(ASM_OBJS) \ $O\resource.res !include "../../../CPP/Build.mak" @@ -30,7 +34,26 @@ $(SLIBPATH): $O $(OBJS) lib -out:$(SLIBPATH) $(OBJS) $(LIBS) + +MAK_SINGLE_FILE = 1 + +$O\Precomp.obj: Precomp.c + $(CCOMPL_PCH) + +!IFDEF MAK_SINGLE_FILE + $(LIB_OBJS): $(*B).c - $(COMPL_O2) + $(CCOMPL_USE) $(C_OBJS): ../../$(*B).c - $(COMPL_O2) + $(CCOMPL_USE) + +!ELSE + +{.}.c{$O}.obj:: + $(CCOMPLB_USE) +{../../../C}.c{$O}.obj:: + $(CCOMPLB_USE) + +!ENDIF + +!include "../../Asm_c.mak" diff -Nru 7zip-22.01+dfsg/C/Util/SfxSetup/Precomp.h 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/Precomp.h --- 7zip-22.01+dfsg/C/Util/SfxSetup/Precomp.h 2014-06-16 05:58:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -1,10 +1,13 @@ -/* Precomp.h -- StdAfx -2013-06-16 : Igor Pavlov : Public domain */ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "../../Compiler.h" -#include "../../7zTypes.h" +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif + +#include "../../Precomp.h" + +// #endif diff -Nru 7zip-22.01+dfsg/C/Util/SfxSetup/SfxSetup.c 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/SfxSetup.c --- 7zip-22.01+dfsg/C/Util/SfxSetup/SfxSetup.c 2019-02-02 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/SfxSetup.c 2024-01-24 17:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* SfxSetup.c - 7z SFX Setup -2019-02-02 : Igor Pavlov : Public domain */ +2024-01-24 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -26,6 +26,12 @@ #define kInputBufSize ((size_t)1 << 18) + +#define wcscat lstrcatW +#define wcslen (size_t)lstrlenW +#define wcscpy lstrcpyW +// wcsncpy() and lstrcpynW() work differently. We don't use them. + static const char * const kExts[] = { "bat" @@ -64,7 +70,7 @@ return len; } -#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c))) +#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len) { @@ -72,13 +78,13 @@ for (i = 0; i < num; i++) { const char *item = items[i]; - unsigned itemLen = (unsigned)strlen(item); + const unsigned itemLen = (unsigned)strlen(item); unsigned j; if (len != itemLen) continue; for (j = 0; j < len; j++) { - unsigned c = (Byte)item[j]; + const unsigned c = (Byte)item[j]; if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j]) break; } @@ -96,10 +102,20 @@ } #endif + +#ifdef _CONSOLE +static void PrintStr(const char *s) +{ + fputs(s, stdout); +} +#endif + static void PrintErrorMessage(const char *message) { #ifdef _CONSOLE - printf("\n7-Zip Error: %s\n", message); + PrintStr("\n7-Zip Error: "); + PrintStr(message); + PrintStr("\n"); #else #ifdef UNDER_CE WCHAR messageW[256 + 4]; @@ -179,7 +195,7 @@ WIN32_FIND_DATAW fd; HANDLE handle; WRes res = 0; - size_t len = wcslen(path); + const size_t len = wcslen(path); wcscpy(path + len, L"*"); handle = FindFirstFileW(path, &fd); path[len] = L'\0'; @@ -228,7 +244,7 @@ } #ifdef _CONSOLE -int MY_CDECL main() +int Z7_CDECL main(void) #else int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, #ifdef UNDER_CE @@ -262,10 +278,10 @@ #ifdef _CONSOLE SetConsoleCtrlHandler(HandlerRoutine, TRUE); #else - UNUSED_VAR(hInstance); - UNUSED_VAR(hPrevInstance); - UNUSED_VAR(lpCmdLine); - UNUSED_VAR(nCmdShow); + UNUSED_VAR(hInstance) + UNUSED_VAR(hPrevInstance) + UNUSED_VAR(lpCmdLine) + UNUSED_VAR(nCmdShow) #endif CrcGenerateTable(); @@ -290,7 +306,7 @@ BoolInt quoteMode = False; for (;; cmdLineParams++) { - wchar_t c = *cmdLineParams; + const wchar_t c = *cmdLineParams; if (c == L'\"') quoteMode = !quoteMode; else if (c == 0 || (c == L' ' && !quoteMode)) @@ -324,7 +340,7 @@ unsigned k; for (k = 0; k < 8; k++) { - unsigned t = value & 0xF; + const unsigned t = value & 0xF; value >>= 4; s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); } @@ -386,7 +402,7 @@ { lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; - LookToRead2_Init(&lookStream); + LookToRead2_INIT(&lookStream) } } @@ -455,11 +471,11 @@ unsigned extLen; const WCHAR *name = temp + nameStartPos; unsigned len = (unsigned)wcslen(name); - unsigned nameLen = FindExt(temp + nameStartPos, &extLen); - unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen); - unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen); + const unsigned nameLen = FindExt(temp + nameStartPos, &extLen); + const unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen); + const unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen); - unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12)); + const unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12)); if (minPrice > price) { minPrice = price; @@ -500,12 +516,13 @@ #endif { - SRes res2 = File_Close(&outFile); + const WRes res2 = File_Close(&outFile); if (res != SZ_OK) break; - if (res2 != SZ_OK) + if (res2 != 0) { - res = res2; + errorMessage = "Can't close output file"; + res = SZ_ERROR_FAIL; break; } } @@ -550,7 +567,7 @@ WCHAR oldCurDir[MAX_PATH + 2]; oldCurDir[0] = 0; { - DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir); + const DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir); if (needLen == 0 || needLen > MAX_PATH) oldCurDir[0] = 0; SetCurrentDirectory(workCurDir); diff -Nru 7zip-22.01+dfsg/C/Util/SfxSetup/makefile 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile --- 7zip-22.01+dfsg/C/Util/SfxSetup/makefile 2018-04-20 14:23:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile 2024-03-21 10:00:00.000000000 +0000 @@ -1,13 +1,14 @@ PROG = 7zS2.sfx MY_FIXED = 1 +CFLAGS = $(CFLAGS) \ + -DZ7_EXTRACT_ONLY \ + C_OBJS = \ $O\7zAlloc.obj \ $O\7zArcIn.obj \ $O\7zBuf.obj \ $O\7zBuf2.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ $O\7zFile.obj \ $O\7zDec.obj \ $O\7zStream.obj \ @@ -24,9 +25,13 @@ 7Z_OBJS = \ $O\SfxSetup.obj \ +!include "../../../CPP/7zip/Crc.mak" +# !include "../../../CPP/7zip/LzmaDec.mak" + OBJS = \ $(7Z_OBJS) \ $(C_OBJS) \ + $(ASM_OBJS) \ $O\resource.res !include "../../../CPP/Build.mak" @@ -35,3 +40,5 @@ $(COMPL_O1) $(C_OBJS): ../../$(*B).c $(COMPL_O1) + +!include "../../Asm_c.mak" diff -Nru 7zip-22.01+dfsg/C/Util/SfxSetup/makefile_con 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile_con --- 7zip-22.01+dfsg/C/Util/SfxSetup/makefile_con 2018-04-20 14:23:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Util/SfxSetup/makefile_con 2023-04-04 13:00:00.000000000 +0000 @@ -1,6 +1,8 @@ PROG = 7zS2con.sfx MY_FIXED = 1 -CFLAGS = $(CFLAGS) -D_CONSOLE + +CFLAGS = $(CFLAGS) -D_CONSOLE \ + -DZ7_EXTRACT_ONLY \ C_OBJS = \ $O\7zAlloc.obj \ diff -Nru 7zip-22.01+dfsg/C/Xxh64.c 7zip-22.01+really25.01+dfsg/C/Xxh64.c --- 7zip-22.01+dfsg/C/Xxh64.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Xxh64.c 2023-08-18 08:00:00.000000000 +0000 @@ -0,0 +1,327 @@ +/* Xxh64.c -- XXH64 hash calculation +original code: Copyright (c) Yann Collet. +2023-08-18 : modified by Igor Pavlov. +This source code is licensed under BSD 2-Clause License. +*/ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "RotateDefs.h" +#include "Xxh64.h" + +#define Z7_XXH_PRIME64_1 UINT64_CONST(0x9E3779B185EBCA87) +#define Z7_XXH_PRIME64_2 UINT64_CONST(0xC2B2AE3D27D4EB4F) +#define Z7_XXH_PRIME64_3 UINT64_CONST(0x165667B19E3779F9) +#define Z7_XXH_PRIME64_4 UINT64_CONST(0x85EBCA77C2B2AE63) +#define Z7_XXH_PRIME64_5 UINT64_CONST(0x27D4EB2F165667C5) + +void Xxh64State_Init(CXxh64State *p) +{ + const UInt64 seed = 0; + p->v[0] = seed + Z7_XXH_PRIME64_1 + Z7_XXH_PRIME64_2; + p->v[1] = seed + Z7_XXH_PRIME64_2; + p->v[2] = seed; + p->v[3] = seed - Z7_XXH_PRIME64_1; +} + +#if !defined(MY_CPU_64BIT) && defined(MY_CPU_X86) && defined(_MSC_VER) + #define Z7_XXH64_USE_ASM +#endif + +#if !defined(MY_CPU_64BIT) && defined(MY_CPU_X86) \ + && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL > 1200 +/* we try to avoid __allmul calls in MSVC for 64-bit multiply. + But MSVC6 still uses __allmul for our code. + So for MSVC6 we use default 64-bit multiply without our optimization. +*/ +#define LOW32(b) ((UInt32)(b & 0xffffffff)) +/* MSVC compiler (MSVC > 1200) can use "mul" instruction + without __allmul for our MY_emulu MACRO. + MY_emulu is similar to __emulu(a, b) MACRO */ +#define MY_emulu(a, b) ((UInt64)(a) * (b)) +#define MY_SET_HIGH32(a) ((UInt64)(a) << 32) +#define MY_MUL32_SET_HIGH32(a, b) MY_SET_HIGH32((UInt32)(a) * (UInt32)(b)) +// /* +#define MY_MUL64(a, b) \ + ( MY_emulu((UInt32)(a), LOW32(b)) + \ + MY_SET_HIGH32( \ + (UInt32)((a) >> 32) * LOW32(b) + \ + (UInt32)(a) * (UInt32)((b) >> 32) \ + )) +// */ +/* +#define MY_MUL64(a, b) \ + ( MY_emulu((UInt32)(a), LOW32(b)) \ + + MY_MUL32_SET_HIGH32((a) >> 32, LOW32(b)) + \ + + MY_MUL32_SET_HIGH32(a, (b) >> 32) \ + ) +*/ + +#define MY_MUL_32_64(a32, b) \ + ( MY_emulu((UInt32)(a32), LOW32(b)) \ + + MY_MUL32_SET_HIGH32(a32, (b) >> 32) \ + ) + +#else +#define MY_MUL64(a, b) ((a) * (b)) +#define MY_MUL_32_64(a32, b) ((a32) * (UInt64)(b)) +#endif + + +static +Z7_FORCE_INLINE +UInt64 Xxh64_Round(UInt64 acc, UInt64 input) +{ + acc += MY_MUL64(input, Z7_XXH_PRIME64_2); + acc = Z7_ROTL64(acc, 31); + return MY_MUL64(acc, Z7_XXH_PRIME64_1); +} + +static UInt64 Xxh64_Merge(UInt64 acc, UInt64 val) +{ + acc ^= Xxh64_Round(0, val); + return MY_MUL64(acc, Z7_XXH_PRIME64_1) + Z7_XXH_PRIME64_4; +} + + +#ifdef Z7_XXH64_USE_ASM + +#define Z7_XXH_PRIME64_1_HIGH 0x9E3779B1 +#define Z7_XXH_PRIME64_1_LOW 0x85EBCA87 +#define Z7_XXH_PRIME64_2_HIGH 0xC2B2AE3D +#define Z7_XXH_PRIME64_2_LOW 0x27D4EB4F + +void +Z7_NO_INLINE +__declspec(naked) +Z7_FASTCALL +Xxh64State_UpdateBlocks(CXxh64State *p, const void *data, const void *end) +{ + #if !defined(__clang__) + UNUSED_VAR(p) + UNUSED_VAR(data) + UNUSED_VAR(end) + #endif + __asm push ebx + __asm push ebp + __asm push esi + __asm push edi + + #define STACK_OFFSET 4 * 8 + __asm sub esp, STACK_OFFSET + +#define COPY_1(n) \ + __asm mov eax, [ecx + n * 4] \ + __asm mov [esp + n * 4], eax \ + +#define COPY_2(n) \ + __asm mov eax, [esp + n * 4] \ + __asm mov [ecx + n * 4], eax \ + + COPY_1(0) + __asm mov edi, [ecx + 1 * 4] \ + COPY_1(2) + COPY_1(3) + COPY_1(4) + COPY_1(5) + COPY_1(6) + COPY_1(7) + + __asm mov esi, edx \ + __asm mov [esp + 0 * 8 + 4], ecx + __asm mov ecx, Z7_XXH_PRIME64_2_LOW \ + __asm mov ebp, Z7_XXH_PRIME64_1_LOW \ + +#define R(n, state1, state1_reg) \ + __asm mov eax, [esi + n * 8] \ + __asm imul ebx, eax, Z7_XXH_PRIME64_2_HIGH \ + __asm add ebx, state1 \ + __asm mul ecx \ + __asm add edx, ebx \ + __asm mov ebx, [esi + n * 8 + 4] \ + __asm imul ebx, ecx \ + __asm add eax, [esp + n * 8] \ + __asm adc edx, ebx \ + __asm mov ebx, eax \ + __asm shld eax, edx, 31 \ + __asm shld edx, ebx, 31 \ + __asm imul state1_reg, eax, Z7_XXH_PRIME64_1_HIGH \ + __asm imul edx, ebp \ + __asm add state1_reg, edx \ + __asm mul ebp \ + __asm add state1_reg, edx \ + __asm mov [esp + n * 8], eax \ + +#define R2(n) \ + R(n, [esp + n * 8 + 4], ebx) \ + __asm mov [esp + n * 8 + 4], ebx \ + + __asm align 16 + __asm main_loop: + R(0, edi, edi) + R2(1) + R2(2) + R2(3) + __asm add esi, 32 + __asm cmp esi, [esp + STACK_OFFSET + 4 * 4 + 4] + __asm jne main_loop + + __asm mov ecx, [esp + 0 * 8 + 4] + + COPY_2(0) + __asm mov [ecx + 1 * 4], edi + COPY_2(2) + COPY_2(3) + COPY_2(4) + COPY_2(5) + COPY_2(6) + COPY_2(7) + + __asm add esp, STACK_OFFSET + __asm pop edi + __asm pop esi + __asm pop ebp + __asm pop ebx + __asm ret 4 +} + +#else + +void +Z7_NO_INLINE +Z7_FASTCALL +Xxh64State_UpdateBlocks(CXxh64State *p, const void *_data, const void *end) +{ + const Byte *data = (const Byte *)_data; + UInt64 v[4]; + v[0] = p->v[0]; + v[1] = p->v[1]; + v[2] = p->v[2]; + v[3] = p->v[3]; + do + { + v[0] = Xxh64_Round(v[0], GetUi64(data)); data += 8; + v[1] = Xxh64_Round(v[1], GetUi64(data)); data += 8; + v[2] = Xxh64_Round(v[2], GetUi64(data)); data += 8; + v[3] = Xxh64_Round(v[3], GetUi64(data)); data += 8; + } + while (data != end); + p->v[0] = v[0]; + p->v[1] = v[1]; + p->v[2] = v[2]; + p->v[3] = v[3]; +} + +#endif + +UInt64 Xxh64State_Digest(const CXxh64State *p, const void *_data, UInt64 count) +{ + UInt64 h = p->v[2]; + + if (count >= 32) + { + h = Z7_ROTL64(p->v[0], 1) + + Z7_ROTL64(p->v[1], 7) + + Z7_ROTL64(h, 12) + + Z7_ROTL64(p->v[3], 18); + h = Xxh64_Merge(h, p->v[0]); + h = Xxh64_Merge(h, p->v[1]); + h = Xxh64_Merge(h, p->v[2]); + h = Xxh64_Merge(h, p->v[3]); + } + else + h += Z7_XXH_PRIME64_5; + + h += count; + + // XXH64_finalize(): + { + unsigned cnt = (unsigned)count & 31; + const Byte *data = (const Byte *)_data; + while (cnt >= 8) + { + h ^= Xxh64_Round(0, GetUi64(data)); + data += 8; + h = Z7_ROTL64(h, 27); + h = MY_MUL64(h, Z7_XXH_PRIME64_1) + Z7_XXH_PRIME64_4; + cnt -= 8; + } + if (cnt >= 4) + { + const UInt32 v = GetUi32(data); + data += 4; + h ^= MY_MUL_32_64(v, Z7_XXH_PRIME64_1); + h = Z7_ROTL64(h, 23); + h = MY_MUL64(h, Z7_XXH_PRIME64_2) + Z7_XXH_PRIME64_3; + cnt -= 4; + } + while (cnt) + { + const UInt32 v = *data++; + h ^= MY_MUL_32_64(v, Z7_XXH_PRIME64_5); + h = Z7_ROTL64(h, 11); + h = MY_MUL64(h, Z7_XXH_PRIME64_1); + cnt--; + } + // XXH64_avalanche(h): + h ^= h >> 33; h = MY_MUL64(h, Z7_XXH_PRIME64_2); + h ^= h >> 29; h = MY_MUL64(h, Z7_XXH_PRIME64_3); + h ^= h >> 32; + return h; + } +} + + +void Xxh64_Init(CXxh64 *p) +{ + Xxh64State_Init(&p->state); + p->count = 0; + p->buf64[0] = 0; + p->buf64[1] = 0; + p->buf64[2] = 0; + p->buf64[3] = 0; +} + +void Xxh64_Update(CXxh64 *p, const void *_data, size_t size) +{ + const Byte *data = (const Byte *)_data; + unsigned cnt; + if (size == 0) + return; + cnt = (unsigned)p->count; + p->count += size; + + if (cnt &= 31) + { + unsigned rem = 32 - cnt; + Byte *dest = (Byte *)p->buf64 + cnt; + if (rem > size) + rem = (unsigned)size; + size -= rem; + cnt += rem; + // memcpy((Byte *)p->buf64 + cnt, data, rem); + do + *dest++ = *data++; + while (--rem); + if (cnt != 32) + return; + Xxh64State_UpdateBlocks(&p->state, p->buf64, &p->buf64[4]); + } + + if (size &= ~(size_t)31) + { + Xxh64State_UpdateBlocks(&p->state, data, data + size); + data += size; + } + + cnt = (unsigned)p->count & 31; + if (cnt) + { + // memcpy(p->buf64, data, cnt); + Byte *dest = (Byte *)p->buf64; + do + *dest++ = *data++; + while (--cnt); + } +} diff -Nru 7zip-22.01+dfsg/C/Xxh64.h 7zip-22.01+really25.01+dfsg/C/Xxh64.h --- 7zip-22.01+dfsg/C/Xxh64.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Xxh64.h 2023-08-18 08:00:00.000000000 +0000 @@ -0,0 +1,50 @@ +/* Xxh64.h -- XXH64 hash calculation interfaces +2023-08-18 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XXH64_H +#define ZIP7_INC_XXH64_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define Z7_XXH64_BLOCK_SIZE (4 * 8) + +typedef struct +{ + UInt64 v[4]; +} CXxh64State; + +void Xxh64State_Init(CXxh64State *p); + +// end != data && end == data + Z7_XXH64_BLOCK_SIZE * numBlocks +void Z7_FASTCALL Xxh64State_UpdateBlocks(CXxh64State *p, const void *data, const void *end); + +/* +Xxh64State_Digest(): +data: + the function processes only + (totalCount & (Z7_XXH64_BLOCK_SIZE - 1)) bytes in (data): (smaller than 32 bytes). +totalCount: total size of hashed stream: + it includes total size of data processed by previous Xxh64State_UpdateBlocks() calls, + and it also includes current processed size in (data). +*/ +UInt64 Xxh64State_Digest(const CXxh64State *p, const void *data, UInt64 totalCount); + + +typedef struct +{ + CXxh64State state; + UInt64 count; + UInt64 buf64[4]; +} CXxh64; + +void Xxh64_Init(CXxh64 *p); +void Xxh64_Update(CXxh64 *p, const void *data, size_t size); + +#define Xxh64_Digest(p) \ + Xxh64State_Digest(&(p)->state, (p)->buf64, (p)->count) + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/Xz.c 7zip-22.01+really25.01+dfsg/C/Xz.c --- 7zip-22.01+dfsg/C/Xz.c 2021-02-09 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Xz.c 2024-03-01 07:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* Xz.c - Xz -2021-02-09 : Igor Pavlov : Public domain */ +2024-03-01 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -52,6 +52,7 @@ case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; + default: break; } } @@ -62,6 +63,7 @@ case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; + default: break; } } @@ -70,7 +72,7 @@ switch (p->mode) { case XZ_CHECK_CRC32: - SetUi32(digest, CRC_GET_DIGEST(p->crc)); + SetUi32(digest, CRC_GET_DIGEST(p->crc)) break; case XZ_CHECK_CRC64: { diff -Nru 7zip-22.01+dfsg/C/Xz.h 7zip-22.01+really25.01+dfsg/C/Xz.h --- 7zip-22.01+dfsg/C/Xz.h 2021-04-01 17:13:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/Xz.h 2025-05-03 11:00:00.000000000 +0000 @@ -1,21 +1,24 @@ /* Xz.h - Xz interface -2021-04-01 : Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ -#ifndef __XZ_H -#define __XZ_H +#ifndef ZIP7_INC_XZ_H +#define ZIP7_INC_XZ_H #include "Sha256.h" +#include "Delta.h" EXTERN_C_BEGIN #define XZ_ID_Subblock 1 #define XZ_ID_Delta 3 -#define XZ_ID_X86 4 -#define XZ_ID_PPC 5 -#define XZ_ID_IA64 6 -#define XZ_ID_ARM 7 -#define XZ_ID_ARMT 8 +#define XZ_ID_X86 4 +#define XZ_ID_PPC 5 +#define XZ_ID_IA64 6 +#define XZ_ID_ARM 7 +#define XZ_ID_ARMT 8 #define XZ_ID_SPARC 9 +#define XZ_ID_ARM64 0xa +#define XZ_ID_RISCV 0xb #define XZ_ID_LZMA2 0x21 unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); @@ -53,7 +56,7 @@ #define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0) SRes XzBlock_Parse(CXzBlock *p, const Byte *header); -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes); +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes); /* ---------- xz stream ---------- */ @@ -101,7 +104,7 @@ unsigned XzFlags_GetCheckSize(CXzStreamFlags f); SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream); typedef struct { @@ -112,11 +115,13 @@ typedef struct { CXzStreamFlags flags; + // Byte _pad[6]; size_t numBlocks; CXzBlockSizes *blocks; UInt64 startOffset; } CXzStream; +#define Xz_CONSTRUCT(p) { (p)->numBlocks = 0; (p)->blocks = NULL; (p)->flags = 0; } void Xz_Construct(CXzStream *p); void Xz_Free(CXzStream *p, ISzAllocPtr alloc); @@ -132,9 +137,14 @@ CXzStream *streams; } CXzs; +#define Xzs_CONSTRUCT(p) { (p)->num = 0; (p)->numAllocated = 0; (p)->streams = NULL; } void Xzs_Construct(CXzs *p); void Xzs_Free(CXzs *p, ISzAllocPtr alloc); -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc); +/* +Xzs_ReadBackward() must be called for empty CXzs object. +Xzs_ReadBackward() can return non empty object with (p->num != 0) even in case of error. +*/ +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr inStream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc); UInt64 Xzs_GetNumBlocks(const CXzs *p); UInt64 Xzs_GetUnpackSize(const CXzs *p); @@ -160,9 +170,9 @@ } ECoderFinishMode; -typedef struct _IStateCoder +typedef struct { - void *p; + void *p; // state object; void (*Free)(void *p, ISzAllocPtr alloc); SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); void (*Init)(void *p); @@ -174,6 +184,20 @@ } IStateCoder; +typedef struct +{ + UInt32 methodId; + UInt32 delta; + UInt32 ip; + UInt32 X86_State; + Byte delta_State[DELTA_STATE_SIZE]; +} CXzBcFilterStateBase; + +typedef SizeT (*Xz_Func_BcFilterStateBase_Filter)(CXzBcFilterStateBase *p, Byte *data, SizeT size); + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc); + #define MIXCODER_NUM_FILTERS_MAX 4 @@ -216,13 +240,13 @@ typedef struct { EXzState state; - UInt32 pos; + unsigned pos; unsigned alignPos; unsigned indexPreSize; CXzStreamFlags streamFlags; - UInt32 blockHeaderSize; + unsigned blockHeaderSize; UInt64 packSize; UInt64 unpackSize; @@ -250,8 +274,8 @@ size_t outBufSize; size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked - Byte shaDigest[SHA256_DIGEST_SIZE]; - Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; + UInt32 shaDigest32[SHA256_DIGEST_SIZE / 4]; + Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; // it must be aligned for 4-bytes } CXzUnpacker; /* alloc : aligned for cache line allocation is better */ @@ -422,7 +446,7 @@ size_t outStep_ST; // size of output buffer for Single-Thread decoding BoolInt ignoreErrors; // if set to 1, the decoder can ignore some errors and it skips broken parts of data. - #ifndef _7ZIP_ST + #ifndef Z7_ST unsigned numThreads; // the number of threads for Multi-Thread decoding. if (umThreads == 1) it will use Single-thread decoding size_t inBufSize_MT; // size of small input data buffers for Multi-Thread decoding. Big number of such small buffers can be created size_t memUseMax; // the limit of total memory usage for Multi-Thread decoding. @@ -432,8 +456,9 @@ void XzDecMtProps_Init(CXzDecMtProps *p); - -typedef void * CXzDecMtHandle; +typedef struct CXzDecMt CXzDecMt; +typedef CXzDecMt * CXzDecMtHandle; +// Z7_DECLARE_HANDLE(CXzDecMtHandle) /* alloc : XzDecMt uses CAlignOffsetAlloc internally for addresses allocated by (alloc). @@ -503,14 +528,14 @@ const CXzDecMtProps *props, const UInt64 *outDataSize, // NULL means undefined int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, // Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, // const Byte *inData, size_t inDataSize, CXzStatInfo *stat, // out: decoding results and statistics int *isMT, // out: 0 means that ST (Single-Thread) version was used // 1 means that MT (Multi-Thread) version was used - ICompressProgress *progress); + ICompressProgressPtr progress); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/XzCrc64.c 7zip-22.01+really25.01+dfsg/C/XzCrc64.c --- 7zip-22.01+dfsg/C/XzCrc64.c 2017-05-23 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzCrc64.c 2023-12-08 10:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* XzCrc64.c -- CRC64 calculation -2017-05-23 : Igor Pavlov : Public domain */ +2023-12-08 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -8,45 +8,76 @@ #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) -#ifdef MY_CPU_LE - #define CRC64_NUM_TABLES 4 +// for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC64_DEBUG_BE +#ifdef Z7_CRC64_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +#ifdef Z7_CRC64_NUM_TABLES + #define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES #else - #define CRC64_NUM_TABLES 5 - #define CRC_UINT64_SWAP(v) \ - ((v >> 56) \ - | ((v >> 40) & ((UInt64)0xFF << 8)) \ - | ((v >> 24) & ((UInt64)0xFF << 16)) \ - | ((v >> 8) & ((UInt64)0xFF << 24)) \ - | ((v << 8) & ((UInt64)0xFF << 32)) \ - | ((v << 24) & ((UInt64)0xFF << 40)) \ - | ((v << 40) & ((UInt64)0xFF << 48)) \ - | ((v << 56))) + #define Z7_CRC64_NUM_TABLES_USE 12 +#endif - UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#if Z7_CRC64_NUM_TABLES_USE < 1 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES #endif + +#if Z7_CRC64_NUM_TABLES_USE != 1 + #ifndef MY_CPU_BE - UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); + #define FUNC_NAME_LE_2(s) XzCrc64UpdateT ## s + #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s) + #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC64_NUM_TABLES_USE) + UInt64 Z7_FASTCALL FUNC_NAME_LE (UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif +#ifndef MY_CPU_LE + #define FUNC_NAME_BE_2(s) XzCrc64UpdateBeT ## s + #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s) + #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC64_NUM_TABLES_USE) + UInt64 Z7_FASTCALL FUNC_NAME_BE (UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#if defined(MY_CPU_LE) + #define FUNC_REF FUNC_NAME_LE +#elif defined(MY_CPU_BE) + #define FUNC_REF FUNC_NAME_BE +#else + #define FUNC_REF g_Crc64Update + static UInt64 (Z7_FASTCALL *FUNC_REF)(UInt64 v, const void *data, size_t size, const UInt64 *table); #endif -typedef UInt64 (MY_FAST_CALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif -static CRC64_FUNC g_Crc64Update; -UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES]; -UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) -{ - return g_Crc64Update(v, data, size, g_Crc64Table); -} +MY_ALIGN(64) +static UInt64 g_Crc64Table[256 * Z7_CRC64_NUM_TABLES_USE]; + -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) +UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size) { - return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; +#if Z7_CRC64_NUM_TABLES_USE == 1 + #define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + const UInt64 *table = g_Crc64Table; + const Byte *p = (const Byte *)data; + const Byte *lim = p + size; + for (; p != lim; p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + return v; + #undef CRC64_UPDATE_BYTE_2 +#else + return FUNC_REF (v, data, size, g_Crc64Table); +#endif } -void MY_FAST_CALL Crc64GenerateTable() + +Z7_NO_INLINE +void Z7_FASTCALL Crc64GenerateTable(void) { - UInt32 i; + unsigned i; for (i = 0; i < 256; i++) { UInt64 r = i; @@ -55,32 +86,55 @@ r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); g_Crc64Table[i] = r; } - for (i = 256; i < 256 * CRC64_NUM_TABLES; i++) + +#if Z7_CRC64_NUM_TABLES_USE != 1 +#if 1 || 1 && defined(MY_CPU_X86) // low register count + for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i++) { - UInt64 r = g_Crc64Table[(size_t)i - 256]; - g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); + const UInt64 r0 = g_Crc64Table[(size_t)i]; + g_Crc64Table[(size_t)i + 256] = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); } - - #ifdef MY_CPU_LE - - g_Crc64Update = XzCrc64UpdateT4; +#else + for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i += 2) + { + UInt64 r0 = g_Crc64Table[(size_t)(i) ]; + UInt64 r1 = g_Crc64Table[(size_t)(i) + 1]; + r0 = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); + r1 = g_Crc64Table[(Byte)r1] ^ (r1 >> 8); + g_Crc64Table[(size_t)i + 256 ] = r0; + g_Crc64Table[(size_t)i + 256 + 1] = r1; + } +#endif - #else +#ifndef MY_CPU_LE { - #ifndef MY_CPU_BE +#ifndef MY_CPU_BE UInt32 k = 1; if (*(const Byte *)&k == 1) - g_Crc64Update = XzCrc64UpdateT4; + FUNC_REF = FUNC_NAME_LE; else - #endif +#endif { - for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--) +#ifndef MY_CPU_BE + FUNC_REF = FUNC_NAME_BE; +#endif + for (i = 0; i < 256 * Z7_CRC64_NUM_TABLES_USE; i++) { - UInt64 x = g_Crc64Table[(size_t)i - 256]; - g_Crc64Table[i] = CRC_UINT64_SWAP(x); + const UInt64 x = g_Crc64Table[i]; + g_Crc64Table[i] = Z7_BSWAP64(x); } - g_Crc64Update = XzCrc64UpdateT1_BeT4; } } - #endif +#endif // ndef MY_CPU_LE +#endif // Z7_CRC64_NUM_TABLES_USE != 1 } + +#undef kCrc64Poly +#undef Z7_CRC64_NUM_TABLES_USE +#undef FUNC_REF +#undef FUNC_NAME_LE_2 +#undef FUNC_NAME_LE_1 +#undef FUNC_NAME_LE +#undef FUNC_NAME_BE_2 +#undef FUNC_NAME_BE_1 +#undef FUNC_NAME_BE diff -Nru 7zip-22.01+dfsg/C/XzCrc64.h 7zip-22.01+really25.01+dfsg/C/XzCrc64.h --- 7zip-22.01+dfsg/C/XzCrc64.h 2013-01-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzCrc64.h 2023-12-08 10:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* XzCrc64.h -- CRC64 calculation -2013-01-18 : Igor Pavlov : Public domain */ +2023-12-08 : Igor Pavlov : Public domain */ -#ifndef __XZ_CRC64_H -#define __XZ_CRC64_H +#ifndef ZIP7_INC_XZ_CRC64_H +#define ZIP7_INC_XZ_CRC64_H #include @@ -10,16 +10,16 @@ EXTERN_C_BEGIN -extern UInt64 g_Crc64Table[]; +// extern UInt64 g_Crc64Table[]; -void MY_FAST_CALL Crc64GenerateTable(void); +void Z7_FASTCALL Crc64GenerateTable(void); #define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) #define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) -#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +// #define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size); -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size); +UInt64 Z7_FASTCALL Crc64Update(UInt64 crc, const void *data, size_t size); +// UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/XzCrc64Opt.c 7zip-22.01+really25.01+dfsg/C/XzCrc64Opt.c --- 7zip-22.01+dfsg/C/XzCrc64Opt.c 2021-02-09 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzCrc64Opt.c 2025-01-03 20:00:00.000000000 +0000 @@ -1,71 +1,261 @@ -/* XzCrc64Opt.c -- CRC64 calculation -2021-02-09 : Igor Pavlov : Public domain */ +/* XzCrc64Opt.c -- CRC64 calculation (optimized functions) +: Igor Pavlov : Public domain */ #include "Precomp.h" #include "CpuArch.h" +#if !defined(Z7_CRC64_NUM_TABLES) || Z7_CRC64_NUM_TABLES > 1 + +// for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC64_DEBUG_BE +#ifdef Z7_CRC64_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +#if defined(MY_CPU_64BIT) +#define Z7_CRC64_USE_64BIT +#endif + +// the value Z7_CRC64_NUM_TABLES_USE must be defined to same value as in XzCrc64.c +#ifdef Z7_CRC64_NUM_TABLES +#define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES +#else +#define Z7_CRC64_NUM_TABLES_USE 12 +#endif + +#if Z7_CRC64_NUM_TABLES_USE % 4 || \ + Z7_CRC64_NUM_TABLES_USE < 4 || \ + Z7_CRC64_NUM_TABLES_USE > 4 * 4 + #error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + + #ifndef MY_CPU_BE -#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +#if defined(Z7_CRC64_USE_64BIT) && (Z7_CRC64_NUM_TABLES_USE % 8 == 0) + +#define Q64LE(n, d) \ + ( (table + ((n) * 8 + 7) * 0x100)[((d) ) & 0xFF] \ + ^ (table + ((n) * 8 + 6) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 5) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 4) * 0x100)[((d) >> 3 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 3) * 0x100)[((d) >> 4 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 2) * 0x100)[((d) >> 5 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 1) * 0x100)[((d) >> 6 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 0) * 0x100)[((d) >> 7 * 8)] ) + +#define R64(a) *((const UInt64 *)(const void *)p + (a)) + +#else + +#define Q32LE(n, d) \ + ( (table + ((n) * 4 + 3) * 0x100)[((d) ) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] ) + +#define R32(a) *((const UInt32 *)(const void *)p + (a)) + +#endif + + +#define CRC64_FUNC_PRE_LE2(step) \ +UInt64 Z7_FASTCALL XzCrc64UpdateT ## step (UInt64 v, const void *data, size_t size, const UInt64 *table) + +#define CRC64_FUNC_PRE_LE(step) \ + CRC64_FUNC_PRE_LE2(step); \ + CRC64_FUNC_PRE_LE2(step) -UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +CRC64_FUNC_PRE_LE(Z7_CRC64_NUM_TABLES_USE) { const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + const Byte *lim; + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC64_NUM_TABLES_USE & 4))) != 0; size--, p++) v = CRC64_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) + lim = p + size; + if (size >= Z7_CRC64_NUM_TABLES_USE) { - UInt32 d = (UInt32)v ^ *(const UInt32 *)(const void *)p; - v = (v >> 32) - ^ (table + 0x300)[((d ) & 0xFF)] - ^ (table + 0x200)[((d >> 8) & 0xFF)] - ^ (table + 0x100)[((d >> 16) & 0xFF)] - ^ (table + 0x000)[((d >> 24))]; + lim -= Z7_CRC64_NUM_TABLES_USE; + do + { +#if Z7_CRC64_NUM_TABLES_USE == 4 + const UInt32 d = (UInt32)v ^ R32(0); + v = (v >> 32) ^ Q32LE(0, d); +#elif Z7_CRC64_NUM_TABLES_USE == 8 +#ifdef Z7_CRC64_USE_64BIT + v ^= R64(0); + v = Q64LE(0, v); +#else + UInt32 v0, v1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + v = Q32LE(1, v0) ^ Q32LE(0, v1); +#endif +#elif Z7_CRC64_NUM_TABLES_USE == 12 + UInt32 w; + UInt32 v0, v1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + w = R32(2); + v = Q32LE(0, w); + v ^= Q32LE(2, v0) ^ Q32LE(1, v1); +#elif Z7_CRC64_NUM_TABLES_USE == 16 +#ifdef Z7_CRC64_USE_64BIT + UInt64 w; + UInt64 x; + w = R64(1); x = Q64LE(0, w); + v ^= R64(0); v = x ^ Q64LE(1, v); +#else + UInt32 v0, v1; + UInt32 r0, r1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + r0 = R32(2); + r1 = R32(3); + v = Q32LE(1, r0) ^ Q32LE(0, r1); + v ^= Q32LE(3, v0) ^ Q32LE(2, v1); +#endif +#else +#error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + p += Z7_CRC64_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC64_NUM_TABLES_USE; } - for (; size > 0; size--, p++) + for (; p < lim; p++) v = CRC64_UPDATE_BYTE_2(v, *p); return v; } +#undef CRC64_UPDATE_BYTE_2 +#undef R32 +#undef R64 +#undef Q32LE +#undef Q64LE +#undef CRC64_FUNC_PRE_LE +#undef CRC64_FUNC_PRE_LE2 + #endif + + #ifndef MY_CPU_LE -#define CRC_UINT64_SWAP(v) \ - ((v >> 56) \ - | ((v >> 40) & ((UInt64)0xFF << 8)) \ - | ((v >> 24) & ((UInt64)0xFF << 16)) \ - | ((v >> 8) & ((UInt64)0xFF << 24)) \ - | ((v << 8) & ((UInt64)0xFF << 32)) \ - | ((v << 24) & ((UInt64)0xFF << 40)) \ - | ((v << 40) & ((UInt64)0xFF << 48)) \ - | ((v << 56))) +#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 56) ^ (b)] ^ ((crc) << 8)) + +#if defined(Z7_CRC64_USE_64BIT) && (Z7_CRC64_NUM_TABLES_USE % 8 == 0) + +#define Q64BE(n, d) \ + ( (table + ((n) * 8 + 0) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 8 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 3) * 0x100)[((d) >> 3 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 4) * 0x100)[((d) >> 4 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 5) * 0x100)[((d) >> 5 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 6) * 0x100)[((d) >> 6 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 7) * 0x100)[((d) >> 7 * 8)] ) + +#ifdef Z7_CRC64_DEBUG_BE + #define R64BE(a) GetBe64a((const UInt64 *)(const void *)p + (a)) +#else + #define R64BE(a) *((const UInt64 *)(const void *)p + (a)) +#endif + +#else + +#define Q32BE(n, d) \ + ( (table + ((n) * 4 + 0) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] ) + +#ifdef Z7_CRC64_DEBUG_BE + #define R32BE(a) GetBe32a((const UInt32 *)(const void *)p + (a)) +#else + #define R32BE(a) *((const UInt32 *)(const void *)p + (a)) +#endif + +#endif -#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8)) +#define CRC64_FUNC_PRE_BE2(step) \ +UInt64 Z7_FASTCALL XzCrc64UpdateBeT ## step (UInt64 v, const void *data, size_t size, const UInt64 *table) -UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +#define CRC64_FUNC_PRE_BE(step) \ + CRC64_FUNC_PRE_BE2(step); \ + CRC64_FUNC_PRE_BE2(step) + +CRC64_FUNC_PRE_BE(Z7_CRC64_NUM_TABLES_USE) { const Byte *p = (const Byte *)data; - table += 0x100; - v = CRC_UINT64_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + const Byte *lim; + v = Z7_BSWAP64(v); + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC64_NUM_TABLES_USE & 4))) != 0; size--, p++) v = CRC64_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 4; size -= 4, p += 4) + lim = p + size; + if (size >= Z7_CRC64_NUM_TABLES_USE) { - UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)(const void *)p; - v = (v << 32) - ^ (table + 0x000)[((d ) & 0xFF)] - ^ (table + 0x100)[((d >> 8) & 0xFF)] - ^ (table + 0x200)[((d >> 16) & 0xFF)] - ^ (table + 0x300)[((d >> 24))]; + lim -= Z7_CRC64_NUM_TABLES_USE; + do + { +#if Z7_CRC64_NUM_TABLES_USE == 4 + const UInt32 d = (UInt32)(v >> 32) ^ R32BE(0); + v = (v << 32) ^ Q32BE(0, d); +#elif Z7_CRC64_NUM_TABLES_USE == 12 + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + const UInt32 w = R32BE(2); + v = Q32BE(0, w); + v ^= Q32BE(2, d1) ^ Q32BE(1, d0); + +#elif Z7_CRC64_NUM_TABLES_USE == 8 + #ifdef Z7_CRC64_USE_64BIT + v ^= R64BE(0); + v = Q64BE(0, v); + #else + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + v = Q32BE(1, d1) ^ Q32BE(0, d0); + #endif +#elif Z7_CRC64_NUM_TABLES_USE == 16 + #ifdef Z7_CRC64_USE_64BIT + const UInt64 w = R64BE(1); + v ^= R64BE(0); + v = Q64BE(0, w) ^ Q64BE(1, v); + #else + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + const UInt32 w1 = R32BE(2); + const UInt32 w0 = R32BE(3); + v = Q32BE(1, w1) ^ Q32BE(0, w0); + v ^= Q32BE(3, d1) ^ Q32BE(2, d0); + #endif +#else +#error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + p += Z7_CRC64_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC64_NUM_TABLES_USE; } - for (; size > 0; size--, p++) + for (; p < lim; p++) v = CRC64_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT64_SWAP(v); + return Z7_BSWAP64(v); } +#undef CRC64_UPDATE_BYTE_2_BE +#undef R32BE +#undef R64BE +#undef Q32BE +#undef Q64BE +#undef CRC64_FUNC_PRE_BE +#undef CRC64_FUNC_PRE_BE2 + +#endif +#undef Z7_CRC64_NUM_TABLES_USE #endif diff -Nru 7zip-22.01+dfsg/C/XzDec.c 7zip-22.01+really25.01+dfsg/C/XzDec.c --- 7zip-22.01+dfsg/C/XzDec.c 2021-09-04 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzDec.c 2025-04-30 13:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* XzDec.c -- Xz Decode -2021-09-04 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -59,7 +59,7 @@ for (i = 0; i < limit;) { - Byte b = p[i]; + const unsigned b = p[i]; *value |= (UInt64)(b & 0x7F) << (7 * i++); if ((b & 0x80) == 0) return (b == 0 && i != 1) ? 0 : i; @@ -67,7 +67,8 @@ return 0; } -/* ---------- BraState ---------- */ + +/* ---------- XzBcFilterState ---------- */ #define BRA_BUF_SIZE (1 << 14) @@ -76,55 +77,60 @@ size_t bufPos; size_t bufConv; size_t bufTotal; + Byte *buf; // must be aligned for 4 bytes + Xz_Func_BcFilterStateBase_Filter filter_func; + // int encodeMode; + CXzBcFilterStateBase base; + // Byte buf[BRA_BUF_SIZE]; +} CXzBcFilterState; - int encodeMode; - - UInt32 methodId; - UInt32 delta; - UInt32 ip; - UInt32 x86State; - Byte deltaState[DELTA_STATE_SIZE]; - - Byte buf[BRA_BUF_SIZE]; -} CBraState; -static void BraState_Free(void *pp, ISzAllocPtr alloc) +static void XzBcFilterState_Free(void *pp, ISzAllocPtr alloc) { - ISzAlloc_Free(alloc, pp); + if (pp) + { + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + ISzAlloc_Free(alloc, p->buf); + ISzAlloc_Free(alloc, pp); + } } -static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) + +static SRes XzBcFilterState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) { - CBraState *p = ((CBraState *)pp); - UNUSED_VAR(alloc); + CXzBcFilterStateBase *p = &((CXzBcFilterState *)pp)->base; + UNUSED_VAR(alloc) p->ip = 0; if (p->methodId == XZ_ID_Delta) { if (propSize != 1) return SZ_ERROR_UNSUPPORTED; - p->delta = (unsigned)props[0] + 1; + p->delta = (UInt32)props[0] + 1; } else { if (propSize == 4) { - UInt32 v = GetUi32(props); + const UInt32 v = GetUi32(props); switch (p->methodId) { case XZ_ID_PPC: case XZ_ID_ARM: case XZ_ID_SPARC: - if ((v & 3) != 0) + case XZ_ID_ARM64: + if (v & 3) return SZ_ERROR_UNSUPPORTED; break; case XZ_ID_ARMT: - if ((v & 1) != 0) + case XZ_ID_RISCV: + if (v & 1) return SZ_ERROR_UNSUPPORTED; break; case XZ_ID_IA64: - if ((v & 0xF) != 0) + if (v & 0xf) return SZ_ERROR_UNSUPPORTED; break; + default: break; } p->ip = v; } @@ -134,73 +140,91 @@ return SZ_OK; } -static void BraState_Init(void *pp) + +static void XzBcFilterState_Init(void *pp) { - CBraState *p = ((CBraState *)pp); + CXzBcFilterState *p = ((CXzBcFilterState *)pp); p->bufPos = p->bufConv = p->bufTotal = 0; - x86_Convert_Init(p->x86State); - if (p->methodId == XZ_ID_Delta) - Delta_Init(p->deltaState); + p->base.X86_State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + if (p->base.methodId == XZ_ID_Delta) + Delta_Init(p->base.delta_State); } -#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: size = isa ## _Convert(data, size, p->ip, p->encodeMode); break; +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Dec[] = +{ + Z7_BRANCH_CONV_DEC_2 (BranchConv_PPC), + Z7_BRANCH_CONV_DEC_2 (BranchConv_IA64), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARMT), + Z7_BRANCH_CONV_DEC_2 (BranchConv_SPARC), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM64), + Z7_BRANCH_CONV_DEC_2 (BranchConv_RISCV) +}; -static SizeT BraState_Filter(void *pp, Byte *data, SizeT size) +static SizeT XzBcFilterStateBase_Filter_Dec(CXzBcFilterStateBase *p, Byte *data, SizeT size) { - CBraState *p = ((CBraState *)pp); switch (p->methodId) { case XZ_ID_Delta: - if (p->encodeMode) - Delta_Encode(p->deltaState, p->delta, data, size); - else - Delta_Decode(p->deltaState, p->delta, data, size); + Delta_Decode(p->delta_State, p->delta, data, size); break; case XZ_ID_X86: - size = x86_Convert(data, size, p->ip, &p->x86State, p->encodeMode); + size = (SizeT)(z7_BranchConvSt_X86_Dec(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Dec)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Dec[i](data, size, p->ip) - data); + } break; - CASE_BRA_CONV(PPC) - CASE_BRA_CONV(IA64) - CASE_BRA_CONV(ARM) - CASE_BRA_CONV(ARMT) - CASE_BRA_CONV(SPARC) } p->ip += (UInt32)size; return size; } -static SRes BraState_Code2(void *pp, +static SizeT XzBcFilterState_Filter(void *pp, Byte *data, SizeT size) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + return p->filter_func(&p->base, data, size); +} + + +static SRes XzBcFilterState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, int srcWasFinished, ECoderFinishMode finishMode, // int *wasFinished ECoderStatus *status) { - CBraState *p = ((CBraState *)pp); + CXzBcFilterState *p = ((CXzBcFilterState *)pp); SizeT destRem = *destLen; SizeT srcRem = *srcLen; - UNUSED_VAR(finishMode); + UNUSED_VAR(finishMode) *destLen = 0; *srcLen = 0; // *wasFinished = False; *status = CODER_STATUS_NOT_FINISHED; - while (destRem > 0) + while (destRem != 0) { - if (p->bufPos != p->bufConv) { size_t size = p->bufConv - p->bufPos; - if (size > destRem) - size = destRem; - memcpy(dest, p->buf + p->bufPos, size); - p->bufPos += size; - *destLen += size; - dest += size; - destRem -= size; - continue; + if (size) + { + if (size > destRem) + size = destRem; + memcpy(dest, p->buf + p->bufPos, size); + p->bufPos += size; + *destLen += size; + dest += size; + destRem -= size; + continue; + } } p->bufTotal -= p->bufPos; @@ -220,7 +244,7 @@ if (p->bufTotal == 0) break; - p->bufConv = BraState_Filter(pp, p->buf, p->bufTotal); + p->bufConv = p->filter_func(&p->base, p->buf, p->bufTotal); if (p->bufConv == 0) { @@ -240,27 +264,37 @@ } -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc); -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc) +#define XZ_IS_SUPPORTED_FILTER_ID(id) \ + ((id) >= XZ_ID_Delta && (id) <= XZ_ID_RISCV) + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc) { - CBraState *decoder; - if (id < XZ_ID_Delta || id > XZ_ID_SPARC) + CXzBcFilterState *decoder; + if (!XZ_IS_SUPPORTED_FILTER_ID(id)) return SZ_ERROR_UNSUPPORTED; - decoder = (CBraState *)p->p; + decoder = (CXzBcFilterState *)p->p; if (!decoder) { - decoder = (CBraState *)ISzAlloc_Alloc(alloc, sizeof(CBraState)); + decoder = (CXzBcFilterState *)ISzAlloc_Alloc(alloc, sizeof(CXzBcFilterState)); if (!decoder) return SZ_ERROR_MEM; + decoder->buf = ISzAlloc_Alloc(alloc, BRA_BUF_SIZE); + if (!decoder->buf) + { + ISzAlloc_Free(alloc, decoder); + return SZ_ERROR_MEM; + } p->p = decoder; - p->Free = BraState_Free; - p->SetProps = BraState_SetProps; - p->Init = BraState_Init; - p->Code2 = BraState_Code2; - p->Filter = BraState_Filter; + p->Free = XzBcFilterState_Free; + p->SetProps = XzBcFilterState_SetProps; + p->Init = XzBcFilterState_Init; + p->Code2 = XzBcFilterState_Code2; + p->Filter = XzBcFilterState_Filter; + decoder->filter_func = func; } - decoder->methodId = (UInt32)id; - decoder->encodeMode = encodeMode; + decoder->base.methodId = (UInt32)id; + // decoder->encodeMode = encodeMode; return SZ_OK; } @@ -279,9 +313,9 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) { - UNUSED_VAR(pp); - UNUSED_VAR(props); - UNUSED_VAR(alloc); + UNUSED_VAR(pp) + UNUSED_VAR(props) + UNUSED_VAR(alloc) return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; } @@ -297,7 +331,7 @@ { CSbDec *p = (CSbDec *)pp; SRes res; - UNUSED_VAR(srcWasFinished); + UNUSED_VAR(srcWasFinished) p->dest = dest; p->destLen = *destLen; p->src = src; @@ -389,7 +423,7 @@ ELzmaStatus status2; /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ SRes res; - UNUSED_VAR(srcWasFinished); + UNUSED_VAR(srcWasFinished) if (spec->outBufMode) { SizeT dicPos = spec->decoder.decoder.dicPos; @@ -420,7 +454,7 @@ p->Init = Lzma2State_Init; p->Code2 = Lzma2State_Code2; p->Filter = NULL; - Lzma2Dec_Construct(&spec->decoder); + Lzma2Dec_CONSTRUCT(&spec->decoder) } spec->outBufMode = False; if (outBuf) @@ -510,26 +544,24 @@ { IStateCoder *sc = &p->coders[coderIndex]; p->ids[coderIndex] = methodId; - switch (methodId) - { - case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); - #ifdef USE_SUBBLOCK - case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); - #endif - } + if (methodId == XZ_ID_LZMA2) + return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); +#ifdef USE_SUBBLOCK + if (methodId == XZ_ID_Subblock) + return SbState_SetFromMethod(sc, p->alloc); +#endif if (coderIndex == 0) return SZ_ERROR_UNSUPPORTED; - return BraState_SetFromMethod(sc, methodId, 0, p->alloc); + return Xz_StateCoder_Bc_SetFromMethod_Func(sc, methodId, + XzBcFilterStateBase_Filter_Dec, p->alloc); } static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) { IStateCoder *sc = &p->coders[coderIndex]; - switch (methodId) - { - case XZ_ID_LZMA2: return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); - } + if (methodId == XZ_ID_LZMA2) + return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); return SZ_ERROR_UNSUPPORTED; } @@ -568,7 +600,7 @@ SizeT destLen2, srcLen2; int wasFinished; - PRF_STR("------- MixCoder Single ----------"); + PRF_STR("------- MixCoder Single ----------") srcLen2 = srcLenOrig; destLen2 = destLenOrig; @@ -615,14 +647,14 @@ processed = coder->Filter(coder->p, p->outBuf, processed); if (wasFinished || (destFinish && p->outWritten == destLenOrig)) processed = p->outWritten; - PRF_STR_INT("filter", i); + PRF_STR_INT("filter", i) } *destLen = processed; } return res; } - PRF_STR("standard mix"); + PRF_STR("standard mix") if (p->numCoders != 1) { @@ -764,22 +796,21 @@ static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) { - return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) - && GetUi32(buf) == CrcCalc(buf + 4, 6) - && flags == GetBe16(buf + 8) - && buf[10] == XZ_FOOTER_SIG_0 - && buf[11] == XZ_FOOTER_SIG_1; + return indexSize == (((UInt64)GetUi32a(buf + 4) + 1) << 2) + && GetUi32a(buf) == CrcCalc(buf + 4, 6) + && flags == GetBe16a(buf + 8) + && GetUi16a(buf + 10) == (XZ_FOOTER_SIG_0 | (XZ_FOOTER_SIG_1 << 8)); } #define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + { const unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ if (s == 0) return SZ_ERROR_ARCHIVE; \ pos += s; } static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p) { - unsigned numFilters = XzBlock_GetNumFilters(p) - 1; + const unsigned numFilters = XzBlock_GetNumFilters(p) - 1; unsigned i; { const CXzFilter *f = &p->filters[numFilters]; @@ -795,8 +826,7 @@ if (f->propsSize != 1) return False; } - else if (f->id < XZ_ID_Delta - || f->id > XZ_ID_SPARC + else if (!XZ_IS_SUPPORTED_FILTER_ID(f->id) || (f->propsSize != 0 && f->propsSize != 4)) return False; } @@ -821,22 +851,24 @@ p->packSize = (UInt64)(Int64)-1; if (XzBlock_HasPackSize(p)) { - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize); + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize) if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) return SZ_ERROR_ARCHIVE; } p->unpackSize = (UInt64)(Int64)-1; if (XzBlock_HasUnpackSize(p)) - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize); + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize) + } numFilters = XzBlock_GetNumFilters(p); for (i = 0; i < numFilters; i++) { CXzFilter *filter = p->filters + i; UInt64 size; - READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id); - READ_VARINT_AND_CHECK(header, pos, headerSize, &size); + READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id) + READ_VARINT_AND_CHECK(header, pos, headerSize, &size) if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) return SZ_ERROR_ARCHIVE; filter->propsSize = (UInt32)size; @@ -894,20 +926,20 @@ MixCoder_Free(p); for (i = 0; i < numFilters; i++) { - RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)); + RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)) } p->numCoders = numFilters; } else { - RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)); + RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)) } for (i = 0; i < numFilters; i++) { const CXzFilter *f = &block->filters[numFilters - 1 - i]; IStateCoder *sc = &p->coders[i]; - RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)); + RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)) } MixCoder_Init(p); @@ -1001,7 +1033,7 @@ SRes res; ECoderFinishMode finishMode2 = finishMode; - BoolInt srcFinished2 = srcFinished; + BoolInt srcFinished2 = (BoolInt)srcFinished; BoolInt destFinish = False; if (p->block.packSize != (UInt64)(Int64)-1) @@ -1054,14 +1086,14 @@ (*destLen) += destLen2; p->unpackSize += destLen2; - RINOK(res); + RINOK(res) if (*status != CODER_STATUS_FINISHED_WITH_MARK) { if (p->block.packSize == p->packSize && *status == CODER_STATUS_NEEDS_MORE_INPUT) { - PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT"); + PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT") *status = CODER_STATUS_NOT_SPECIFIED; return SZ_ERROR_DATA; } @@ -1078,7 +1110,7 @@ if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize) || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize)) { - PRF_STR("ERROR: block.size mismatch"); + PRF_STR("ERROR: block.size mismatch") return SZ_ERROR_DATA; } } @@ -1094,7 +1126,7 @@ return SZ_OK; } - switch (p->state) + switch ((int)p->state) { case XZ_STATE_STREAM_HEADER: { @@ -1109,7 +1141,7 @@ } else { - RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); + RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)) p->numStartedStreams++; p->indexSize = 0; p->numBlocks = 0; @@ -1133,21 +1165,21 @@ p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); p->indexPos = p->indexPreSize; p->indexSize += p->indexPreSize; - Sha256_Final(&p->sha, p->shaDigest); + Sha256_Final(&p->sha, (Byte *)(void *)p->shaDigest32); Sha256_Init(&p->sha); p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); p->state = XZ_STATE_STREAM_INDEX; break; } - p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; + p->blockHeaderSize = ((unsigned)p->buf[0] << 2) + 4; break; } if (p->pos != p->blockHeaderSize) { - UInt32 cur = p->blockHeaderSize - p->pos; + unsigned cur = p->blockHeaderSize - p->pos; if (cur > srcRem) - cur = (UInt32)srcRem; + cur = (unsigned)srcRem; memcpy(p->buf + p->pos, src, cur); p->pos += cur; (*srcLen) += cur; @@ -1155,7 +1187,7 @@ } else { - RINOK(XzBlock_Parse(&p->block, p->buf)); + RINOK(XzBlock_Parse(&p->block, p->buf)) if (!XzBlock_AreSupportedFilters(&p->block)) return SZ_ERROR_UNSUPPORTED; p->numTotalBlocks++; @@ -1168,7 +1200,7 @@ p->headerParsedOk = True; return SZ_OK; } - RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)); + RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)) } break; } @@ -1189,8 +1221,8 @@ } else { - UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); - UInt32 cur = checkSize - p->pos; + const unsigned checkSize = XzFlags_GetCheckSize(p->streamFlags); + unsigned cur = checkSize - p->pos; if (cur != 0) { if (srcRem == 0) @@ -1199,7 +1231,7 @@ return SZ_OK; } if (cur > srcRem) - cur = (UInt32)srcRem; + cur = (unsigned)srcRem; memcpy(p->buf + p->pos, src, cur); p->pos += cur; (*srcLen) += cur; @@ -1208,10 +1240,10 @@ break; } { - Byte digest[XZ_CHECK_SIZE_MAX]; + UInt32 digest32[XZ_CHECK_SIZE_MAX / 4]; p->state = XZ_STATE_BLOCK_HEADER; p->pos = 0; - if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) + if (XzCheck_Final(&p->check, (void *)digest32) && memcmp(digest32, p->buf, checkSize) != 0) return SZ_ERROR_CRC; if (p->decodeOnlyOneBlock) { @@ -1256,12 +1288,12 @@ } else { - Byte digest[SHA256_DIGEST_SIZE]; + UInt32 digest32[SHA256_DIGEST_SIZE / 4]; p->state = XZ_STATE_STREAM_INDEX_CRC; p->indexSize += 4; p->pos = 0; - Sha256_Final(&p->sha, digest); - if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) + Sha256_Final(&p->sha, (void *)digest32); + if (memcmp(digest32, p->shaDigest32, SHA256_DIGEST_SIZE) != 0) return SZ_ERROR_CRC; } } @@ -1280,7 +1312,7 @@ const Byte *ptr = p->buf; p->state = XZ_STATE_STREAM_FOOTER; p->pos = 0; - if (CRC_GET_DIGEST(p->crc) != GetUi32(ptr)) + if (CRC_GET_DIGEST(p->crc) != GetUi32a(ptr)) return SZ_ERROR_CRC; } break; @@ -1288,9 +1320,9 @@ case XZ_STATE_STREAM_FOOTER: { - UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; + unsigned cur = XZ_STREAM_FOOTER_SIZE - p->pos; if (cur > srcRem) - cur = (UInt32)srcRem; + cur = (unsigned)srcRem; memcpy(p->buf + p->pos, src, cur); p->pos += cur; (*srcLen) += cur; @@ -1310,7 +1342,7 @@ { if (*src != 0) { - if (((UInt32)p->padSize & 3) != 0) + if ((unsigned)p->padSize & 3) return SZ_ERROR_NO_ARCHIVE; p->pos = 0; p->state = XZ_STATE_STREAM_HEADER; @@ -1325,6 +1357,8 @@ } case XZ_STATE_BLOCK: break; /* to disable GCC warning */ + + default: return SZ_ERROR_FAIL; } } /* @@ -1389,7 +1423,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "MtDec.h" #endif @@ -1400,7 +1434,7 @@ p->outStep_ST = 1 << 20; p->ignoreErrors = False; - #ifndef _7ZIP_ST + #ifndef Z7_ST p->numThreads = 1; p->inBufSize_MT = 1 << 18; p->memUseMax = sizeof(size_t) << 28; @@ -1409,7 +1443,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST /* ---------- CXzDecMtThread ---------- */ @@ -1448,7 +1482,7 @@ /* ---------- CXzDecMt ---------- */ -typedef struct +struct CXzDecMt { CAlignOffsetAlloc alignOffsetAlloc; ISzAllocPtr allocMid; @@ -1456,9 +1490,9 @@ CXzDecMtProps props; size_t unpackBlockMaxSize; - ISeqInStream *inStream; - ISeqOutStream *outStream; - ICompressProgress *progress; + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; BoolInt finishMode; BoolInt outSize_Defined; @@ -1481,7 +1515,7 @@ ECoderStatus status; SRes codeRes; - #ifndef _7ZIP_ST + #ifndef Z7_ST BoolInt mainDecoderWasCalled; // int statErrorDefined; int finishedDecoderIndex; @@ -1504,10 +1538,9 @@ BoolInt mtc_WasConstructed; CMtDec mtc; - CXzDecMtThread coders[MTDEC__THREADS_MAX]; + CXzDecMtThread coders[MTDEC_THREADS_MAX]; #endif - -} CXzDecMt; +}; @@ -1535,11 +1568,11 @@ XzDecMtProps_Init(&p->props); - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtc_WasConstructed = False; { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CXzDecMtThread *coder = &p->coders[i]; coder->dec_created = False; @@ -1549,16 +1582,16 @@ } #endif - return p; + return (CXzDecMtHandle)p; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void XzDecMt_FreeOutBufs(CXzDecMt *p) { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CXzDecMtThread *coder = &p->coders[i]; if (coder->outBuf) @@ -1595,13 +1628,15 @@ } -void XzDecMt_Destroy(CXzDecMtHandle pp) +// #define GET_CXzDecMt_p CXzDecMt *p = pp; + +void XzDecMt_Destroy(CXzDecMtHandle p) { - CXzDecMt *p = (CXzDecMt *)pp; + // GET_CXzDecMt_p XzDecMt_FreeSt(p); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtc_WasConstructed) { @@ -1610,7 +1645,7 @@ } { unsigned i; - for (i = 0; i < MTDEC__THREADS_MAX; i++) + for (i = 0; i < MTDEC_THREADS_MAX; i++) { CXzDecMtThread *t = &p->coders[i]; if (t->dec_created) @@ -1625,12 +1660,12 @@ #endif - ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, pp); + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) { @@ -1696,7 +1731,7 @@ coder->dec.parseMode = True; coder->dec.headerParsedOk = False; - PRF_STR_INT("Parse", srcSize2); + PRF_STR_INT("Parse", srcSize2) res = XzUnpacker_Code(&coder->dec, NULL, &destSize, @@ -1739,10 +1774,10 @@ } } { - UInt64 packSize = block->packSize; - UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); - UInt32 checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); - UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; + const UInt64 packSize = block->packSize; + const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + const unsigned checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); + const UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; // if (blockPackSum <= me->props.inBlockMax) // unpackBlockMaxSize { @@ -2071,7 +2106,7 @@ } data += cur; size -= cur; - // PRF_STR_INT("Written size =", size); + // PRF_STR_INT("Written size =", size) if (size == 0) break; res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0); @@ -2087,7 +2122,7 @@ return res; } - RINOK(res); + RINOK(res) if (coder->inPreSize != coder->inCodeSize || coder->blockPackTotal != coder->inCodeSize) @@ -2106,13 +2141,13 @@ // (coder->state == MTDEC_PARSE_END) means that there are no other working threads // so we can use mtc variables without lock - PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed); + PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed) me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; { CXzUnpacker *dec = &me->dec; - PRF_STR_INT("PostSingle", srcSize); + PRF_STR_INT("PostSingle", srcSize) { size_t srcProcessed = srcSize; @@ -2186,7 +2221,7 @@ me->mtc.crossEnd = srcSize; } - PRF_STR_INT("XZ_STATE_STREAM_HEADER crossEnd = ", (unsigned)me->mtc.crossEnd); + PRF_STR_INT("XZ_STATE_STREAM_HEADER crossEnd = ", (unsigned)me->mtc.crossEnd) return SZ_OK; } @@ -2277,7 +2312,7 @@ UInt64 inDelta = me->mtc.inProcessed - inProgressPrev; if (inDelta >= (1 << 22)) { - RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)); + RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)) inProgressPrev = me->mtc.inProcessed; } } @@ -2331,7 +2366,7 @@ */ static SRes XzDecMt_Decode_ST(CXzDecMt *p - #ifndef _7ZIP_ST + #ifndef Z7_ST , BoolInt tMode #endif , CXzStatInfo *stat) @@ -2343,11 +2378,11 @@ CXzUnpacker *dec; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (tMode) { XzDecMt_FreeOutBufs(p); - tMode = MtDec_PrepareRead(&p->mtc); + tMode = (BoolInt)MtDec_PrepareRead(&p->mtc); } #endif @@ -2400,7 +2435,7 @@ if (inPos == inLim) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (tMode) { inData = MtDec_Read(&p->mtc, &inLim); @@ -2577,19 +2612,19 @@ -SRes XzDecMt_Decode(CXzDecMtHandle pp, +SRes XzDecMt_Decode(CXzDecMtHandle p, const CXzDecMtProps *props, const UInt64 *outDataSize, int finishMode, - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, // Byte *outBuf, size_t *outBufSize, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, // const Byte *inData, size_t inDataSize, CXzStatInfo *stat, int *isMT, - ICompressProgress *progress) + ICompressProgressPtr progress) { - CXzDecMt *p = (CXzDecMt *)pp; - #ifndef _7ZIP_ST + // GET_CXzDecMt_p + #ifndef Z7_ST BoolInt tMode; #endif @@ -2610,7 +2645,7 @@ p->outSize = *outDataSize; } - p->finishMode = finishMode; + p->finishMode = (BoolInt)finishMode; // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test @@ -2640,7 +2675,7 @@ */ - #ifndef _7ZIP_ST + #ifndef Z7_ST p->isBlockHeaderState_Parse = False; p->isBlockHeaderState_Write = False; @@ -2782,7 +2817,7 @@ return res; } - PRF_STR("----- decoding ST -----"); + PRF_STR("----- decoding ST -----") } #endif @@ -2792,13 +2827,13 @@ { SRes res = XzDecMt_Decode_ST(p - #ifndef _7ZIP_ST + #ifndef Z7_ST , tMode #endif , stat ); - #ifndef _7ZIP_ST + #ifndef Z7_ST // we must set error code from MT decoding at first if (p->mainErrorCode != SZ_OK) stat->DecodeRes = p->mainErrorCode; @@ -2835,3 +2870,7 @@ return res; } } + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff -Nru 7zip-22.01+dfsg/C/XzEnc.c 7zip-22.01+really25.01+dfsg/C/XzEnc.c --- 7zip-22.01+dfsg/C/XzEnc.c 2021-04-01 17:13:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzEnc.c 2025-07-04 06:00:00.000000000 +0000 @@ -1,5 +1,5 @@ /* XzEnc.c -- Xz Encode -2021-04-01 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -18,42 +18,43 @@ #include "XzEnc.h" -// #define _7ZIP_ST +// #define Z7_ST -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "MtCoder.h" #else -#define MTCODER__THREADS_MAX 1 -#define MTCODER__BLOCKS_MAX 1 +#define MTCODER_THREADS_MAX 1 +#define MTCODER_BLOCKS_MAX 1 #endif #define XZ_GET_PAD_SIZE(dataSize) ((4 - ((unsigned)(dataSize) & 3)) & 3) -/* max pack size for LZMA2 block + check-64bytrs: */ -#define XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize) ((unpackSize) + ((unpackSize) >> 10) + 16 + 64) +#define XZ_CHECK_SIZE_MAX 64 +/* max pack size for LZMA2 block + pad4 + check_size: */ +#define XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize) ((unpackSize) + ((unpackSize) >> 10) + 16 + XZ_CHECK_SIZE_MAX) #define XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(unpackSize) (XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize)) -#define XzBlock_ClearFlags(p) (p)->flags = 0; -#define XzBlock_SetNumFilters(p, n) (p)->flags = (Byte)((p)->flags | ((n) - 1)); +// #define XzBlock_ClearFlags(p) (p)->flags = 0; +#define XzBlock_ClearFlags_SetNumFilters(p, n) (p)->flags = (Byte)((n) - 1); #define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; #define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; -static SRes WriteBytes(ISeqOutStream *s, const void *buf, size_t size) +static SRes WriteBytes(ISeqOutStreamPtr s, const void *buf, size_t size) { return (ISeqOutStream_Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; } -static SRes WriteBytesUpdateCrc(ISeqOutStream *s, const void *buf, size_t size, UInt32 *crc) +static SRes WriteBytes_UpdateCrc(ISeqOutStreamPtr s, const void *buf, size_t size, UInt32 *crc) { *crc = CrcUpdate(*crc, buf, size); return WriteBytes(s, buf, size); } -static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s) +static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStreamPtr s) { UInt32 crc; Byte header[XZ_STREAM_HEADER_SIZE]; @@ -61,12 +62,12 @@ header[XZ_SIG_SIZE] = (Byte)(f >> 8); header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); - SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc); + SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc) return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); } -static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s) +static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStreamPtr s) { Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; @@ -91,7 +92,7 @@ header[pos++] = 0; header[0] = (Byte)(pos >> 2); - SetUi32(header + pos, CrcCalc(header, pos)); + SetUi32(header + pos, CrcCalc(header, pos)) return WriteBytes(s, header, pos + 4); } @@ -182,7 +183,7 @@ size_t newSize = p->allocated * 2 + 16 * 2; if (newSize < p->size + pos) return SZ_ERROR_MEM; - RINOK(XzEncIndex_ReAlloc(p, newSize, alloc)); + RINOK(XzEncIndex_ReAlloc(p, newSize, alloc)) } memcpy(p->blocks + p->size, buf, pos); p->size += pos; @@ -191,7 +192,7 @@ } -static SRes XzEncIndex_WriteFooter(const CXzEncIndex *p, CXzStreamFlags flags, ISeqOutStream *s) +static SRes XzEncIndex_WriteFooter(const CXzEncIndex *p, CXzStreamFlags flags, ISeqOutStreamPtr s) { Byte buf[32]; UInt64 globalPos; @@ -200,8 +201,8 @@ globalPos = pos; buf[0] = 0; - RINOK(WriteBytesUpdateCrc(s, buf, pos, &crc)); - RINOK(WriteBytesUpdateCrc(s, p->blocks, p->size, &crc)); + RINOK(WriteBytes_UpdateCrc(s, buf, pos, &crc)) + RINOK(WriteBytes_UpdateCrc(s, p->blocks, p->size, &crc)) globalPos += p->size; pos = XZ_GET_PAD_SIZE(globalPos); @@ -211,12 +212,12 @@ globalPos += pos; crc = CrcUpdate(crc, buf + 4 - pos, pos); - SetUi32(buf + 4, CRC_GET_DIGEST(crc)); + SetUi32(buf + 4, CRC_GET_DIGEST(crc)) - SetUi32(buf + 8 + 4, (UInt32)(globalPos >> 2)); + SetUi32(buf + 8 + 4, (UInt32)(globalPos >> 2)) buf[8 + 8] = (Byte)(flags >> 8); buf[8 + 9] = (Byte)(flags & 0xFF); - SetUi32(buf + 8, CrcCalc(buf + 8 + 4, 6)); + SetUi32(buf + 8, CrcCalc(buf + 8 + 4, 6)) buf[8 + 10] = XZ_FOOTER_SIG_0; buf[8 + 11] = XZ_FOOTER_SIG_1; @@ -230,7 +231,7 @@ typedef struct { ISeqInStream vt; - ISeqInStream *realStream; + ISeqInStreamPtr realStream; const Byte *data; UInt64 limit; UInt64 processed; @@ -251,9 +252,9 @@ XzCheck_Final(&p->check, digest); } -static SRes SeqCheckInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +static SRes SeqCheckInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) { - CSeqCheckInStream *p = CONTAINER_FROM_VTBL(pp, CSeqCheckInStream, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqCheckInStream) size_t size2 = *size; SRes res = SZ_OK; @@ -285,15 +286,15 @@ typedef struct { ISeqOutStream vt; - ISeqOutStream *realStream; + ISeqOutStreamPtr realStream; Byte *outBuf; size_t outBufLimit; UInt64 processed; } CSeqSizeOutStream; -static size_t SeqSizeOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size) +static size_t SeqSizeOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) { - CSeqSizeOutStream *p = CONTAINER_FROM_VTBL(pp, CSeqSizeOutStream, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqSizeOutStream) if (p->realStream) size = ISeqOutStream_Write(p->realStream, data, size); else @@ -313,8 +314,8 @@ typedef struct { - ISeqInStream p; - ISeqInStream *realStream; + ISeqInStream vt; + ISeqInStreamPtr realStream; IStateCoder StateCoder; Byte *buf; size_t curPos; @@ -323,7 +324,40 @@ } CSeqInFilter; -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc); +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Enc[] = +{ + Z7_BRANCH_CONV_ENC_2 (BranchConv_PPC), + Z7_BRANCH_CONV_ENC_2 (BranchConv_IA64), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARM), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARMT), + Z7_BRANCH_CONV_ENC_2 (BranchConv_SPARC), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARM64), + Z7_BRANCH_CONV_ENC_2 (BranchConv_RISCV) +}; + +static SizeT XzBcFilterStateBase_Filter_Enc(CXzBcFilterStateBase *p, Byte *data, SizeT size) +{ + switch (p->methodId) + { + case XZ_ID_Delta: + Delta_Encode(p->delta_State, p->delta, data, size); + break; + case XZ_ID_X86: + size = (SizeT)(z7_BranchConvSt_X86_Enc(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Enc)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Enc[i](data, size, p->ip) - data); + } + break; + } + p->ip += (UInt32)size; + return size; +} + static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props, ISzAllocPtr alloc) { @@ -335,17 +369,17 @@ } p->curPos = p->endPos = 0; p->srcWasFinished = 0; - RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, alloc)); - RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, alloc)); + RINOK(Xz_StateCoder_Bc_SetFromMethod_Func(&p->StateCoder, props->id, XzBcFilterStateBase_Filter_Enc, alloc)) + RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, alloc)) p->StateCoder.Init(p->StateCoder.p); return SZ_OK; } -static SRes SeqInFilter_Read(const ISeqInStream *pp, void *data, size_t *size) +static SRes SeqInFilter_Read(ISeqInStreamPtr pp, void *data, size_t *size) { - CSeqInFilter *p = CONTAINER_FROM_VTBL(pp, CSeqInFilter, p); - size_t sizeOriginal = *size; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInFilter) + const size_t sizeOriginal = *size; if (sizeOriginal == 0) return SZ_OK; *size = 0; @@ -356,7 +390,7 @@ { p->curPos = 0; p->endPos = FILTER_BUF_SIZE; - RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos)); + RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos)) if (p->endPos == 0) p->srcWasFinished = 1; } @@ -377,13 +411,15 @@ } } +Z7_FORCE_INLINE static void SeqInFilter_Construct(CSeqInFilter *p) { p->buf = NULL; p->StateCoder.p = NULL; - p->p.Read = SeqInFilter_Read; + p->vt.Read = SeqInFilter_Read; } +Z7_FORCE_INLINE static void SeqInFilter_Free(CSeqInFilter *p, ISzAllocPtr alloc) { if (p->StateCoder.p) @@ -406,13 +442,13 @@ typedef struct { ISeqInStream vt; - ISeqInStream *inStream; + ISeqInStreamPtr inStream; CSbEnc enc; } CSbEncInStream; -static SRes SbEncInStream_Read(const ISeqInStream *pp, void *data, size_t *size) +static SRes SbEncInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) { - CSbEncInStream *p = CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt); + CSbEncInStream *p = Z7_CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt); size_t sizeOriginal = *size; if (sizeOriginal == 0) return SZ_OK; @@ -422,7 +458,7 @@ if (p->enc.needRead && !p->enc.readWasFinished) { size_t processed = p->enc.needReadSizeMax; - RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)); + RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)) p->enc.readPos += processed; if (processed == 0) { @@ -433,7 +469,7 @@ } *size = sizeOriginal; - RINOK(SbEnc_Read(&p->enc, data, size)); + RINOK(SbEnc_Read(&p->enc, data, size)) if (*size != 0 || !p->enc.needRead) return SZ_OK; } @@ -473,7 +509,8 @@ void XzProps_Init(CXzProps *p) { p->checkId = XZ_CHECK_CRC32; - p->blockSize = XZ_PROPS__BLOCK_SIZE__AUTO; + p->numThreadGroups = 0; + p->blockSize = XZ_PROPS_BLOCK_SIZE_AUTO; p->numBlockThreads_Reduced = -1; p->numBlockThreads_Max = -1; p->numTotalThreads = -1; @@ -502,8 +539,8 @@ t2 = p->numBlockThreads_Max; t3 = p->numTotalThreads; - if (t2 > MTCODER__THREADS_MAX) - t2 = MTCODER__THREADS_MAX; + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; if (t3 <= 0) { @@ -519,8 +556,8 @@ t1 = 1; t2 = t3; } - if (t2 > MTCODER__THREADS_MAX) - t2 = MTCODER__THREADS_MAX; + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; } else if (t1 <= 0) { @@ -571,7 +608,7 @@ /* we normalize xzProps properties, but we normalize only some of CXzProps::lzma2Props properties. Lzma2Enc_SetProps() will normalize lzma2Props later. */ - if (p->blockSize == XZ_PROPS__BLOCK_SIZE__SOLID) + if (p->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID) { p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; p->numBlockThreads_Reduced = 1; @@ -583,15 +620,15 @@ else { CLzma2EncProps *lzma2 = &p->lzma2Props; - if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) { // xz-auto p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; - if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) { // if (xz-auto && lzma2-solid) - we use solid for both - p->blockSize = XZ_PROPS__BLOCK_SIZE__SOLID; + p->blockSize = XZ_PROPS_BLOCK_SIZE_SOLID; p->numBlockThreads_Reduced = 1; p->numBlockThreads_Max = 1; if (p->lzma2Props.numTotalThreads <= 0) @@ -610,9 +647,9 @@ p->blockSize = tp.blockSize; // fixed or solid p->numBlockThreads_Reduced = tp.numBlockThreads_Reduced; p->numBlockThreads_Max = tp.numBlockThreads_Max; - if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) - lzma2->blockSize = tp.blockSize; // fixed or solid, LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID - if (lzma2->lzmaProps.reduceSize > tp.blockSize && tp.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = tp.blockSize; // fixed or solid, LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + if (lzma2->lzmaProps.reduceSize > tp.blockSize && tp.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) lzma2->lzmaProps.reduceSize = tp.blockSize; lzma2->numBlockThreads_Reduced = 1; lzma2->numBlockThreads_Max = 1; @@ -631,9 +668,9 @@ r = p->blockSize; lzma2->lzmaProps.reduceSize = r; } - if (lzma2->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO) - lzma2->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID; - else if (lzma2->blockSize > p->blockSize && lzma2->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID) + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + else if (lzma2->blockSize > p->blockSize && lzma2->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) lzma2->blockSize = p->blockSize; XzEncProps_Normalize_Fixed(p); @@ -655,6 +692,7 @@ } CLzma2WithFilters; +Z7_FORCE_INLINE static void Lzma2WithFilters_Construct(CLzma2WithFilters *p) { p->lzma2 = NULL; @@ -678,6 +716,7 @@ } +Z7_FORCE_INLINE static void Lzma2WithFilters_Free(CLzma2WithFilters *p, ISzAllocPtr alloc) { #ifdef USE_SUBBLOCK @@ -704,17 +743,17 @@ static SRes Xz_CompressBlock( CLzma2WithFilters *lzmaf, - ISeqOutStream *outStream, + ISeqOutStreamPtr outStream, Byte *outBufHeader, Byte *outBufData, size_t outBufDataLimit, - ISeqInStream *inStream, + ISeqInStreamPtr inStream, // UInt64 expectedSize, const Byte *inBuf, // used if (!inStream) size_t inBufSize, // used if (!inStream), it's block size, props->blockSize is ignored const CXzProps *props, - ICompressProgress *progress, + ICompressProgressPtr progress, int *inStreamFinished, /* only for inStream version */ CXzEncBlockInfo *blockSizes, ISzAllocPtr alloc, @@ -731,12 +770,12 @@ *inStreamFinished = False; - RINOK(Lzma2WithFilters_Create(lzmaf, alloc, allocBig)); + RINOK(Lzma2WithFilters_Create(lzmaf, alloc, allocBig)) - RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, &props->lzma2Props)); + RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, &props->lzma2Props)) - XzBlock_ClearFlags(&block); - XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); + // XzBlock_ClearFlags(&block) + XzBlock_ClearFlags_SetNumFilters(&block, 1 + (fp ? 1 : 0)) if (fp) { @@ -752,7 +791,7 @@ else if (fp->ipDefined) { Byte *ptr = filter->props; - SetUi32(ptr, fp->ip); + SetUi32(ptr, fp->ip) filter->propsSize = 4; } } @@ -777,13 +816,13 @@ if (props->blockSize != (UInt64)(Int64)-1) if (expectedSize > props->blockSize) block.unpackSize = props->blockSize; - XzBlock_SetHasUnpackSize(&block); + XzBlock_SetHasUnpackSize(&block) } */ if (outStream) { - RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)); + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) } checkInStream.vt.Read = SeqCheckInStream_Read; @@ -801,13 +840,13 @@ if (fp->id == XZ_ID_Subblock) { lzmaf->sb.inStream = &checkInStream.vt; - RINOK(SbEncInStream_Init(&lzmaf->sb)); + RINOK(SbEncInStream_Init(&lzmaf->sb)) } else #endif { lzmaf->filter.realStream = &checkInStream.vt; - RINOK(SeqInFilter_Init(&lzmaf->filter, filter, alloc)); + RINOK(SeqInFilter_Init(&lzmaf->filter, filter, alloc)) } } @@ -841,7 +880,7 @@ #ifdef USE_SUBBLOCK (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.vt: #endif - &lzmaf->filter.p) : + &lzmaf->filter.vt) : &checkInStream.vt) : NULL, useStream ? NULL : inBuf, @@ -852,13 +891,13 @@ if (outBuf) seqSizeOutStream.processed += outSize; - RINOK(res); + RINOK(res) blockSizes->unpackSize = checkInStream.processed; } { - Byte buf[4 + 64]; - unsigned padSize = XZ_GET_PAD_SIZE(seqSizeOutStream.processed); - UInt64 packSize = seqSizeOutStream.processed; + Byte buf[4 + XZ_CHECK_SIZE_MAX]; + const unsigned padSize = XZ_GET_PAD_SIZE(seqSizeOutStream.processed); + const UInt64 packSize = seqSizeOutStream.processed; buf[0] = 0; buf[1] = 0; @@ -866,7 +905,8 @@ buf[3] = 0; SeqCheckInStream_GetDigest(&checkInStream, buf + 4); - RINOK(WriteBytes(&seqSizeOutStream.vt, buf + (4 - padSize), padSize + XzFlags_GetCheckSize((CXzStreamFlags)props->checkId))); + RINOK(WriteBytes(&seqSizeOutStream.vt, buf + (4 - padSize), + padSize + XzFlags_GetCheckSize((CXzStreamFlags)props->checkId))) blockSizes->totalSize = seqSizeOutStream.processed - padSize; @@ -877,12 +917,12 @@ seqSizeOutStream.processed = 0; block.unpackSize = blockSizes->unpackSize; - XzBlock_SetHasUnpackSize(&block); + XzBlock_SetHasUnpackSize(&block) block.packSize = packSize; - XzBlock_SetHasPackSize(&block); + XzBlock_SetHasPackSize(&block) - RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)); + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) blockSizes->headerSize = (size_t)seqSizeOutStream.processed; blockSizes->totalSize += seqSizeOutStream.processed; @@ -906,15 +946,15 @@ typedef struct { ICompressProgress vt; - ICompressProgress *progress; + ICompressProgressPtr progress; UInt64 inOffset; UInt64 outOffset; } CCompressProgress_XzEncOffset; -static SRes CompressProgress_XzEncOffset_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) +static SRes CompressProgress_XzEncOffset_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) { - const CCompressProgress_XzEncOffset *p = CONTAINER_FROM_VTBL(pp, CCompressProgress_XzEncOffset, vt); + const CCompressProgress_XzEncOffset *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CCompressProgress_XzEncOffset, vt); inSize += p->inOffset; outSize += p->outOffset; return ICompressProgress_Progress(p->progress, inSize, outSize); @@ -923,7 +963,7 @@ -typedef struct +struct CXzEnc { ISzAllocPtr alloc; ISzAllocPtr allocBig; @@ -933,20 +973,19 @@ CXzEncIndex xzIndex; - CLzma2WithFilters lzmaf_Items[MTCODER__THREADS_MAX]; + CLzma2WithFilters lzmaf_Items[MTCODER_THREADS_MAX]; size_t outBufSize; /* size of allocated outBufs[i] */ - Byte *outBufs[MTCODER__BLOCKS_MAX]; + Byte *outBufs[MTCODER_BLOCKS_MAX]; - #ifndef _7ZIP_ST + #ifndef Z7_ST unsigned checkType; - ISeqOutStream *outStream; + ISeqOutStreamPtr outStream; BoolInt mtCoder_WasConstructed; CMtCoder mtCoder; - CXzEncBlockInfo EncBlocks[MTCODER__BLOCKS_MAX]; + CXzEncBlockInfo EncBlocks[MTCODER_BLOCKS_MAX]; #endif - -} CXzEnc; +}; static void XzEnc_Construct(CXzEnc *p) @@ -955,13 +994,13 @@ XzEncIndex_Construct(&p->xzIndex); - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) Lzma2WithFilters_Construct(&p->lzmaf_Items[i]); - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtCoder_WasConstructed = False; { - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) p->outBufs[i] = NULL; p->outBufSize = 0; } @@ -972,7 +1011,7 @@ static void XzEnc_FreeOutBufs(CXzEnc *p) { unsigned i; - for (i = 0; i < MTCODER__BLOCKS_MAX; i++) + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) if (p->outBufs[i]) { ISzAlloc_Free(p->alloc, p->outBufs[i]); @@ -988,10 +1027,10 @@ XzEncIndex_Free(&p->xzIndex, alloc); - for (i = 0; i < MTCODER__THREADS_MAX; i++) + for (i = 0; i < MTCODER_THREADS_MAX; i++) Lzma2WithFilters_Free(&p->lzmaf_Items[i], alloc); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtCoder_WasConstructed) { MtCoder_Destruct(&p->mtCoder); @@ -1013,37 +1052,38 @@ p->expectedDataSize = (UInt64)(Int64)-1; p->alloc = alloc; p->allocBig = allocBig; - return p; + return (CXzEncHandle)p; } +// #define GET_CXzEnc_p CXzEnc *p = (CXzEnc *)(void *)pp; -void XzEnc_Destroy(CXzEncHandle pp) +void XzEnc_Destroy(CXzEncHandle p) { - CXzEnc *p = (CXzEnc *)pp; + // GET_CXzEnc_p XzEnc_Free(p, p->alloc); ISzAlloc_Free(p->alloc, p); } -SRes XzEnc_SetProps(CXzEncHandle pp, const CXzProps *props) +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props) { - CXzEnc *p = (CXzEnc *)pp; + // GET_CXzEnc_p p->xzProps = *props; XzProps_Normalize(&p->xzProps); return SZ_OK; } -void XzEnc_SetDataSize(CXzEncHandle pp, UInt64 expectedDataSiize) +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize) { - CXzEnc *p = (CXzEnc *)pp; + // GET_CXzEnc_p p->expectedDataSize = expectedDataSiize; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, const Byte *src, size_t srcSize, int finished) @@ -1051,18 +1091,19 @@ CXzEnc *me = (CXzEnc *)pp; SRes res; CMtProgressThunk progressThunk; - - Byte *dest = me->outBufs[outBufIndex]; - + Byte *dest; UNUSED_VAR(finished) - { CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; bInfo->totalSize = 0; bInfo->unpackSize = 0; bInfo->headerSize = 0; + // v23.02: we don't compress empty blocks + // also we must ignore that empty block in XzEnc_MtCallback_Write() + if (srcSize == 0) + return SZ_OK; } - + dest = me->outBufs[outBufIndex]; if (!dest) { dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); @@ -1073,7 +1114,7 @@ MtProgressThunk_CreateVTable(&progressThunk); progressThunk.mtProgress = &me->mtCoder.mtProgress; - MtProgressThunk_Init(&progressThunk); + MtProgressThunk_INIT(&progressThunk) { CXzEncBlockInfo blockSizes; @@ -1108,27 +1149,29 @@ static SRes XzEnc_MtCallback_Write(void *pp, unsigned outBufIndex) { CXzEnc *me = (CXzEnc *)pp; - const CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; - const Byte *data = me->outBufs[outBufIndex]; - - RINOK(WriteBytes(me->outStream, data, bInfo->headerSize)); - + // v23.02: we don't write empty blocks + // note: if (bInfo->unpackSize == 0) then there is no compressed data of block + if (bInfo->unpackSize == 0) + return SZ_OK; { - UInt64 totalPackFull = bInfo->totalSize + XZ_GET_PAD_SIZE(bInfo->totalSize); - RINOK(WriteBytes(me->outStream, data + XZ_BLOCK_HEADER_SIZE_MAX, (size_t)totalPackFull - bInfo->headerSize)); + const Byte *data = me->outBufs[outBufIndex]; + RINOK(WriteBytes(me->outStream, data, bInfo->headerSize)) + { + const UInt64 totalPackFull = bInfo->totalSize + XZ_GET_PAD_SIZE(bInfo->totalSize); + RINOK(WriteBytes(me->outStream, data + XZ_BLOCK_HEADER_SIZE_MAX, (size_t)totalPackFull - bInfo->headerSize)) + } + return XzEncIndex_AddIndexRecord(&me->xzIndex, bInfo->unpackSize, bInfo->totalSize, me->alloc); } - - return XzEncIndex_AddIndexRecord(&me->xzIndex, bInfo->unpackSize, bInfo->totalSize, me->alloc); } #endif -SRes XzEnc_Encode(CXzEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress) { - CXzEnc *p = (CXzEnc *)pp; + // GET_CXzEnc_p const CXzProps *props = &p->xzProps; @@ -1137,7 +1180,7 @@ UInt64 numBlocks = 1; UInt64 blockSize = props->blockSize; - if (blockSize != XZ_PROPS__BLOCK_SIZE__SOLID + if (blockSize != XZ_PROPS_BLOCK_SIZE_SOLID && props->reduceSize != (UInt64)(Int64)-1) { numBlocks = props->reduceSize / blockSize; @@ -1147,13 +1190,13 @@ else blockSize = (UInt64)1 << 62; - RINOK(XzEncIndex_PreAlloc(&p->xzIndex, numBlocks, blockSize, XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(blockSize), p->alloc)); + RINOK(XzEncIndex_PreAlloc(&p->xzIndex, numBlocks, blockSize, XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(blockSize), p->alloc)) } - RINOK(Xz_WriteHeader((CXzStreamFlags)props->checkId, outStream)); + RINOK(Xz_WriteHeader((CXzStreamFlags)props->checkId, outStream)) - #ifndef _7ZIP_ST + #ifndef Z7_ST if (props->numBlockThreads_Reduced > 1) { IMtCoderCallback2 vt; @@ -1180,8 +1223,8 @@ p->mtCoder.mtCallback = &vt; p->mtCoder.mtCallbackObject = p; - if ( props->blockSize == XZ_PROPS__BLOCK_SIZE__SOLID - || props->blockSize == XZ_PROPS__BLOCK_SIZE__AUTO) + if ( props->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID + || props->blockSize == XZ_PROPS_BLOCK_SIZE_AUTO) return SZ_ERROR_FAIL; p->mtCoder.blockSize = (size_t)props->blockSize; @@ -1198,9 +1241,10 @@ } p->mtCoder.numThreadsMax = (unsigned)props->numBlockThreads_Max; + p->mtCoder.numThreadGroups = props->numThreadGroups; p->mtCoder.expectedDataSize = p->expectedDataSize; - RINOK(MtCoder_Code(&p->mtCoder)); + RINOK(MtCoder_Code(&p->mtCoder)) } else #endif @@ -1217,7 +1261,7 @@ writeStartSizes = 0; - if (props->blockSize != XZ_PROPS__BLOCK_SIZE__SOLID) + if (props->blockSize != XZ_PROPS_BLOCK_SIZE_SOLID) { writeStartSizes = (props->forceWriteSizesInHeader > 0); @@ -1274,18 +1318,18 @@ &inStreamFinished, &blockSizes, p->alloc, - p->allocBig)); + p->allocBig)) { UInt64 totalPackFull = blockSizes.totalSize + XZ_GET_PAD_SIZE(blockSizes.totalSize); if (writeStartSizes) { - RINOK(WriteBytes(outStream, p->outBufs[0], blockSizes.headerSize)); - RINOK(WriteBytes(outStream, bufData, (size_t)totalPackFull - blockSizes.headerSize)); + RINOK(WriteBytes(outStream, p->outBufs[0], blockSizes.headerSize)) + RINOK(WriteBytes(outStream, bufData, (size_t)totalPackFull - blockSizes.headerSize)) } - RINOK(XzEncIndex_AddIndexRecord(&p->xzIndex, blockSizes.unpackSize, blockSizes.totalSize, p->alloc)); + RINOK(XzEncIndex_AddIndexRecord(&p->xzIndex, blockSizes.unpackSize, blockSizes.totalSize, p->alloc)) progress2.inOffset += blockSizes.unpackSize; progress2.outOffset += totalPackFull; @@ -1302,8 +1346,8 @@ #include "Alloc.h" -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress) +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress) { SRes res; CXzEncHandle xz = XzEnc_Create(&g_Alloc, &g_BigAlloc); @@ -1317,7 +1361,7 @@ } -SRes Xz_EncodeEmpty(ISeqOutStream *outStream) +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream) { SRes res; CXzEncIndex xzIndex; diff -Nru 7zip-22.01+dfsg/C/XzEnc.h 7zip-22.01+really25.01+dfsg/C/XzEnc.h --- 7zip-22.01+dfsg/C/XzEnc.h 2017-06-27 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzEnc.h 2025-07-02 12:00:00.000000000 +0000 @@ -1,8 +1,8 @@ /* XzEnc.h -- Xz Encode -2017-06-27 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ -#ifndef __XZ_ENC_H -#define __XZ_ENC_H +#ifndef ZIP7_INC_XZ_ENC_H +#define ZIP7_INC_XZ_ENC_H #include "Lzma2Enc.h" @@ -11,8 +11,8 @@ EXTERN_C_BEGIN -#define XZ_PROPS__BLOCK_SIZE__AUTO LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO -#define XZ_PROPS__BLOCK_SIZE__SOLID LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID +#define XZ_PROPS_BLOCK_SIZE_AUTO LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO +#define XZ_PROPS_BLOCK_SIZE_SOLID LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID typedef struct @@ -31,6 +31,7 @@ CLzma2EncProps lzma2Props; CXzFilterProps filterProps; unsigned checkId; + unsigned numThreadGroups; // 0 : no groups UInt64 blockSize; int numBlockThreads_Reduced; int numBlockThreads_Max; @@ -41,19 +42,20 @@ void XzProps_Init(CXzProps *p); - -typedef void * CXzEncHandle; +typedef struct CXzEnc CXzEnc; +typedef CXzEnc * CXzEncHandle; +// Z7_DECLARE_HANDLE(CXzEncHandle) CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); void XzEnc_Destroy(CXzEncHandle p); SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props); void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize); -SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress); +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress); -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress); +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress); -SRes Xz_EncodeEmpty(ISeqOutStream *outStream); +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream); EXTERN_C_END diff -Nru 7zip-22.01+dfsg/C/XzIn.c 7zip-22.01+really25.01+dfsg/C/XzIn.c --- 7zip-22.01+dfsg/C/XzIn.c 2021-09-04 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/XzIn.c 2025-05-04 10:00:00.000000000 +0000 @@ -1,41 +1,44 @@ /* XzIn.c - Xz input -2021-09-04 : Igor Pavlov : Public domain */ +: Igor Pavlov : Public domain */ #include "Precomp.h" #include #include "7zCrc.h" -#include "CpuArch.h" #include "Xz.h" +#include "CpuArch.h" -/* -#define XZ_FOOTER_SIG_CHECK(p) (memcmp((p), XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0) -*/ -#define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1) - - -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) -{ - Byte sig[XZ_STREAM_HEADER_SIZE]; - RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) +#define XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(p) \ + (GetUi16a((const Byte *)(const void *)(p) + 10) == \ + (XZ_FOOTER_SIG_0 | (XZ_FOOTER_SIG_1 << 8))) + +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream) +{ + UInt32 data32[XZ_STREAM_HEADER_SIZE / 4]; + size_t processedSize = XZ_STREAM_HEADER_SIZE; + RINOK(SeqInStream_ReadMax(inStream, data32, &processedSize)) + if (processedSize != XZ_STREAM_HEADER_SIZE + || memcmp(data32, XZ_SIG, XZ_SIG_SIZE) != 0) return SZ_ERROR_NO_ARCHIVE; - return Xz_ParseHeader(p, sig); + return Xz_ParseHeader(p, (const Byte *)(const void *)data32); } -#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ +#define READ_VARINT_AND_CHECK(buf, size, res) \ +{ const unsigned s = Xz_ReadVarInt(buf, size, res); \ if (s == 0) return SZ_ERROR_ARCHIVE; \ - pos += s; } + size -= s; \ + buf += s; \ +} -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes) +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes) { + MY_ALIGN(4) Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; unsigned headerSize; *headerSizeRes = 0; - RINOK(SeqInStream_ReadByte(inStream, &header[0])); - headerSize = (unsigned)header[0]; + RINOK(SeqInStream_ReadByte(inStream, &header[0])) + headerSize = header[0]; if (headerSize == 0) { *headerSizeRes = 1; @@ -45,20 +48,31 @@ *isIndex = False; headerSize = (headerSize << 2) + 4; - *headerSizeRes = headerSize; - RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1)); + *headerSizeRes = (UInt32)headerSize; + { + size_t processedSize = headerSize - 1; + RINOK(SeqInStream_ReadMax(inStream, header + 1, &processedSize)) + if (processedSize != headerSize - 1) + return SZ_ERROR_INPUT_EOF; + } return XzBlock_Parse(p, header); } + #define ADD_SIZE_CHECK(size, val) \ - { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; } +{ const UInt64 newSize = size + (val); \ + if (newSize < size) return XZ_SIZE_OVERFLOW; \ + size = newSize; \ +} UInt64 Xz_GetUnpackSize(const CXzStream *p) { UInt64 size = 0; size_t i; for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECK(size, p->blocks[i].unpackSize); + { + ADD_SIZE_CHECK(size, p->blocks[i].unpackSize) + } return size; } @@ -67,167 +81,196 @@ UInt64 size = 0; size_t i; for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3); + { + ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3) + } return size; } -/* -SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) -{ - return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); -} -*/ -static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +// input; +// CXzStream (p) is empty object. +// size != 0 +// (size & 3) == 0 +// (buf) is aligned for at least 4 bytes. +// output: +// p->numBlocks is number of allocated items in p->blocks +// p->blocks[*] values must be ignored, if function returns error. +static SRes Xz_ParseIndex(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc) { - size_t numBlocks, pos = 1; - UInt32 crc; - + size_t numBlocks; if (size < 5 || buf[0] != 0) return SZ_ERROR_ARCHIVE; - size -= 4; - crc = CrcCalc(buf, size); - if (crc != GetUi32(buf + size)) - return SZ_ERROR_ARCHIVE; - + { + const UInt32 crc = CrcCalc(buf, size); + if (crc != GetUi32a(buf + size)) + return SZ_ERROR_ARCHIVE; + } + buf++; + size--; { UInt64 numBlocks64; - READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64); - numBlocks = (size_t)numBlocks64; - if (numBlocks != numBlocks64 || numBlocks * 2 > size) + READ_VARINT_AND_CHECK(buf, size, &numBlocks64) + // (numBlocks64) is 63-bit value, so we can calculate (numBlocks64 * 2): + if (numBlocks64 * 2 > size) return SZ_ERROR_ARCHIVE; + if (numBlocks64 >= ((size_t)1 << (sizeof(size_t) * 8 - 1)) / sizeof(CXzBlockSizes)) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE + numBlocks = (size_t)numBlocks64; } - - Xz_Free(p, alloc); - if (numBlocks != 0) + // Xz_Free(p, alloc); // it's optional, because (p) is empty already + if (numBlocks) { - size_t i; - p->numBlocks = numBlocks; - p->blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); - if (!p->blocks) + CXzBlockSizes *blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); + if (!blocks) return SZ_ERROR_MEM; - for (i = 0; i < numBlocks; i++) + p->blocks = blocks; + p->numBlocks = numBlocks; + // the caller will call Xz_Free() in case of error + do { - CXzBlockSizes *block = &p->blocks[i]; - READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize); - READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize); - if (block->totalSize == 0) + READ_VARINT_AND_CHECK(buf, size, &blocks->totalSize) + READ_VARINT_AND_CHECK(buf, size, &blocks->unpackSize) + if (blocks->totalSize == 0) return SZ_ERROR_ARCHIVE; + blocks++; } + while (--numBlocks); } - while ((pos & 3) != 0) - if (buf[pos++] != 0) + if (size >= 4) + return SZ_ERROR_ARCHIVE; + while (size) + if (buf[--size]) return SZ_ERROR_ARCHIVE; - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; + return SZ_OK; } -static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAllocPtr alloc) + +/* +static SRes Xz_ReadIndex(CXzStream *p, ILookInStreamPtr stream, UInt64 indexSize, ISzAllocPtr alloc) { SRes res; size_t size; Byte *buf; - if (indexSize > ((UInt32)1 << 31)) - return SZ_ERROR_UNSUPPORTED; + if (indexSize >= ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE size = (size_t)indexSize; - if (size != indexSize) - return SZ_ERROR_UNSUPPORTED; buf = (Byte *)ISzAlloc_Alloc(alloc, size); if (!buf) return SZ_ERROR_MEM; res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); if (res == SZ_OK) - res = Xz_ReadIndex2(p, buf, size, alloc); + res = Xz_ParseIndex(p, buf, size, alloc); ISzAlloc_Free(alloc, buf); return res; } +*/ -static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size) +static SRes LookInStream_SeekRead_ForArc(ILookInStreamPtr stream, UInt64 offset, void *buf, size_t size) { - RINOK(LookInStream_SeekTo(stream, offset)); + RINOK(LookInStream_SeekTo(stream, offset)) return LookInStream_Read(stream, buf, size); /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ } -static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc) + +/* +in: + (*startOffset) is position in (stream) where xz_stream must be finished. +out: + if returns SZ_OK, then (*startOffset) is position in stream that shows start of xz_stream. +*/ +static SRes Xz_ReadBackward(CXzStream *p, ILookInStreamPtr stream, Int64 *startOffset, ISzAllocPtr alloc) { - UInt64 indexSize; - Byte buf[XZ_STREAM_FOOTER_SIZE]; + #define TEMP_BUF_SIZE (1 << 10) + UInt32 buf32[TEMP_BUF_SIZE / 4]; UInt64 pos = (UInt64)*startOffset; - if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE) + if ((pos & 3) || pos < XZ_STREAM_FOOTER_SIZE) return SZ_ERROR_NO_ARCHIVE; - pos -= XZ_STREAM_FOOTER_SIZE; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, XZ_STREAM_FOOTER_SIZE)) - if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + if (!XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(buf32)) { - UInt32 total = 0; pos += XZ_STREAM_FOOTER_SIZE; - for (;;) { - size_t i; - #define TEMP_BUF_SIZE (1 << 10) - Byte temp[TEMP_BUF_SIZE]; - - i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; + // pos != 0 + // (pos & 3) == 0 + size_t i = pos >= TEMP_BUF_SIZE ? TEMP_BUF_SIZE : (size_t)pos; pos -= i; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)); - total += (UInt32)i; - for (; i != 0; i--) - if (temp[i - 1] != 0) + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, i)) + i /= 4; + do + if (buf32[i - 1] != 0) break; - if (i != 0) - { - if ((i & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - pos += i; - break; - } - if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) + while (--i); + + pos += i * 4; + #define XZ_STREAM_BACKWARD_READING_PAD_MAX (1 << 16) + // here we don't support rare case with big padding for xz stream. + // so we have padding limit for backward reading. + if ((UInt64)*startOffset - pos > XZ_STREAM_BACKWARD_READING_PAD_MAX) return SZ_ERROR_NO_ARCHIVE; + if (i) + break; } - + // we try to open xz stream after skipping zero padding. + // ((UInt64)*startOffset == pos) is possible here! if (pos < XZ_STREAM_FOOTER_SIZE) return SZ_ERROR_NO_ARCHIVE; pos -= XZ_STREAM_FOOTER_SIZE; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); - if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, XZ_STREAM_FOOTER_SIZE)) + if (!XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(buf32)) return SZ_ERROR_NO_ARCHIVE; } - p->flags = (CXzStreamFlags)GetBe16(buf + 8); - + p->flags = (CXzStreamFlags)GetBe16a(buf32 + 2); if (!XzFlags_IsSupported(p->flags)) return SZ_ERROR_UNSUPPORTED; - { /* to eliminate GCC 6.3 warning: dereferencing type-punned pointer will break strict-aliasing rules */ - const Byte *buf_ptr = buf; - if (GetUi32(buf_ptr) != CrcCalc(buf + 4, 6)) + const UInt32 *buf_ptr = buf32; + if (GetUi32a(buf_ptr) != CrcCalc(buf32 + 1, 6)) return SZ_ERROR_ARCHIVE; } - - indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; - - if (pos < indexSize) - return SZ_ERROR_ARCHIVE; - - pos -= indexSize; - RINOK(LookInStream_SeekTo(stream, pos)); - RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)); - { - UInt64 totalSize = Xz_GetPackSize(p); - if (totalSize == XZ_SIZE_OVERFLOW - || totalSize >= ((UInt64)1 << 63) - || pos < totalSize + XZ_STREAM_HEADER_SIZE) + const UInt64 indexSize = ((UInt64)GetUi32a(buf32 + 1) + 1) << 2; + if (pos < indexSize) return SZ_ERROR_ARCHIVE; - pos -= (totalSize + XZ_STREAM_HEADER_SIZE); - RINOK(LookInStream_SeekTo(stream, pos)); + pos -= indexSize; + // v25.00: relaxed indexSize check. We allow big index table. + // if (indexSize > ((UInt32)1 << 31)) + if (indexSize >= ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE + RINOK(LookInStream_SeekTo(stream, pos)) + // RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)) + { + SRes res; + const size_t size = (size_t)indexSize; + // if (size != indexSize) return SZ_ERROR_UNSUPPORTED; + Byte *buf = (Byte *)ISzAlloc_Alloc(alloc, size); + if (!buf) + return SZ_ERROR_MEM; + res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); + if (res == SZ_OK) + res = Xz_ParseIndex(p, buf, size, alloc); + ISzAlloc_Free(alloc, buf); + RINOK(res) + } + } + { + UInt64 total = Xz_GetPackSize(p); + if (total == XZ_SIZE_OVERFLOW || total >= ((UInt64)1 << 63)) + return SZ_ERROR_ARCHIVE; + total += XZ_STREAM_HEADER_SIZE; + if (pos < total) + return SZ_ERROR_ARCHIVE; + pos -= total; + RINOK(LookInStream_SeekTo(stream, pos)) *startOffset = (Int64)pos; } { @@ -235,8 +278,7 @@ CSecToRead secToRead; SecToRead_CreateVTable(&secToRead); secToRead.realStream = stream; - - RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)); + RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)) return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; } } @@ -246,8 +288,7 @@ void Xzs_Construct(CXzs *p) { - p->num = p->numAllocated = 0; - p->streams = 0; + Xzs_CONSTRUCT(p) } void Xzs_Free(CXzs *p, ISzAllocPtr alloc) @@ -257,7 +298,7 @@ Xz_Free(&p->streams[i], alloc); ISzAlloc_Free(alloc, p->streams); p->num = p->numAllocated = 0; - p->streams = 0; + p->streams = NULL; } UInt64 Xzs_GetNumBlocks(const CXzs *p) @@ -274,7 +315,9 @@ UInt64 size = 0; size_t i; for (i = 0; i < p->num; i++) - ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])); + { + ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])) + } return size; } @@ -284,42 +327,59 @@ UInt64 size = 0; size_t i; for (i = 0; i < p->num; i++) - ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])); + { + ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])) + } return size; } */ -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc) +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr stream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc) { Int64 endOffset = 0; - RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)); + // it's supposed that CXzs object is empty here. + // if CXzs object is not empty, it will add new streams to that non-empty object. + // Xzs_Free(p, alloc); // it's optional call to empty CXzs object. + RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)) *startOffset = endOffset; for (;;) { CXzStream st; SRes res; - Xz_Construct(&st); + Xz_CONSTRUCT(&st) res = Xz_ReadBackward(&st, stream, startOffset, alloc); + // if (res == SZ_OK), then (*startOffset) is start offset of new stream if + // if (res != SZ_OK), then (*startOffset) is unchend or it's expected start offset of stream with error st.startOffset = (UInt64)*startOffset; - RINOK(res); + // we must store (st) object to array, or we must free (st) local object. + if (res != SZ_OK) + { + Xz_Free(&st, alloc); + return res; + } if (p->num == p->numAllocated) { const size_t newNum = p->num + p->num / 4 + 1; void *data = ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream)); if (!data) + { + Xz_Free(&st, alloc); return SZ_ERROR_MEM; + } p->numAllocated = newNum; if (p->num != 0) memcpy(data, p->streams, p->num * sizeof(CXzStream)); ISzAlloc_Free(alloc, p->streams); p->streams = (CXzStream *)data; } + // we use direct copying of raw data from local variable (st) to object in array. + // so we don't need to call Xz_Free(&st, alloc) after copying and after p->num++ p->streams[p->num++] = st; if (*startOffset == 0) - break; - RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)); + return SZ_OK; + // seek operation is optional: + // RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)) if (progress && ICompressProgress_Progress(progress, (UInt64)(endOffset - *startOffset), (UInt64)(Int64)-1) != SZ_OK) return SZ_ERROR_PROGRESS; } - return SZ_OK; } diff -Nru 7zip-22.01+dfsg/C/ZstdDec.c 7zip-22.01+really25.01+dfsg/C/ZstdDec.c --- 7zip-22.01+dfsg/C/ZstdDec.c 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/ZstdDec.c 2024-06-18 06:00:00.000000000 +0000 @@ -0,0 +1,4067 @@ +/* ZstdDec.c -- Zstd Decoder +2024-06-18 : the code was developed by Igor Pavlov, using Zstandard format + specification and original zstd decoder code as reference code. +original zstd decoder code: Copyright (c) Facebook, Inc. All rights reserved. +This source code is licensed under BSD 3-Clause License. +*/ + +#include "Precomp.h" + +#include +#include +// #include + +#include "Alloc.h" +#include "Xxh64.h" +#include "ZstdDec.h" +#include "CpuArch.h" + +#if defined(MY_CPU_ARM64) +#include +#endif + +/* original-zstd still doesn't support window larger than 2 GiB. + So we also limit our decoder for 2 GiB window: */ +#if defined(MY_CPU_64BIT) && 0 == 1 + #define MAX_WINDOW_SIZE_LOG 41 +#else + #define MAX_WINDOW_SIZE_LOG 31 +#endif + +typedef + #if MAX_WINDOW_SIZE_LOG < 32 + UInt32 + #else + size_t + #endif + CZstdDecOffset; + +// for debug: simpler and smaller code but slow: +// #define Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + +// #define SHOW_STAT +#ifdef SHOW_STAT +#include +static unsigned g_Num_Blocks_Compressed = 0; +static unsigned g_Num_Blocks_memcpy = 0; +static unsigned g_Num_Wrap_memmove_Num = 0; +static unsigned g_Num_Wrap_memmove_Bytes = 0; +static unsigned g_NumSeqs_total = 0; +// static unsigned g_NumCopy = 0; +static unsigned g_NumOver = 0; +static unsigned g_NumOver2 = 0; +static unsigned g_Num_Match = 0; +static unsigned g_Num_Lits = 0; +static unsigned g_Num_LitsBig = 0; +static unsigned g_Num_Lit0 = 0; +static unsigned g_Num_Rep0 = 0; +static unsigned g_Num_Rep1 = 0; +static unsigned g_Num_Rep2 = 0; +static unsigned g_Num_Rep3 = 0; +static unsigned g_Num_Threshold_0 = 0; +static unsigned g_Num_Threshold_1 = 0; +static unsigned g_Num_Threshold_0sum = 0; +static unsigned g_Num_Threshold_1sum = 0; +#define STAT_UPDATE(v) v +#else +#define STAT_UPDATE(v) +#endif +#define STAT_INC(v) STAT_UPDATE(v++;) + + +typedef struct +{ + const Byte *ptr; + size_t len; +} +CInBufPair; + + +#if defined(MY_CPU_ARM_OR_ARM64) || defined(MY_CPU_X86_OR_AMD64) + #if (defined(__clang__) && (__clang_major__ >= 6)) \ + || (defined(__GNUC__) && (__GNUC__ >= 6)) + // disable for debug: + #define Z7_ZSTD_DEC_USE_BSR + #elif defined(_MSC_VER) && (_MSC_VER >= 1300) + // #if defined(MY_CPU_ARM_OR_ARM64) + #if (_MSC_VER >= 1600) + #include + #endif + // disable for debug: + #define Z7_ZSTD_DEC_USE_BSR + #endif +#endif + +#ifdef Z7_ZSTD_DEC_USE_BSR + #if defined(__clang__) || defined(__GNUC__) + #define MY_clz(x) ((unsigned)__builtin_clz((UInt32)x)) + #else // #if defined(_MSC_VER) + #ifdef MY_CPU_ARM_OR_ARM64 + #define MY_clz _CountLeadingZeros + #endif // MY_CPU_X86_OR_AMD64 + #endif // _MSC_VER +#elif !defined(Z7_ZSTD_DEC_USE_LOG_TABLE) + #define Z7_ZSTD_DEC_USE_LOG_TABLE +#endif + + +static +Z7_FORCE_INLINE +unsigned GetHighestSetBit_32_nonzero_big(UInt32 num) +{ + // (num != 0) + #ifdef MY_clz + return 31 - MY_clz(num); + #elif defined(Z7_ZSTD_DEC_USE_BSR) + { + unsigned long zz; + _BitScanReverse(&zz, num); + return zz; + } + #else + { + int i = -1; + for (;;) + { + i++; + num >>= 1; + if (num == 0) + return (unsigned)i; + } + } + #endif +} + +#ifdef Z7_ZSTD_DEC_USE_LOG_TABLE + +#define R1(a) a, a +#define R2(a) R1(a), R1(a) +#define R3(a) R2(a), R2(a) +#define R4(a) R3(a), R3(a) +#define R5(a) R4(a), R4(a) +#define R6(a) R5(a), R5(a) +#define R7(a) R6(a), R6(a) +#define R8(a) R7(a), R7(a) +#define R9(a) R8(a), R8(a) + +#define Z7_ZSTD_FSE_MAX_ACCURACY 9 +// states[] values in FSE_Generate() can use (Z7_ZSTD_FSE_MAX_ACCURACY + 1) bits. +static const Byte k_zstd_LogTable[2 << Z7_ZSTD_FSE_MAX_ACCURACY] = +{ + R1(0), R1(1), R2(2), R3(3), R4(4), R5(5), R6(6), R7(7), R8(8), R9(9) +}; + +#define GetHighestSetBit_32_nonzero_small(num) (k_zstd_LogTable[num]) +#else +#define GetHighestSetBit_32_nonzero_small GetHighestSetBit_32_nonzero_big +#endif + + +#ifdef MY_clz + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + bitOffset -= (CBitCtr)(MY_clz(b) - 23); +#elif defined(Z7_ZSTD_DEC_USE_BSR) + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + { unsigned long zz; _BitScanReverse(&zz, b); bitOffset -= 8; bitOffset += zz; } +#else + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + for (;;) { bitOffset--; if (b & 0x80) { break; } b <<= 1; } +#endif + +#define SET_bitOffset_TO_PAD(bitOffset, src, srcLen) \ +{ \ + unsigned lastByte = (src)[(size_t)(srcLen) - 1]; \ + if (lastByte == 0) return SZ_ERROR_DATA; \ + bitOffset = (CBitCtr)((srcLen) * 8); \ + UPDATE_BIT_OFFSET_FOR_PADDING(lastByte, bitOffset) \ +} + +#ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + +#define SET_bitOffset_TO_PAD_and_SET_BIT_SIZE(bitOffset, src, srcLen_res) \ +{ \ + unsigned lastByte = (src)[(size_t)(srcLen_res) - 1]; \ + if (lastByte == 0) return SZ_ERROR_DATA; \ + srcLen_res *= 8; \ + bitOffset = (CBitCtr)srcLen_res; \ + UPDATE_BIT_OFFSET_FOR_PADDING(lastByte, bitOffset) \ +} + +#endif + +/* +typedef Int32 CBitCtr_signed; +typedef Int32 CBitCtr; +*/ +// /* +typedef ptrdiff_t CBitCtr_signed; +typedef ptrdiff_t CBitCtr; +// */ + + +#define MATCH_LEN_MIN 3 +#define kBlockSizeMax (1u << 17) + +// #define Z7_ZSTD_DEC_PRINT_TABLE + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE +#define NUM_OFFSET_SYMBOLS_PREDEF 29 +#endif +#define NUM_OFFSET_SYMBOLS_MAX (MAX_WINDOW_SIZE_LOG + 1) // 32 +#define NUM_LL_SYMBOLS 36 +#define NUM_ML_SYMBOLS 53 +#define FSE_NUM_SYMBOLS_MAX 53 // NUM_ML_SYMBOLS + +// /* +#if !defined(MY_CPU_X86) || defined(__PIC__) || defined(MY_CPU_64BIT) +#define Z7_ZSTD_DEC_USE_BASES_IN_OBJECT +#endif +// */ +// for debug: +// #define Z7_ZSTD_DEC_USE_BASES_LOCAL +// #define Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + +#define GLOBAL_TABLE(n) k_ ## n + +#if defined(Z7_ZSTD_DEC_USE_BASES_LOCAL) + #define BASES_TABLE(n) a_ ## n +#elif defined(Z7_ZSTD_DEC_USE_BASES_IN_OBJECT) + #define BASES_TABLE(n) p->m_ ## n +#else + #define BASES_TABLE(n) GLOBAL_TABLE(n) +#endif + +#define Z7_ZSTD_DEC_USE_ML_PLUS3 + +#if defined(Z7_ZSTD_DEC_USE_BASES_LOCAL) || \ + defined(Z7_ZSTD_DEC_USE_BASES_IN_OBJECT) + +#define SEQ_EXTRA_TABLES(n) \ + Byte n ## SEQ_LL_EXTRA [NUM_LL_SYMBOLS]; \ + Byte n ## SEQ_ML_EXTRA [NUM_ML_SYMBOLS]; \ + UInt32 n ## SEQ_LL_BASES [NUM_LL_SYMBOLS]; \ + UInt32 n ## SEQ_ML_BASES [NUM_ML_SYMBOLS]; \ + +#define Z7_ZSTD_DEC_USE_BASES_CALC + +#ifdef Z7_ZSTD_DEC_USE_BASES_CALC + + #define FILL_LOC_BASES(n, startSum) \ + { unsigned i; UInt32 sum = startSum; \ + for (i = 0; i != Z7_ARRAY_SIZE(GLOBAL_TABLE(n ## _EXTRA)); i++) \ + { const unsigned a = GLOBAL_TABLE(n ## _EXTRA)[i]; \ + BASES_TABLE(n ## _BASES)[i] = sum; \ + /* if (sum != GLOBAL_TABLE(n ## _BASES)[i]) exit(1); */ \ + sum += (UInt32)1 << a; \ + BASES_TABLE(n ## _EXTRA)[i] = (Byte)a; }} + + #define FILL_LOC_BASES_ALL \ + FILL_LOC_BASES (SEQ_LL, 0) \ + FILL_LOC_BASES (SEQ_ML, MATCH_LEN_MIN) \ + +#else + #define COPY_GLOBAL_ARR(n) \ + memcpy(BASES_TABLE(n), GLOBAL_TABLE(n), sizeof(GLOBAL_TABLE(n))); + #define FILL_LOC_BASES_ALL \ + COPY_GLOBAL_ARR (SEQ_LL_EXTRA) \ + COPY_GLOBAL_ARR (SEQ_ML_EXTRA) \ + COPY_GLOBAL_ARR (SEQ_LL_BASES) \ + COPY_GLOBAL_ARR (SEQ_ML_BASES) \ + +#endif + +#endif + + + +/// The sequence decoding baseline and number of additional bits to read/add +#if !defined(Z7_ZSTD_DEC_USE_BASES_CALC) +static const UInt32 GLOBAL_TABLE(SEQ_LL_BASES) [NUM_LL_SYMBOLS] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 +}; +#endif + +static const Byte GLOBAL_TABLE(SEQ_LL_EXTRA) [NUM_LL_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16 +}; + +#if !defined(Z7_ZSTD_DEC_USE_BASES_CALC) +static const UInt32 GLOBAL_TABLE(SEQ_ML_BASES) [NUM_ML_SYMBOLS] = +{ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 +}; +#endif + +static const Byte GLOBAL_TABLE(SEQ_ML_EXTRA) [NUM_ML_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16 +}; + + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE + +static const Int16 SEQ_LL_PREDEF_DIST [NUM_LL_SYMBOLS] = +{ + 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 +}; +static const Int16 SEQ_OFFSET_PREDEF_DIST [NUM_OFFSET_SYMBOLS_PREDEF] = +{ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 +}; +static const Int16 SEQ_ML_PREDEF_DIST [NUM_ML_SYMBOLS] = +{ + 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 +}; + +#endif + +// typedef int FastInt; +// typedef Int32 FastInt32; +typedef unsigned FastInt; +typedef UInt32 FastInt32; +typedef FastInt32 CFseRecord; + + +#define FSE_REC_LEN_OFFSET 8 +#define FSE_REC_STATE_OFFSET 16 +#define GET_FSE_REC_SYM(st) ((Byte)(st)) +#define GET_FSE_REC_LEN(st) ((Byte)((st) >> FSE_REC_LEN_OFFSET)) +#define GET_FSE_REC_STATE(st) ((st) >> FSE_REC_STATE_OFFSET) + +// #define FSE_REC_SYM_MASK (0xff) +// #define GET_FSE_REC_SYM(st) (st & FSE_REC_SYM_MASK) + +#define W_BASE(state, len, sym) \ + (((UInt32)state << (4 + FSE_REC_STATE_OFFSET)) + \ + (len << FSE_REC_LEN_OFFSET) + (sym)) +#define W(state, len, sym) W_BASE(state, len, sym) +static const CFseRecord k_PredefRecords_LL[1 << 6] = { +W(0,4, 0),W(1,4, 0),W(2,5, 1),W(0,5, 3),W(0,5, 4),W(0,5, 6),W(0,5, 7),W(0,5, 9), +W(0,5,10),W(0,5,12),W(0,6,14),W(0,5,16),W(0,5,18),W(0,5,19),W(0,5,21),W(0,5,22), +W(0,5,24),W(2,5,25),W(0,5,26),W(0,6,27),W(0,6,29),W(0,6,31),W(2,4, 0),W(0,4, 1), +W(0,5, 2),W(2,5, 4),W(0,5, 5),W(2,5, 7),W(0,5, 8),W(2,5,10),W(0,5,11),W(0,6,13), +W(2,5,16),W(0,5,17),W(2,5,19),W(0,5,20),W(2,5,22),W(0,5,23),W(0,4,25),W(1,4,25), +W(2,5,26),W(0,6,28),W(0,6,30),W(3,4, 0),W(1,4, 1),W(2,5, 2),W(2,5, 3),W(2,5, 5), +W(2,5, 6),W(2,5, 8),W(2,5, 9),W(2,5,11),W(2,5,12),W(0,6,15),W(2,5,17),W(2,5,18), +W(2,5,20),W(2,5,21),W(2,5,23),W(2,5,24),W(0,6,35),W(0,6,34),W(0,6,33),W(0,6,32) +}; +static const CFseRecord k_PredefRecords_OF[1 << 5] = { +W(0,5, 0),W(0,4, 6),W(0,5, 9),W(0,5,15),W(0,5,21),W(0,5, 3),W(0,4, 7),W(0,5,12), +W(0,5,18),W(0,5,23),W(0,5, 5),W(0,4, 8),W(0,5,14),W(0,5,20),W(0,5, 2),W(1,4, 7), +W(0,5,11),W(0,5,17),W(0,5,22),W(0,5, 4),W(1,4, 8),W(0,5,13),W(0,5,19),W(0,5, 1), +W(1,4, 6),W(0,5,10),W(0,5,16),W(0,5,28),W(0,5,27),W(0,5,26),W(0,5,25),W(0,5,24) +}; +#if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) +#undef W +#define W(state, len, sym) W_BASE(state, len, (sym + MATCH_LEN_MIN)) +#endif +static const CFseRecord k_PredefRecords_ML[1 << 6] = { +W(0,6, 0),W(0,4, 1),W(2,5, 2),W(0,5, 3),W(0,5, 5),W(0,5, 6),W(0,5, 8),W(0,6,10), +W(0,6,13),W(0,6,16),W(0,6,19),W(0,6,22),W(0,6,25),W(0,6,28),W(0,6,31),W(0,6,33), +W(0,6,35),W(0,6,37),W(0,6,39),W(0,6,41),W(0,6,43),W(0,6,45),W(1,4, 1),W(0,4, 2), +W(2,5, 3),W(0,5, 4),W(2,5, 6),W(0,5, 7),W(0,6, 9),W(0,6,12),W(0,6,15),W(0,6,18), +W(0,6,21),W(0,6,24),W(0,6,27),W(0,6,30),W(0,6,32),W(0,6,34),W(0,6,36),W(0,6,38), +W(0,6,40),W(0,6,42),W(0,6,44),W(2,4, 1),W(3,4, 1),W(1,4, 2),W(2,5, 4),W(2,5, 5), +W(2,5, 7),W(2,5, 8),W(0,6,11),W(0,6,14),W(0,6,17),W(0,6,20),W(0,6,23),W(0,6,26), +W(0,6,29),W(0,6,52),W(0,6,51),W(0,6,50),W(0,6,49),W(0,6,48),W(0,6,47),W(0,6,46) +}; + + +// sum of freqs[] must be correct +// (numSyms != 0) +// (accuracy >= 5) +static +Z7_NO_INLINE +// Z7_FORCE_INLINE +void FSE_Generate(CFseRecord *table, + const Int16 *const freqs, const size_t numSyms, + const unsigned accuracy, UInt32 delta) +{ + size_t size = (size_t)1 << accuracy; + // max value in states[x] is ((1 << accuracy) * 2) + UInt16 states[FSE_NUM_SYMBOLS_MAX]; + { + /* Symbols with "less than 1" probability get a single cell, + starting from the end of the table. + These symbols define a full state reset, reading (accuracy) bits. */ + size_t threshold = size; + { + size_t s = 0; + do + if (freqs[s] == -1) + { + table[--threshold] = (CFseRecord)s; + states[s] = 1; + } + while (++s != numSyms); + } + + #ifdef SHOW_STAT + if (threshold == size) + { + STAT_INC(g_Num_Threshold_0) + STAT_UPDATE(g_Num_Threshold_0sum += (unsigned)size;) + } + else + { + STAT_INC(g_Num_Threshold_1) + STAT_UPDATE(g_Num_Threshold_1sum += (unsigned)size;) + } + #endif + + // { unsigned uuu; for (uuu = 0; uuu < 400; uuu++) + { + // Each (symbol) gets freqs[symbol] cells. + // Cell allocation is spread, not linear. + const size_t step = (size >> 1) + (size >> 3) + 3; + size_t pos = 0; + // const unsigned mask = size - 1; + /* + if (threshold == size) + { + size_t s = 0; + size--; + do + { + int freq = freqs[s]; + if (freq <= 0) + continue; + states[s] = (UInt16)freq; + do + { + table[pos] (CFseRecord)s; + pos = (pos + step) & size; // & mask; + } + while (--freq); + } + while (++s != numSyms); + } + else + */ + { + size_t s = 0; + size--; + do + { + int freq = freqs[s]; + if (freq <= 0) + continue; + states[s] = (UInt16)freq; + do + { + table[pos] = (CFseRecord)s; + // we skip position, if it's already occupied by a "less than 1" probability symbol. + // (step) is coprime to table size, so the cycle will visit each position exactly once + do + pos = (pos + step) & size; // & mask; + while (pos >= threshold); + } + while (--freq); + } + while (++s != numSyms); + } + size++; + // (pos != 0) is unexpected case that means that freqs[] are not correct. + // so it's some failure in code (for example, incorrect predefined freq[] table) + // if (pos != 0) return SZ_ERROR_FAIL; + } + // } + } + { + const CFseRecord * const limit = table + size; + delta = ((UInt32)size << FSE_REC_STATE_OFFSET) - delta; + /* State increases by symbol over time, decreasing number of bits. + Baseline increases until the bit threshold is passed, at which point it resets to 0 */ + do + { + #define TABLE_ITER(a) \ + { \ + const FastInt sym = (FastInt)table[a]; \ + const unsigned nextState = states[sym]; \ + unsigned nb; \ + states[sym] = (UInt16)(nextState + 1); \ + nb = accuracy - GetHighestSetBit_32_nonzero_small(nextState); \ + table[a] = (CFseRecord)(sym - delta \ + + ((UInt32)nb << FSE_REC_LEN_OFFSET) \ + + ((UInt32)nextState << FSE_REC_STATE_OFFSET << nb)); \ + } + TABLE_ITER(0) + TABLE_ITER(1) + table += 2; + } + while (table != limit); + } +} + + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE + +static void Print_Predef(unsigned predefAccuracy, + const unsigned numSymsPredef, + const Int16 * const predefFreqs, + const CFseRecord *checkTable) +{ + CFseRecord table[1 << 6]; + unsigned i; + FSE_Generate(table, predefFreqs, numSymsPredef, predefAccuracy, + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + numSymsPredef == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : + #endif + 0 + ); + if (memcmp(table, checkTable, sizeof(UInt32) << predefAccuracy) != 0) + exit(1); + for (i = 0; i < (1u << predefAccuracy); i++) + { + const UInt32 v = table[i]; + const unsigned state = (unsigned)(GET_FSE_REC_STATE(v)); + if (state & 0xf) + exit(1); + if (i != 0) + { + printf(","); + if (i % 8 == 0) + printf("\n"); + } + printf("W(%d,%d,%2d)", + (unsigned)(state >> 4), + (unsigned)((v >> FSE_REC_LEN_OFFSET) & 0xff), + (unsigned)GET_FSE_REC_SYM(v)); + } + printf("\n\n"); +} + +#endif + + +#define GET16(dest, p) { const Byte *ptr = p; dest = GetUi16(ptr); } +#define GET32(dest, p) { const Byte *ptr = p; dest = GetUi32(ptr); } + +// (1 <= numBits <= 9) +#define FORWARD_READ_BITS(destVal, numBits, mask) \ + { const CBitCtr_signed bos3 = (bitOffset) >> 3; \ + if (bos3 >= 0) return SZ_ERROR_DATA; \ + GET16(destVal, src + bos3) \ + destVal >>= (bitOffset) & 7; \ + bitOffset += (CBitCtr_signed)(numBits); \ + mask = (1u << (numBits)) - 1; \ + destVal &= mask; \ + } + +#define FORWARD_READ_1BIT(destVal) \ + { const CBitCtr_signed bos3 = (bitOffset) >> 3; \ + if (bos3 >= 0) return SZ_ERROR_DATA; \ + destVal = *(src + bos3); \ + destVal >>= (bitOffset) & 7; \ + (bitOffset)++; \ + destVal &= 1; \ + } + + +// in: (accuracyMax <= 9) +// at least 2 bytes will be processed from (in) stream. +// at return: (in->len > 0) +static +Z7_NO_INLINE +SRes FSE_DecodeHeader(CFseRecord *const table, + CInBufPair *const in, + const unsigned accuracyMax, + Byte *const accuracyRes, + unsigned numSymbolsMax) +{ + unsigned accuracy; + unsigned remain1; + unsigned syms; + Int16 freqs[FSE_NUM_SYMBOLS_MAX + 3]; // +3 for overwrite (repeat) + const Byte *src = in->ptr; + CBitCtr_signed bitOffset = (CBitCtr_signed)in->len - 1; + if (bitOffset <= 0) + return SZ_ERROR_DATA; + accuracy = *src & 0xf; + accuracy += 5; + if (accuracy > accuracyMax) + return SZ_ERROR_DATA; + *accuracyRes = (Byte)accuracy; + remain1 = (1u << accuracy) + 1; // (it's remain_freqs_sum + 1) + syms = 0; + src += bitOffset; // src points to last byte + bitOffset = 4 - (bitOffset << 3); + + for (;;) + { + // (2 <= remain1) + const unsigned bits = GetHighestSetBit_32_nonzero_small((unsigned)remain1); + // (1 <= bits <= accuracy) + unsigned val; // it must be unsigned or int + unsigned mask; + FORWARD_READ_BITS(val, bits, mask) + { + const unsigned val2 = remain1 + val - mask; + if (val2 > mask) + { + unsigned bit; + FORWARD_READ_1BIT(bit) + if (bit) + val = val2; + } + } + { + // (remain1 >= 2) + // (0 <= (int)val <= remain1) + val = (unsigned)((int)val - 1); + // val now is "probability" of symbol + // (probability == -1) means "less than 1" frequency. + // (-1 <= (int)val <= remain1 - 1) + freqs[syms++] = (Int16)(int)val; + if (val != 0) + { + remain1 -= (int)val < 0 ? 1u : (unsigned)val; + // remain1 -= val; + // val >>= (sizeof(val) * 8 - 2); + // remain1 -= val & 2; + // freqs[syms++] = (Int16)(int)val; + // syms++; + if (remain1 == 1) + break; + if (syms >= FSE_NUM_SYMBOLS_MAX) + return SZ_ERROR_DATA; + } + else // if (val == 0) + { + // freqs[syms++] = 0; + // syms++; + for (;;) + { + unsigned repeat; + FORWARD_READ_BITS(repeat, 2, mask) + freqs[syms ] = 0; + freqs[syms + 1] = 0; + freqs[syms + 2] = 0; + syms += repeat; + if (syms >= FSE_NUM_SYMBOLS_MAX) + return SZ_ERROR_DATA; + if (repeat != 3) + break; + } + } + } + } + + if (syms > numSymbolsMax) + return SZ_ERROR_DATA; + bitOffset += 7; + bitOffset >>= 3; + if (bitOffset > 0) + return SZ_ERROR_DATA; + in->ptr = src + bitOffset; + in->len = (size_t)(1 - bitOffset); + { + // unsigned uuu; for (uuu = 0; uuu < 50; uuu++) + FSE_Generate(table, freqs, syms, accuracy, + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : + #endif + 0 + ); + } + return SZ_OK; +} + + +// ---------- HUFFMAN ---------- + +#define HUF_MAX_BITS 12 +#define HUF_MAX_SYMBS 256 +#define HUF_DUMMY_SIZE (128 + 8 * 2) // it must multiple of 8 +// #define HUF_DUMMY_SIZE 0 +#define HUF_TABLE_SIZE ((2 << HUF_MAX_BITS) + HUF_DUMMY_SIZE) +#define HUF_GET_SYMBOLS(table) ((table) + (1 << HUF_MAX_BITS) + HUF_DUMMY_SIZE) +// #define HUF_GET_LENS(table) (table) + +typedef struct +{ + // Byte table[HUF_TABLE_SIZE]; + UInt64 table64[HUF_TABLE_SIZE / sizeof(UInt64)]; +} +CZstdDecHufTable; + +/* +Input: + numSyms != 0 + (bits) array size must be aligned for 2 + if (numSyms & 1), then bits[numSyms] == 0, + Huffman tree must be correct before Huf_Build() call: + (sum (1/2^bits[i]) == 1). + && (bits[i] <= HUF_MAX_BITS) +*/ +static +Z7_FORCE_INLINE +void Huf_Build(Byte * const table, + const Byte *bits, const unsigned numSyms) +{ + unsigned counts0[HUF_MAX_BITS + 1]; + unsigned counts1[HUF_MAX_BITS + 1]; + const Byte * const bitsEnd = bits + numSyms; + // /* + { + unsigned t; + for (t = 0; t < Z7_ARRAY_SIZE(counts0); t++) counts0[t] = 0; + for (t = 0; t < Z7_ARRAY_SIZE(counts1); t++) counts1[t] = 0; + } + // */ + // memset(counts0, 0, sizeof(counts0)); + // memset(counts1, 0, sizeof(counts1)); + { + const Byte *bits2 = bits; + // we access additional bits[symbol] if (numSyms & 1) + do + { + counts0[bits2[0]]++; + counts1[bits2[1]]++; + } + while ((bits2 += 2) < bitsEnd); + } + { + unsigned r = 0; + unsigned i = HUF_MAX_BITS; + // Byte *lens = HUF_GET_LENS(symbols); + do + { + const unsigned num = (counts0[i] + counts1[i]) << (HUF_MAX_BITS - i); + counts0[i] = r; + if (num) + { + Byte *lens = &table[r]; + r += num; + memset(lens, (int)i, num); + } + } + while (--i); + counts0[0] = 0; // for speculated loads + // no need for check: + // if (r != (UInt32)1 << HUF_MAX_BITS) exit(0); + } + { + #ifdef MY_CPU_64BIT + UInt64 + #else + UInt32 + #endif + v = 0; + Byte *symbols = HUF_GET_SYMBOLS(table); + do + { + const unsigned nb = *bits++; + if (nb) + { + const unsigned code = counts0[nb]; + const unsigned num = (1u << HUF_MAX_BITS) >> nb; + counts0[nb] = code + num; + // memset(&symbols[code], i, num); + // /* + { + Byte *s2 = &symbols[code]; + if (num <= 2) + { + s2[0] = (Byte)v; + s2[(size_t)num - 1] = (Byte)v; + } + else if (num <= 8) + { + *(UInt32 *)(void *)s2 = (UInt32)v; + *(UInt32 *)(void *)(s2 + (size_t)num - 4) = (UInt32)v; + } + else + { + #ifdef MY_CPU_64BIT + UInt64 *s = (UInt64 *)(void *)s2; + const UInt64 *lim = (UInt64 *)(void *)(s2 + num); + do + { + s[0] = v; s[1] = v; s += 2; + } + while (s != lim); + #else + UInt32 *s = (UInt32 *)(void *)s2; + const UInt32 *lim = (const UInt32 *)(const void *)(s2 + num); + do + { + s[0] = v; s[1] = v; s += 2; + s[0] = v; s[1] = v; s += 2; + } + while (s != lim); + #endif + } + } + // */ + } + v += + #ifdef MY_CPU_64BIT + 0x0101010101010101; + #else + 0x01010101; + #endif + } + while (bits != bitsEnd); + } +} + + + +// how many bytes (src) was moved back from original value. +// we need (HUF_SRC_OFFSET == 3) for optimized 32-bit memory access +#define HUF_SRC_OFFSET 3 + +// v <<= 8 - (bitOffset & 7) + numBits; +// v >>= 32 - HUF_MAX_BITS; +#define HUF_GET_STATE(v, bitOffset, numBits) \ + GET32(v, src + (HUF_SRC_OFFSET - 3) + ((CBitCtr_signed)bitOffset >> 3)) \ + v >>= 32 - HUF_MAX_BITS - 8 + ((unsigned)bitOffset & 7) - numBits; \ + v &= (1u << HUF_MAX_BITS) - 1; \ + + +#ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS +#if defined(MY_CPU_AMD64) && defined(_MSC_VER) && _MSC_VER == 1400 \ + || !defined(MY_CPU_X86_OR_AMD64) \ + // || 1 == 1 /* for debug : to force STREAM4_PRELOAD mode */ + // we need big number (>=16) of registers for PRELOAD4 + #define Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4 + // #define Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2 // for debug +#endif +#endif + +// for debug: simpler and smaller code but slow: +// #define Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE + +#if defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE) || \ + !defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS) + +#define HUF_DECODE(bitOffset, dest) \ +{ \ + UInt32 v; \ + HUF_GET_STATE(v, bitOffset, 0) \ + bitOffset -= table[v]; \ + *(dest) = symbols[v]; \ + if ((CBitCtr_signed)bitOffset < 0) return SZ_ERROR_DATA; \ +} + +#endif + +#if !defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE) || \ + defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4) || \ + defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2) \ + +#define HUF_DECODE_2_INIT(v, bitOffset) \ + HUF_GET_STATE(v, bitOffset, 0) + +#define HUF_DECODE_2(v, bitOffset, dest) \ +{ \ + unsigned numBits; \ + numBits = table[v]; \ + *(dest) = symbols[v]; \ + HUF_GET_STATE(v, bitOffset, numBits) \ + bitOffset -= (CBitCtr)numBits; \ + if ((CBitCtr_signed)bitOffset < 0) return SZ_ERROR_DATA; \ +} + +#endif + + +// src == ptr - HUF_SRC_OFFSET +// we are allowed to access 3 bytes before start of input buffer +static +Z7_NO_INLINE +SRes Huf_Decompress_1stream(const Byte * const table, + const Byte *src, const size_t srcLen, + Byte *dest, const size_t destLen) +{ + CBitCtr bitOffset; + if (srcLen == 0) + return SZ_ERROR_DATA; + SET_bitOffset_TO_PAD (bitOffset, src + HUF_SRC_OFFSET, srcLen) + if (destLen) + { + const Byte *symbols = HUF_GET_SYMBOLS(table); + const Byte *destLim = dest + destLen; + #ifdef Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE + { + do + { + HUF_DECODE (bitOffset, dest) + } + while (++dest != destLim); + } + #else + { + UInt32 v; + HUF_DECODE_2_INIT (v, bitOffset) + do + { + HUF_DECODE_2 (v, bitOffset, dest) + } + while (++dest != destLim); + } + #endif + } + return bitOffset == 0 ? SZ_OK : SZ_ERROR_DATA; +} + + +// for debug : it reduces register pressure : by array copy can be slow : +// #define Z7_ZSTD_DEC_USE_HUF_LOCAL + +// src == ptr + (6 - HUF_SRC_OFFSET) +// srcLen >= 10 +// we are allowed to access 3 bytes before start of input buffer +static +Z7_NO_INLINE +SRes Huf_Decompress_4stream(const Byte * const + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + table2, + #else + table, + #endif + const Byte *src, size_t srcLen, + Byte *dest, size_t destLen) +{ + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + Byte table[HUF_TABLE_SIZE]; + #endif + UInt32 sizes[3]; + const size_t delta = (destLen + 3) / 4; + if ((sizes[0] = GetUi16(src + (0 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + if ((sizes[1] = GetUi16(src + (2 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + sizes[1] += sizes[0]; + if ((sizes[2] = GetUi16(src + (4 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + sizes[2] += sizes[1]; + srcLen -= 6; + if (srcLen <= sizes[2]) + return SZ_ERROR_DATA; + + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + { + // unsigned i = 0; for(; i < 1000; i++) + memcpy(table, table2, HUF_TABLE_SIZE); + } + #endif + + #ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + { + CBitCtr bitOffset_0, + bitOffset_1, + bitOffset_2, + bitOffset_3; + { + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_0, src + HUF_SRC_OFFSET, sizes[0]) + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_1, src + HUF_SRC_OFFSET, sizes[1]) + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_2, src + HUF_SRC_OFFSET, sizes[2]) + SET_bitOffset_TO_PAD (bitOffset_3, src + HUF_SRC_OFFSET, srcLen) + } + { + const Byte * const symbols = HUF_GET_SYMBOLS(table); + Byte *destLim = dest + destLen - delta * 3; + + if (dest != destLim) + #ifdef Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4 + { + UInt32 v_0, v_1, v_2, v_3; + HUF_DECODE_2_INIT (v_0, bitOffset_0) + HUF_DECODE_2_INIT (v_1, bitOffset_1) + HUF_DECODE_2_INIT (v_2, bitOffset_2) + HUF_DECODE_2_INIT (v_3, bitOffset_3) + // #define HUF_DELTA (1 << 17) / 4 + do + { + HUF_DECODE_2 (v_3, bitOffset_3, dest + delta * 3) + HUF_DECODE_2 (v_2, bitOffset_2, dest + delta * 2) + HUF_DECODE_2 (v_1, bitOffset_1, dest + delta) + HUF_DECODE_2 (v_0, bitOffset_0, dest) + } + while (++dest != destLim); + /* + {// unsigned y = 0; for (;y < 1; y++) + { + const size_t num = destLen - delta * 3; + Byte *orig = dest - num; + memmove (orig + delta , orig + HUF_DELTA, num); + memmove (orig + delta * 2, orig + HUF_DELTA * 2, num); + memmove (orig + delta * 3, orig + HUF_DELTA * 3, num); + }} + */ + } + #elif defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2) + { + UInt32 v_0, v_1, v_2, v_3; + HUF_DECODE_2_INIT (v_0, bitOffset_0) + HUF_DECODE_2_INIT (v_1, bitOffset_1) + do + { + HUF_DECODE_2 (v_0, bitOffset_0, dest) + HUF_DECODE_2 (v_1, bitOffset_1, dest + delta) + } + while (++dest != destLim); + dest = destLim - (destLen - delta * 3); + dest += delta * 2; + destLim += delta * 2; + HUF_DECODE_2_INIT (v_2, bitOffset_2) + HUF_DECODE_2_INIT (v_3, bitOffset_3) + do + { + HUF_DECODE_2 (v_2, bitOffset_2, dest) + HUF_DECODE_2 (v_3, bitOffset_3, dest + delta) + } + while (++dest != destLim); + dest -= delta * 2; + destLim -= delta * 2; + } + #else + { + do + { + HUF_DECODE (bitOffset_3, dest + delta * 3) + HUF_DECODE (bitOffset_2, dest + delta * 2) + HUF_DECODE (bitOffset_1, dest + delta) + HUF_DECODE (bitOffset_0, dest) + } + while (++dest != destLim); + } + #endif + + if (bitOffset_3 != (CBitCtr)sizes[2]) + return SZ_ERROR_DATA; + if (destLen &= 3) + { + destLim = dest + 4 - destLen; + do + { + HUF_DECODE (bitOffset_2, dest + delta * 2) + HUF_DECODE (bitOffset_1, dest + delta) + HUF_DECODE (bitOffset_0, dest) + } + while (++dest != destLim); + } + if ( bitOffset_0 != 0 + || bitOffset_1 != (CBitCtr)sizes[0] + || bitOffset_2 != (CBitCtr)sizes[1]) + return SZ_ERROR_DATA; + } + } + #else // Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + { + unsigned i; + for (i = 0; i < 4; i++) + { + size_t d = destLen; + size_t size = srcLen; + if (i != 3) + { + d = delta; + size = sizes[i]; + } + if (i != 0) + size -= sizes[i - 1]; + destLen -= d; + RINOK(Huf_Decompress_1stream(table, src, size, dest, d)) + dest += d; + src += size; + } + } + #endif + + return SZ_OK; +} + + + +// (in->len != 0) +// we are allowed to access in->ptr[-3] +// at least 2 bytes in (in->ptr) will be processed +static SRes Huf_DecodeTable(CZstdDecHufTable *const p, CInBufPair *const in) +{ + Byte weights[HUF_MAX_SYMBS + 1]; // +1 for extra write for loop unroll + unsigned numSyms; + const unsigned header = *(in->ptr)++; + in->len--; + // memset(weights, 0, sizeof(weights)); + if (header >= 128) + { + // direct representation: 4 bits field (0-15) per weight + numSyms = header - 127; + // numSyms != 0 + { + const size_t numBytes = (numSyms + 1) / 2; + const Byte *const ws = in->ptr; + size_t i = 0; + if (in->len < numBytes) + return SZ_ERROR_DATA; + in->ptr += numBytes; + in->len -= numBytes; + do + { + const unsigned b = ws[i]; + weights[i * 2 ] = (Byte)(b >> 4); + weights[i * 2 + 1] = (Byte)(b & 0xf); + } + while (++i != numBytes); + /* 7ZIP: we can restore correct zero value for weights[numSyms], + if we want to use zero values starting from numSyms in code below. */ + // weights[numSyms] = 0; + } + } + else + { + #define MAX_ACCURACY_LOG_FOR_WEIGHTS 6 + CFseRecord table[1 << MAX_ACCURACY_LOG_FOR_WEIGHTS]; + + Byte accuracy; + const Byte *src; + size_t srcLen; + if (in->len < header) + return SZ_ERROR_DATA; + { + CInBufPair fse_stream; + fse_stream.len = header; + fse_stream.ptr = in->ptr; + in->ptr += header; + in->len -= header; + RINOK(FSE_DecodeHeader(table, &fse_stream, + MAX_ACCURACY_LOG_FOR_WEIGHTS, + &accuracy, + 16 // num weight symbols max (max-symbol is 15) + )) + // at least 2 bytes were processed in fse_stream. + // (srcLen > 0) after FSE_DecodeHeader() + // if (srcLen == 0) return SZ_ERROR_DATA; + src = fse_stream.ptr; + srcLen = fse_stream.len; + } + // we are allowed to access src[-5] + { + // unsigned yyy = 200; do { + CBitCtr bitOffset; + FastInt32 state1, state2; + SET_bitOffset_TO_PAD (bitOffset, src, srcLen) + state1 = accuracy; + src -= state1 >> 2; // src -= 1; // for GET16() optimization + state1 <<= FSE_REC_LEN_OFFSET; + state2 = state1; + numSyms = 0; + for (;;) + { + #define FSE_WEIGHT_DECODE(st) \ + { \ + const unsigned bits = GET_FSE_REC_LEN(st); \ + FastInt r; \ + GET16(r, src + (bitOffset >> 3)) \ + r >>= (unsigned)bitOffset & 7; \ + if ((CBitCtr_signed)(bitOffset -= (CBitCtr)bits) < 0) \ + { if (bitOffset + (CBitCtr)bits != 0) \ + return SZ_ERROR_DATA; \ + break; } \ + r &= 0xff; \ + r >>= 8 - bits; \ + st = table[GET_FSE_REC_STATE(st) + r]; \ + weights[numSyms++] = (Byte)GET_FSE_REC_SYM(st); \ + } + FSE_WEIGHT_DECODE (state1) + FSE_WEIGHT_DECODE (state2) + if (numSyms == HUF_MAX_SYMBS) + return SZ_ERROR_DATA; + } + // src += (unsigned)accuracy >> 2; } while (--yyy); + } + } + + // Build using weights: + { + UInt32 sum = 0; + { + // numSyms >= 1 + unsigned i = 0; + weights[numSyms] = 0; + do + { + sum += ((UInt32)1 << weights[i ]) & ~(UInt32)1; + sum += ((UInt32)1 << weights[i + 1]) & ~(UInt32)1; + i += 2; + } + while (i < numSyms); + if (sum == 0) + return SZ_ERROR_DATA; + } + { + const unsigned maxBits = GetHighestSetBit_32_nonzero_big(sum) + 1; + { + const UInt32 left = ((UInt32)1 << maxBits) - sum; + // (left != 0) + // (left) must be power of 2 in correct stream + if (left & (left - 1)) + return SZ_ERROR_DATA; + weights[numSyms++] = (Byte)GetHighestSetBit_32_nonzero_big(left); + } + // if (numSyms & 1) + weights[numSyms] = 0; // for loop unroll + // numSyms >= 2 + { + unsigned i = 0; + do + { + /* + #define WEIGHT_ITER(a) \ + { unsigned w = weights[i + (a)]; \ + const unsigned t = maxBits - w; \ + w = w ? t: w; \ + if (w > HUF_MAX_BITS) return SZ_ERROR_DATA; \ + weights[i + (a)] = (Byte)w; } + */ + // /* + #define WEIGHT_ITER(a) \ + { unsigned w = weights[i + (a)]; \ + if (w) { \ + w = maxBits - w; \ + if (w > HUF_MAX_BITS) return SZ_ERROR_DATA; \ + weights[i + (a)] = (Byte)w; }} + // */ + WEIGHT_ITER(0) + // WEIGHT_ITER(1) + // i += 2; + } + while (++i != numSyms); + } + } + } + { + // unsigned yyy; for (yyy = 0; yyy < 100; yyy++) + Huf_Build((Byte *)(void *)p->table64, weights, numSyms); + } + return SZ_OK; +} + + +typedef enum +{ + k_SeqMode_Predef = 0, + k_SeqMode_RLE = 1, + k_SeqMode_FSE = 2, + k_SeqMode_Repeat = 3 +} +z7_zstd_enum_SeqMode; + +// predefAccuracy == 5 for OFFSET symbols +// predefAccuracy == 6 for MATCH/LIT LEN symbols +static +SRes +Z7_NO_INLINE +// Z7_FORCE_INLINE +FSE_Decode_SeqTable(CFseRecord * const table, + CInBufPair * const in, + unsigned predefAccuracy, + Byte * const accuracyRes, + unsigned numSymbolsMax, + const CFseRecord * const predefs, + const unsigned seqMode) +{ + // UNUSED_VAR(numSymsPredef) + // UNUSED_VAR(predefFreqs) + if (seqMode == k_SeqMode_FSE) + { + // unsigned y = 50; CInBufPair in2 = *in; do { *in = in2; RINOK( + return + FSE_DecodeHeader(table, in, + predefAccuracy + 3, // accuracyMax + accuracyRes, + numSymbolsMax) + ; + // )} while (--y); return SZ_OK; + } + // numSymsMax = numSymsPredef + ((predefAccuracy & 1) * (32 - 29))); // numSymsMax + // numSymsMax == 32 for offsets + + if (seqMode == k_SeqMode_Predef) + { + *accuracyRes = (Byte)predefAccuracy; + memcpy(table, predefs, sizeof(UInt32) << predefAccuracy); + return SZ_OK; + } + + // (seqMode == k_SeqMode_RLE) + if (in->len == 0) + return SZ_ERROR_DATA; + in->len--; + { + const Byte *ptr = in->ptr; + const unsigned sym = ptr[0]; + in->ptr = ptr + 1; + if (sym >= numSymbolsMax) + return SZ_ERROR_DATA; + table[0] = (FastInt32)sym + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + + (numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : 0) + #endif + ; + *accuracyRes = 0; + } + return SZ_OK; +} + + +typedef struct +{ + CFseRecord of[1 << 8]; + CFseRecord ll[1 << 9]; + CFseRecord ml[1 << 9]; +} +CZstdDecFseTables; + + +typedef struct +{ + Byte *win; + SizeT cycSize; + /* + if (outBuf_fromCaller) : cycSize = outBufSize_fromCaller + else { + if ( isCyclicMode) : cycSize = cyclic_buffer_size = (winSize + extra_space) + if (!isCyclicMode) : cycSize = ContentSize, + (isCyclicMode == true) if (ContetSize >= winSize) or ContetSize is unknown + } + */ + SizeT winPos; + + CZstdDecOffset reps[3]; + + Byte ll_accuracy; + Byte of_accuracy; + Byte ml_accuracy; + // Byte seqTables_wereSet; + Byte litHuf_wasSet; + + Byte *literalsBase; + + size_t winSize; // from header + size_t totalOutCheck; // totalOutCheck <= winSize + + #ifdef Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + SEQ_EXTRA_TABLES(m_) + #endif + // UInt64 _pad_Alignment; // is not required now + CZstdDecFseTables fse; + CZstdDecHufTable huf; +} +CZstdDec1; + +#define ZstdDec1_GET_BLOCK_SIZE_LIMIT(p) \ + ((p)->winSize < kBlockSizeMax ? (UInt32)(p)->winSize : kBlockSizeMax) + +#define SEQ_TABLES_WERE_NOT_SET_ml_accuracy 1 // accuracy=1 is not used by zstd +#define IS_SEQ_TABLES_WERE_SET(p) (((p)->ml_accuracy != SEQ_TABLES_WERE_NOT_SET_ml_accuracy)) +// #define IS_SEQ_TABLES_WERE_SET(p) ((p)->seqTables_wereSet) + + +static void ZstdDec1_Construct(CZstdDec1 *p) +{ + #ifdef Z7_ZSTD_DEC_PRINT_TABLE + Print_Predef(6, NUM_LL_SYMBOLS, SEQ_LL_PREDEF_DIST, k_PredefRecords_LL); + Print_Predef(5, NUM_OFFSET_SYMBOLS_PREDEF, SEQ_OFFSET_PREDEF_DIST, k_PredefRecords_OF); + Print_Predef(6, NUM_ML_SYMBOLS, SEQ_ML_PREDEF_DIST, k_PredefRecords_ML); + #endif + + p->win = NULL; + p->cycSize = 0; + p->literalsBase = NULL; + #ifdef Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + FILL_LOC_BASES_ALL + #endif +} + + +static void ZstdDec1_Init(CZstdDec1 *p) +{ + p->reps[0] = 1; + p->reps[1] = 4; + p->reps[2] = 8; + // p->seqTables_wereSet = False; + p->ml_accuracy = SEQ_TABLES_WERE_NOT_SET_ml_accuracy; + p->litHuf_wasSet = False; + p->totalOutCheck = 0; +} + + + +#ifdef MY_CPU_LE_UNALIGN + #define Z7_ZSTD_DEC_USE_UNALIGNED_COPY +#endif + +#ifdef Z7_ZSTD_DEC_USE_UNALIGNED_COPY + + #define COPY_CHUNK_SIZE 16 + + #define COPY_CHUNK_4_2(dest, src) \ + { \ + ((UInt32 *)(void *)dest)[0] = ((const UInt32 *)(const void *)src)[0]; \ + ((UInt32 *)(void *)dest)[1] = ((const UInt32 *)(const void *)src)[1]; \ + src += 4 * 2; \ + dest += 4 * 2; \ + } + + /* sse2 doesn't help here in GCC and CLANG. + so we disabled sse2 here */ + /* + #if defined(MY_CPU_AMD64) + #define Z7_ZSTD_DEC_USE_SSE2 + #elif defined(MY_CPU_X86) + #if defined(_MSC_VER) && _MSC_VER >= 1300 && defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || defined(__SSE2__) \ + // || 1 == 1 // for debug only + #define Z7_ZSTD_DEC_USE_SSE2 + #endif + #endif + */ + + #if defined(MY_CPU_ARM64) + #define COPY_OFFSET_MIN 16 + #define COPY_CHUNK1(dest, src) \ + { \ + vst1q_u8((uint8_t *)(void *)dest, \ + vld1q_u8((const uint8_t *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if ((len -= COPY_CHUNK_SIZE) == 0) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(Z7_ZSTD_DEC_USE_SSE2) + #include // sse2 + #define COPY_OFFSET_MIN 16 + + #define COPY_CHUNK1(dest, src) \ + { \ + _mm_storeu_si128((__m128i *)(void *)dest, \ + _mm_loadu_si128((const __m128i *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if ((len -= COPY_CHUNK_SIZE) == 0) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(MY_CPU_64BIT) + #define COPY_OFFSET_MIN 8 + + #define COPY_CHUNK(dest, src) \ + { \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + ((UInt64 *)(void *)dest)[1] = ((const UInt64 *)(const void *)src)[1]; \ + src += 8 * 2; \ + dest += 8 * 2; \ + } + + #else + #define COPY_OFFSET_MIN 4 + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_4_2(dest, src); \ + COPY_CHUNK_4_2(dest, src); \ + } + + #endif +#endif + + +#ifndef COPY_CHUNK_SIZE + #define COPY_OFFSET_MIN 4 + #define COPY_CHUNK_SIZE 8 + #define COPY_CHUNK_2(dest, src) \ + { \ + const Byte a0 = src[0]; \ + const Byte a1 = src[1]; \ + dest[0] = a0; \ + dest[1] = a1; \ + src += 2; \ + dest += 2; \ + } + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + } +#endif + + +#define COPY_PREPARE \ + len += (COPY_CHUNK_SIZE - 1); \ + len &= ~(size_t)(COPY_CHUNK_SIZE - 1); \ + { if (len > rem) \ + { len = rem; \ + rem &= (COPY_CHUNK_SIZE - 1); \ + if (rem) { \ + len -= rem; \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do *dest++ = *src++; while (--rem); \ + if (len == 0) return; }}} + +#define COPY_CHUNKS \ +{ \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do { COPY_CHUNK(dest, src) } \ + while (len -= COPY_CHUNK_SIZE); \ +} + +// (len != 0) +// (len <= rem) +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyLiterals(Byte *dest, Byte const *src, size_t len, size_t rem) +{ + COPY_PREPARE + COPY_CHUNKS +} + + +/* we can define Z7_STD_DEC_USE_AFTER_CYC_BUF, if we want to use additional + space after cycSize that can be used to reduce the code in CopyMatch(): */ +// for debug: +// #define Z7_STD_DEC_USE_AFTER_CYC_BUF + +/* +CopyMatch() +if wrap (offset > winPos) +{ + then we have at least (COPY_CHUNK_SIZE) avail in (dest) before we will overwrite (src): + (cycSize >= offset + COPY_CHUNK_SIZE) + if defined(Z7_STD_DEC_USE_AFTER_CYC_BUF) + we are allowed to read win[cycSize + COPY_CHUNK_SIZE - 1], +} +(len != 0) +*/ +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch(size_t offset, size_t len, + Byte *win, size_t winPos, size_t rem, const size_t cycSize) +{ + Byte *dest = win + winPos; + const Byte *src; + // STAT_INC(g_NumCopy) + + if (offset > winPos) + { + size_t back = offset - winPos; + // src = win + cycSize - back; + // cycSize -= offset; + STAT_INC(g_NumOver) + src = dest + (cycSize - offset); + // (src >= dest) here + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + if (back < len) + { + #else + if (back < len + (COPY_CHUNK_SIZE - 1)) + { + if (back >= len) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + *dest++ = *src++; + while (--len); + return; + } + #endif + // back < len + STAT_INC(g_NumOver2) + len -= back; + rem -= back; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + *dest++ = *src++; + while (--back); + src = dest - offset; + // src = win; + // we go to MAIN-COPY + } + } + else + src = dest - offset; + + // len != 0 + // do *dest++ = *src++; while (--len); return; + + // --- MAIN COPY --- + // if (src >= dest), then ((size_t)(src - dest) >= COPY_CHUNK_SIZE) + // so we have at least COPY_CHUNK_SIZE space before overlap for writing. + COPY_PREPARE + + /* now (len == COPY_CHUNK_SIZE * x) + so we can unroll for aligned copy */ + { + // const unsigned b0 = src[0]; + // (COPY_OFFSET_MIN >= 4) + + if (offset >= COPY_OFFSET_MIN) + { + COPY_CHUNKS + // return; + } + else + #if (COPY_OFFSET_MIN > 4) + #if COPY_CHUNK_SIZE < 8 + #error Stop_Compiling_Bad_COPY_CHUNK_SIZE + #endif + if (offset >= 4) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + COPY_CHUNK_4_2(dest, src) + #if COPY_CHUNK_SIZE != 16 + if (len == 8) break; + #endif + COPY_CHUNK_4_2(dest, src) + } + while (len -= 16); + // return; + } + else + #endif + { + // (offset < 4) + const unsigned b0 = src[0]; + if (offset < 2) + { + #if defined(Z7_ZSTD_DEC_USE_UNALIGNED_COPY) && (COPY_CHUNK_SIZE == 16) + #if defined(MY_CPU_64BIT) + { + const UInt64 v64 = (UInt64)b0 * 0x0101010101010101; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + ((UInt64 *)(void *)dest)[0] = v64; + ((UInt64 *)(void *)dest)[1] = v64; + dest += 16; + } + while (len -= 16); + } + #else + { + UInt32 v = b0; + v |= v << 8; + v |= v << 16; + do + { + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + } + while (len -= 16); + } + #endif + #else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + } + while (len -= 4); + #endif + } + else if (offset == 2) + { + const Byte b1 = src[1]; + { + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest += 2; + } + while (len -= 2); + } + } + else // (offset == 3) + { + const Byte *lim = dest + len - 2; + const Byte b1 = src[1]; + const Byte b2 = src[2]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest[2] = b2; + dest += 3; + } + while (dest < lim); + lim++; // points to last byte that must be written + if (dest <= lim) + { + *dest = (Byte)b0; + if (dest != lim) + dest[1] = b1; + } + } + } + } +} + + + +#define UPDATE_TOTAL_OUT(p, size) \ +{ \ + size_t _toc = (p)->totalOutCheck + (size); \ + const size_t _ws = (p)->winSize; \ + if (_toc >= _ws) _toc = _ws; \ + (p)->totalOutCheck = _toc; \ +} + + +#if defined(MY_CPU_64BIT) && defined(MY_CPU_LE_UNALIGN) +// we can disable it for debug: +#define Z7_ZSTD_DEC_USE_64BIT_LOADS +#endif +// #define Z7_ZSTD_DEC_USE_64BIT_LOADS // for debug : slow in 32-bit + +// SEQ_SRC_OFFSET: how many bytes (src) (seqSrc) was moved back from original value. +// we need (SEQ_SRC_OFFSET != 0) for optimized memory access +#ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define SEQ_SRC_OFFSET 7 +#else + #define SEQ_SRC_OFFSET 3 +#endif +#define SRC_PLUS_FOR_4BYTES(bitOffset) (SEQ_SRC_OFFSET - 3) + ((CBitCtr_signed)(bitOffset) >> 3) +#define BIT_OFFSET_7BITS(bitOffset) ((unsigned)(bitOffset) & 7) +/* + if (BIT_OFFSET_DELTA_BITS == 0) : bitOffset == number_of_unprocessed_bits + if (BIT_OFFSET_DELTA_BITS == 1) : bitOffset == number_of_unprocessed_bits - 1 + and we can read 1 bit more in that mode : (8 * n + 1). +*/ +// #define BIT_OFFSET_DELTA_BITS 0 +#define BIT_OFFSET_DELTA_BITS 1 +#if BIT_OFFSET_DELTA_BITS == 1 + #define GET_SHIFT_FROM_BOFFS7(boff7) (7 ^ (boff7)) +#else + #define GET_SHIFT_FROM_BOFFS7(boff7) (8 - BIT_OFFSET_DELTA_BITS - (boff7)) +#endif + +#define UPDATE_BIT_OFFSET(bitOffset, numBits) \ + (bitOffset) -= (CBitCtr)(numBits); + +#define GET_SHIFT(bitOffset) GET_SHIFT_FROM_BOFFS7(BIT_OFFSET_7BITS(bitOffset)) + + +#if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) + #if (NUM_OFFSET_SYMBOLS_MAX - BIT_OFFSET_DELTA_BITS < 32) + /* if (NUM_OFFSET_SYMBOLS_MAX == 32 && BIT_OFFSET_DELTA_BITS == 1), + we have depth 31 + 9 + 9 + 8 = 57 bits that can b read with single read. */ + #define Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + #endif + #ifndef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + #if (BIT_OFFSET_DELTA_BITS == 1) + /* if (winLimit - winPos <= (kBlockSizeMax = (1 << 17))) + { + the case (16 bits literal extra + 16 match extra) is not possible + in correct stream. So error will be detected for (16 + 16) case. + And longest correct sequence after offset reading is (31 + 9 + 9 + 8 = 57 bits). + So we can use just one 64-bit load here in that case. + } + */ + #define Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML + #endif + #endif +#endif + + +#if !defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) || \ + (!defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML)) +// in : (0 < bits <= (24 or 25)): +#define STREAM_READ_BITS(dest, bits) \ +{ \ + GET32(dest, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + dest <<= GET_SHIFT(bitOffset); \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + dest >>= 32 - bits; \ +} +#endif + + +#define FSE_Peek_1(table, state) table[state] + +#define STATE_VAR(name) state_ ## name + +// in : (0 <= accuracy <= (24 or 25)) +#define FSE_INIT_STATE(name, cond) \ +{ \ + UInt32 r; \ + const unsigned bits = p->name ## _accuracy; \ + GET32(r, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + r <<= GET_SHIFT(bitOffset); \ + r >>= 1; \ + r >>= 31 ^ bits; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + STATE_VAR(name) = FSE_Peek_1(FSE_TABLE(name), r); \ + /* STATE_VAR(name) = dest << 16; */ \ +} + + +#define FSE_Peek_Plus(name, r) \ + STATE_VAR(name) = FSE_Peek_1(FSE_TABLE(name), \ + GET_FSE_REC_STATE(STATE_VAR(name)) + r); + +#define LZ_LOOP_ERROR_EXIT { return SZ_ERROR_DATA; } + +#define BO_OVERFLOW_CHECK \ + { if ((CBitCtr_signed)bitOffset < 0) LZ_LOOP_ERROR_EXIT } + + +#ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + +#define GET64(dest, p) { const Byte *ptr = p; dest = GetUi64(ptr); } + +#define FSE_PRELOAD \ +{ \ + GET64(v, src - 4 + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + v <<= GET_SHIFT(bitOffset); \ +} + +#define FSE_UPDATE_STATE_2(name, cond) \ +{ \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + UInt64 r = v; \ + v <<= bits; \ + r >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + r >>= 63 ^ bits; \ + FSE_Peek_Plus(name, r); \ +} + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_2 (ll, {} ) \ + FSE_UPDATE_STATE_2 (ml, {} ) \ + FSE_UPDATE_STATE_2 (of, BO_OVERFLOW_CHECK) \ + +#else // Z7_ZSTD_DEC_USE_64BIT_LOADS + +// it supports 8 bits accuracy for any code +// it supports 9 bits accuracy, if (BIT_OFFSET_DELTA_BITS == 1) +#define FSE_UPDATE_STATE_0(name, cond) \ +{ \ + UInt32 r; \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + GET16(r, src + 2 + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + r >>= (bitOffset & 7); \ + r &= (1 << (8 + BIT_OFFSET_DELTA_BITS)) - 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + r >>= (8 + BIT_OFFSET_DELTA_BITS) - bits; \ + FSE_Peek_Plus(name, r); \ +} + +// for debug (slow): +// #define Z7_ZSTD_DEC_USE_FSE_FUSION_FORCE +#if BIT_OFFSET_DELTA_BITS == 0 || defined(Z7_ZSTD_DEC_USE_FSE_FUSION_FORCE) + #define Z7_ZSTD_DEC_USE_FSE_FUSION +#endif + +#ifdef Z7_ZSTD_DEC_USE_FSE_FUSION +#define FSE_UPDATE_STATE_1(name) \ +{ UInt32 rest2; \ +{ \ + UInt32 r; \ + unsigned bits; \ + GET32(r, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + r <<= GET_SHIFT(bitOffset); \ + rest2 = r << bits; \ + r >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + r >>= 31 ^ bits; \ + FSE_Peek_Plus(name, r); \ +} + +#define FSE_UPDATE_STATE_3(name) \ +{ \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + rest2 >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + rest2 >>= 31 ^ bits; \ + FSE_Peek_Plus(name, rest2); \ +}} + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_1 (ll) \ + FSE_UPDATE_STATE_3 (ml) \ + FSE_UPDATE_STATE_0 (of, BO_OVERFLOW_CHECK) \ + +#else // Z7_ZSTD_DEC_USE_64BIT_LOADS + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_0 (ll, {} ) \ + FSE_UPDATE_STATE_0 (ml, {} ) \ + FSE_UPDATE_STATE_0 (of, BO_OVERFLOW_CHECK) \ + +#endif // Z7_ZSTD_DEC_USE_FSE_FUSION +#endif // Z7_ZSTD_DEC_USE_64BIT_LOADS + + + +typedef struct +{ + UInt32 numSeqs; + UInt32 literalsLen; + const Byte *literals; +} +CZstdDec1_Vars; + + +// if (BIT_OFFSET_DELTA_BITS != 0), we need (BIT_OFFSET_DELTA_BYTES > 0) +#define BIT_OFFSET_DELTA_BYTES BIT_OFFSET_DELTA_BITS + +/* if (NUM_OFFSET_SYMBOLS_MAX == 32) + max_seq_bit_length = (31) + 16 + 16 + 9 + 8 + 9 = 89 bits + if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) we have longest backward + lookahead offset, and we read UInt64 after literal_len reading. + if (BIT_OFFSET_DELTA_BITS == 1 && NUM_OFFSET_SYMBOLS_MAX == 32) + MAX_BACKWARD_DEPTH = 16 bytes +*/ +#define MAX_BACKWARD_DEPTH \ + ((NUM_OFFSET_SYMBOLS_MAX - 1 + 16 + 16 + 7) / 8 + 7 + BIT_OFFSET_DELTA_BYTES) + +/* srcLen != 0 + src == real_data_ptr - SEQ_SRC_OFFSET - BIT_OFFSET_DELTA_BYTES + if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) then + (winLimit - p->winPos <= (1 << 17)) is required +*/ +static +Z7_NO_INLINE +// Z7_ATTRIB_NO_VECTOR +SRes Decompress_Sequences(CZstdDec1 * const p, + const Byte *src, const size_t srcLen, + const size_t winLimit, + const CZstdDec1_Vars * const vars) +{ +#ifdef Z7_ZSTD_DEC_USE_BASES_LOCAL + SEQ_EXTRA_TABLES(a_) +#endif + + // for debug: + // #define Z7_ZSTD_DEC_USE_LOCAL_FSE_TABLES +#ifdef Z7_ZSTD_DEC_USE_LOCAL_FSE_TABLES + #define FSE_TABLE(n) fse. n + const CZstdDecFseTables fse = p->fse; + /* + CZstdDecFseTables fse; + #define COPY_FSE_TABLE(n) \ + memcpy(fse. n, p->fse. n, (size_t)4 << p-> n ## _accuracy); + COPY_FSE_TABLE(of) + COPY_FSE_TABLE(ll) + COPY_FSE_TABLE(ml) + */ +#else + #define FSE_TABLE(n) (p->fse. n) +#endif + +#ifdef Z7_ZSTD_DEC_USE_BASES_LOCAL + FILL_LOC_BASES_ALL +#endif + + { + unsigned numSeqs = vars->numSeqs; + const Byte *literals = vars->literals; + ptrdiff_t literalsLen = (ptrdiff_t)vars->literalsLen; + Byte * const win = p->win; + size_t winPos = p->winPos; + const size_t cycSize = p->cycSize; + size_t totalOutCheck = p->totalOutCheck; + const size_t winSize = p->winSize; + size_t reps_0 = p->reps[0]; + size_t reps_1 = p->reps[1]; + size_t reps_2 = p->reps[2]; + UInt32 STATE_VAR(ll), STATE_VAR(of), STATE_VAR(ml); + CBitCtr bitOffset; + + SET_bitOffset_TO_PAD (bitOffset, src + SEQ_SRC_OFFSET, srcLen + BIT_OFFSET_DELTA_BYTES) + + bitOffset -= BIT_OFFSET_DELTA_BITS; + + FSE_INIT_STATE(ll, {} ) + FSE_INIT_STATE(of, {} ) + FSE_INIT_STATE(ml, BO_OVERFLOW_CHECK) + + for (;;) + { + size_t matchLen; + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + UInt64 v; + #endif + + #ifdef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + FSE_PRELOAD + #endif + + // if (of_code == 0) + if ((Byte)STATE_VAR(of) == 0) + { + if (GET_FSE_REC_SYM(STATE_VAR(ll)) == 0) + { + const size_t offset = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep1) + } + STAT_UPDATE(else g_Num_Rep0++;) + } + else + { + const unsigned of_code = (Byte)STATE_VAR(of); + + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #if !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #endif + #else + UInt32 v; + { + const Byte *src4 = src + SRC_PLUS_FOR_4BYTES(bitOffset); + const unsigned skip = GET_SHIFT(bitOffset); + GET32(v, src4) + v <<= skip; + v |= (UInt32)src4[-1] >> (8 - skip); + } + #endif + + UPDATE_BIT_OFFSET(bitOffset, of_code) + + if (of_code == 1) + { + // read 1 bit + #if defined(Z7_MSC_VER_ORIGINAL) || defined(MY_CPU_X86_OR_AMD64) + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define CHECK_HIGH_BIT_64(a) ((Int64)(UInt64)(a) < 0) + #else + #define CHECK_HIGH_BIT_32(a) ((Int32)(UInt32)(a) < 0) + #endif + #else + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define CHECK_HIGH_BIT_64(a) ((UInt64)(a) & ((UInt64)1 << 63)) + #else + #define CHECK_HIGH_BIT_32(a) ((UInt32)(a) & ((UInt32)1 << 31)) + #endif + #endif + + if + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + CHECK_HIGH_BIT_64 (((UInt64)GET_FSE_REC_SYM(STATE_VAR(ll)) - 1) ^ v) + #else + CHECK_HIGH_BIT_32 (((UInt32)GET_FSE_REC_SYM(STATE_VAR(ll)) - 1) ^ v) + #endif + { + v <<= 1; + { + const size_t offset = reps_2; + reps_2 = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep2) + } + } + else + { + if (GET_FSE_REC_SYM(STATE_VAR(ll)) == 0) + { + // litLen == 0 && bit == 1 + STAT_INC(g_Num_Rep3) + v <<= 1; + reps_2 = reps_1; + reps_1 = reps_0; + if (--reps_0 == 0) + { + // LZ_LOOP_ERROR_EXIT + // original-zstd decoder : input is corrupted; force offset to 1 + // reps_0 = 1; + reps_0++; + } + } + else + { + // litLen != 0 && bit == 0 + v <<= 1; + { + const size_t offset = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep1) + } + } + } + } + else + { + // (2 <= of_code) + // if (of_code >= 32) LZ_LOOP_ERROR_EXIT // optional check + // we don't allow (of_code >= 32) cases in another code + reps_2 = reps_1; + reps_1 = reps_0; + reps_0 = ((size_t)1 << of_code) - 3 + (size_t) + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + (v >> (64 - of_code)); + v <<= of_code; + #else + (v >> (32 - of_code)); + #endif + } + } + + #ifdef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML + FSE_PRELOAD + #endif + + matchLen = (size_t)GET_FSE_REC_SYM(STATE_VAR(ml)) + #ifndef Z7_ZSTD_DEC_USE_ML_PLUS3 + + MATCH_LEN_MIN + #endif + ; + { + { + if (matchLen >= 32 + MATCH_LEN_MIN) // if (state_ml & 0x20) + { + const unsigned extra = BASES_TABLE(SEQ_ML_EXTRA) [(size_t)matchLen - MATCH_LEN_MIN]; + matchLen = BASES_TABLE(SEQ_ML_BASES) [(size_t)matchLen - MATCH_LEN_MIN]; + #if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) && \ + (defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) || \ + defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF)) + { + UPDATE_BIT_OFFSET(bitOffset, extra) + matchLen += (size_t)(v >> (64 - extra)); + #if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #else + v <<= extra; + #endif + } + #else + { + UInt32 v32; + STREAM_READ_BITS(v32, extra) + matchLen += v32; + } + #endif + STAT_INC(g_Num_Match) + } + } + } + + #if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) + FSE_PRELOAD + #endif + + { + size_t litLen = GET_FSE_REC_SYM(STATE_VAR(ll)); + if (litLen) + { + // if (STATE_VAR(ll) & 0x70) + if (litLen >= 16) + { + const unsigned extra = BASES_TABLE(SEQ_LL_EXTRA) [litLen]; + litLen = BASES_TABLE(SEQ_LL_BASES) [litLen]; + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + { + UPDATE_BIT_OFFSET(bitOffset, extra) + litLen += (size_t)(v >> (64 - extra)); + #if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #else + v <<= extra; + #endif + } + #else + { + UInt32 v32; + STREAM_READ_BITS(v32, extra) + litLen += v32; + } + #endif + STAT_INC(g_Num_LitsBig) + } + + if ((literalsLen -= (ptrdiff_t)litLen) < 0) + LZ_LOOP_ERROR_EXIT + totalOutCheck += litLen; + { + const size_t rem = winLimit - winPos; + if (litLen > rem) + LZ_LOOP_ERROR_EXIT + { + const Byte *literals_temp = literals; + Byte *d = win + winPos; + literals += litLen; + winPos += litLen; + CopyLiterals(d, literals_temp, litLen, rem); + } + } + } + STAT_UPDATE(else g_Num_Lit0++;) + } + + #define COPY_MATCH \ + { if (reps_0 > winSize || reps_0 > totalOutCheck) LZ_LOOP_ERROR_EXIT \ + totalOutCheck += matchLen; \ + { const size_t rem = winLimit - winPos; \ + if (matchLen > rem) LZ_LOOP_ERROR_EXIT \ + { const size_t winPos_temp = winPos; \ + winPos += matchLen; \ + CopyMatch(reps_0, matchLen, win, winPos_temp, rem, cycSize); }}} + + if (--numSeqs == 0) + { + COPY_MATCH + break; + } + FSE_UPDATE_STATES + COPY_MATCH + } // for + + if ((CBitCtr_signed)bitOffset != BIT_OFFSET_DELTA_BYTES * 8 - BIT_OFFSET_DELTA_BITS) + return SZ_ERROR_DATA; + + if (literalsLen) + { + const size_t rem = winLimit - winPos; + if ((size_t)literalsLen > rem) + return SZ_ERROR_DATA; + { + Byte *d = win + winPos; + winPos += (size_t)literalsLen; + totalOutCheck += (size_t)literalsLen; + CopyLiterals + // memcpy + (d, literals, (size_t)literalsLen, rem); + } + } + if (totalOutCheck >= winSize) + totalOutCheck = winSize; + p->totalOutCheck = totalOutCheck; + p->winPos = winPos; + p->reps[0] = (CZstdDecOffset)reps_0; + p->reps[1] = (CZstdDecOffset)reps_1; + p->reps[2] = (CZstdDecOffset)reps_2; + } + return SZ_OK; +} + + +// for debug: define to check that ZstdDec1_NeedTempBufferForInput() works correctly: +// #define Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP // define it for debug only +#ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP +static unsigned g_numSeqs; +#endif + + +#define k_LitBlockType_Flag_RLE_or_Treeless 1 +#define k_LitBlockType_Flag_Compressed 2 + +// outLimit : is strong limit +// outLimit <= ZstdDec1_GET_BLOCK_SIZE_LIMIT(p) +// inSize != 0 +static +Z7_NO_INLINE +SRes ZstdDec1_DecodeBlock(CZstdDec1 *p, + const Byte *src, SizeT inSize, SizeT afterAvail, + const size_t outLimit) +{ + CZstdDec1_Vars vars; + vars.literals = p->literalsBase; + { + const unsigned b0 = *src++; + UInt32 numLits, compressedSize; + const Byte *litStream; + Byte *literalsDest; + inSize--; + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + // we need at least one additional byte for (numSeqs). + // so we check for that additional byte in conditions. + numLits = b0 >> 3; + if (b0 & 4) + { + UInt32 v; + if (inSize < 1 + 1) // we need at least 1 byte here and 1 byte for (numSeqs). + return SZ_ERROR_DATA; + numLits >>= 1; + v = GetUi16(src); + src += 2; + inSize -= 2; + if ((b0 & 8) == 0) + { + src--; + inSize++; + v = (Byte)v; + } + numLits += v << 4; + } + compressedSize = 1; + if ((b0 & k_LitBlockType_Flag_RLE_or_Treeless) == 0) + compressedSize = numLits; + } + else if (inSize < 4) + return SZ_ERROR_DATA; + else + { + const unsigned mode4Streams = b0 & 0xc; + const unsigned numBytes = (3 * mode4Streams + 32) >> 4; + const unsigned numBits = 4 * numBytes - 2; + const UInt32 mask = ((UInt32)16 << numBits) - 1; + compressedSize = GetUi32(src); + numLits = (( + #ifdef MY_CPU_LE_UNALIGN + GetUi32(src - 1) + #else + ((compressedSize << 8) + b0) + #endif + ) >> 4) & mask; + src += numBytes; + inSize -= numBytes; + compressedSize >>= numBits; + compressedSize &= mask; + /* + if (numLits != 0) printf("inSize = %7u num_lits=%7u compressed=%7u ratio = %u ratio2 = %u\n", + i1, numLits, (unsigned)compressedSize * 1, (unsigned)compressedSize * 100 / numLits, + (unsigned)numLits * 100 / (unsigned)inSize); + } + */ + if (compressedSize == 0) + return SZ_ERROR_DATA; // (compressedSize == 0) is not allowed + } + + STAT_UPDATE(g_Num_Lits += numLits;) + + vars.literalsLen = numLits; + + if (compressedSize >= inSize) + return SZ_ERROR_DATA; + litStream = src; + src += compressedSize; + inSize -= compressedSize; + // inSize != 0 + { + UInt32 numSeqs = *src++; + inSize--; + if (numSeqs > 127) + { + UInt32 b1; + if (inSize == 0) + return SZ_ERROR_DATA; + numSeqs -= 128; + b1 = *src++; + inSize--; + if (numSeqs == 127) + { + if (inSize == 0) + return SZ_ERROR_DATA; + numSeqs = (UInt32)(*src++) + 127; + inSize--; + } + numSeqs = (numSeqs << 8) + b1; + } + if (numSeqs * MATCH_LEN_MIN + numLits > outLimit) + return SZ_ERROR_DATA; + vars.numSeqs = numSeqs; + + STAT_UPDATE(g_NumSeqs_total += numSeqs;) + /* + #ifdef SHOW_STAT + printf("\n %5u : %8u, %8u : %5u", (int)g_Num_Blocks_Compressed, (int)numSeqs, (int)g_NumSeqs_total, + (int)g_NumSeqs_total / g_Num_Blocks_Compressed); + #endif + // printf("\nnumSeqs2 = %d", numSeqs); + */ + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + if (numSeqs != g_numSeqs) return SZ_ERROR_DATA; // for debug + #endif + if (numSeqs == 0) + { + if (inSize != 0) + return SZ_ERROR_DATA; + literalsDest = p->win + p->winPos; + } + else + literalsDest = p->literalsBase; + } + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + if (b0 & k_LitBlockType_Flag_RLE_or_Treeless) + { + memset(literalsDest, litStream[0], numLits); + if (vars.numSeqs) + { + // literalsDest == p->literalsBase == vars.literals + #if COPY_CHUNK_SIZE > 1 + memset(p->literalsBase + numLits, 0, COPY_CHUNK_SIZE); + #endif + } + } + else + { + // unsigned y; + // for (y = 0; y < 10000; y++) + memcpy(literalsDest, litStream, numLits); + if (vars.numSeqs) + { + /* we need up to (15 == COPY_CHUNK_SIZE - 1) space for optimized CopyLiterals(). + If we have additional space in input stream after literals stream, + we use direct copy of rar literals in input stream */ + if ((size_t)(src + inSize - litStream) - numLits + afterAvail >= (COPY_CHUNK_SIZE - 1)) + vars.literals = litStream; + else + { + // literalsDest == p->literalsBase == vars.literals + #if COPY_CHUNK_SIZE > 1 + /* CopyLiterals(): + 1) we don't want reading non-initialized data + 2) we will copy only zero byte after literals buffer */ + memset(p->literalsBase + numLits, 0, COPY_CHUNK_SIZE); + #endif + } + } + } + } + else + { + CInBufPair hufStream; + hufStream.ptr = litStream; + hufStream.len = compressedSize; + + if ((b0 & k_LitBlockType_Flag_RLE_or_Treeless) == 0) + { + // unsigned y = 100; CInBufPair hs2 = hufStream; do { hufStream = hs2; + RINOK(Huf_DecodeTable(&p->huf, &hufStream)) + p->litHuf_wasSet = True; + // } while (--y); + } + else if (!p->litHuf_wasSet) + return SZ_ERROR_DATA; + + { + // int yyy; for (yyy = 0; yyy < 34; yyy++) { + SRes sres; + if ((b0 & 0xc) == 0) // mode4Streams + sres = Huf_Decompress_1stream((const Byte *)(const void *)p->huf.table64, + hufStream.ptr - HUF_SRC_OFFSET, hufStream.len, literalsDest, numLits); + else + { + // 6 bytes for the jump table + 4x1 bytes of end-padding Bytes) + if (hufStream.len < 6 + 4) + return SZ_ERROR_DATA; + // the condition from original-zstd decoder: + #define Z7_ZSTD_MIN_LITERALS_FOR_4_STREAMS 6 + if (numLits < Z7_ZSTD_MIN_LITERALS_FOR_4_STREAMS) + return SZ_ERROR_DATA; + sres = Huf_Decompress_4stream((const Byte *)(const void *)p->huf.table64, + hufStream.ptr + (6 - HUF_SRC_OFFSET), hufStream.len, literalsDest, numLits); + } + RINOK(sres) + // } + } + } + + if (vars.numSeqs == 0) + { + p->winPos += numLits; + UPDATE_TOTAL_OUT(p, numLits) + return SZ_OK; + } + } + { + CInBufPair in; + unsigned mode; + unsigned seqMode; + + in.ptr = src; + in.len = inSize; + if (in.len == 0) + return SZ_ERROR_DATA; + in.len--; + mode = *in.ptr++; + if (mode & 3) // Reserved bits + return SZ_ERROR_DATA; + + seqMode = (mode >> 6); + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else RINOK(FSE_Decode_SeqTable( + p->fse.ll, + &in, + 6, // predefAccuracy + &p->ll_accuracy, + NUM_LL_SYMBOLS, + k_PredefRecords_LL, + seqMode)) + + seqMode = (mode >> 4) & 3; + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else RINOK(FSE_Decode_SeqTable( + p->fse.of, + &in, + 5, // predefAccuracy + &p->of_accuracy, + NUM_OFFSET_SYMBOLS_MAX, + k_PredefRecords_OF, + seqMode)) + + seqMode = (mode >> 2) & 3; + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else + { + RINOK(FSE_Decode_SeqTable( + p->fse.ml, + &in, + 6, // predefAccuracy + &p->ml_accuracy, + NUM_ML_SYMBOLS, + k_PredefRecords_ML, + seqMode)) + /* + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + // { unsigned y = 1 << 10; do + { + const unsigned accuracy = p->ml_accuracy; + if (accuracy == 0) + p->fse.ml[0] += 3; + else + #ifdef MY_CPU_64BIT + { + // alignemt (UInt64 _pad_Alignment) in fse.ml is required for that code + UInt64 *table = (UInt64 *)(void *)p->fse.ml; + const UInt64 *end = (const UInt64 *)(const void *) + ((const Byte *)(const void *)table + ((size_t)sizeof(CFseRecord) << accuracy)); + do + { + table[0] += ((UInt64)MATCH_LEN_MIN << 32) + MATCH_LEN_MIN; + table[1] += ((UInt64)MATCH_LEN_MIN << 32) + MATCH_LEN_MIN; + table += 2; + } + while (table != end); + } + #else + { + UInt32 *table = p->fse.ml; + const UInt32 *end = (const UInt32 *)(const void *) + ((const Byte *)(const void *)table + ((size_t)sizeof(CFseRecord) << accuracy)); + do + { + table[0] += MATCH_LEN_MIN; + table[1] += MATCH_LEN_MIN; + table += 2; + table[0] += MATCH_LEN_MIN; + table[1] += MATCH_LEN_MIN; + table += 2; + } + while (table != end); + } + #endif + } + // while (--y); } + #endif + */ + } + + // p->seqTables_wereSet = True; + if (in.len == 0) + return SZ_ERROR_DATA; + return Decompress_Sequences(p, + in.ptr - SEQ_SRC_OFFSET - BIT_OFFSET_DELTA_BYTES, in.len, + p->winPos + outLimit, &vars); + } +} + + + + +// inSize != 0 +// it must do similar to ZstdDec1_DecodeBlock() +static size_t ZstdDec1_NeedTempBufferForInput( + const SizeT beforeSize, const Byte * const src, const SizeT inSize) +{ + unsigned b0; + UInt32 pos; + + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + g_numSeqs = 1 << 24; + #else + // we have at least 3 bytes before seq data: litBlockType, numSeqs, seqMode + #define MIN_BLOCK_LZ_HEADERS_SIZE 3 + if (beforeSize >= MAX_BACKWARD_DEPTH - MIN_BLOCK_LZ_HEADERS_SIZE) + return 0; + #endif + + b0 = src[0]; + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + UInt32 numLits = b0 >> 3; + pos = 1; + if (b0 & 4) + { + UInt32 v; + if (inSize < 3) + return 0; + numLits >>= 1; + v = GetUi16(src + 1); + pos = 3; + if ((b0 & 8) == 0) + { + pos = 2; + v = (Byte)v; + } + numLits += v << 4; + } + if (b0 & k_LitBlockType_Flag_RLE_or_Treeless) + numLits = 1; + pos += numLits; + } + else if (inSize < 5) + return 0; + else + { + const unsigned mode4Streams = b0 & 0xc; + const unsigned numBytes = (3 * mode4Streams + 48) >> 4; + const unsigned numBits = 4 * numBytes - 6; + UInt32 cs = GetUi32(src + 1); + cs >>= numBits; + cs &= ((UInt32)16 << numBits) - 1; + if (cs == 0) + return 0; + pos = numBytes + cs; + } + + if (pos >= inSize) + return 0; + { + UInt32 numSeqs = src[pos++]; + if (numSeqs > 127) + { + UInt32 b1; + if (pos >= inSize) + return 0; + numSeqs -= 128; + b1 = src[pos++]; + if (numSeqs == 127) + { + if (pos >= inSize) + return 0; + numSeqs = (UInt32)(src[pos++]) + 127; + } + numSeqs = (numSeqs << 8) + b1; + } + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + g_numSeqs = numSeqs; // for debug + #endif + if (numSeqs == 0) + return 0; + } + /* + if (pos >= inSize) + return 0; + pos++; + */ + // we will have one additional byte for seqMode: + if (beforeSize + pos >= MAX_BACKWARD_DEPTH - 1) + return 0; + return 1; +} + + + +// ---------- ZSTD FRAME ---------- + +#define kBlockType_Raw 0 +#define kBlockType_RLE 1 +#define kBlockType_Compressed 2 +#define kBlockType_Reserved 3 + +typedef enum +{ + // begin: states that require 4 bytes: + ZSTD2_STATE_SIGNATURE, + ZSTD2_STATE_HASH, + ZSTD2_STATE_SKIP_HEADER, + // end of states that require 4 bytes + + ZSTD2_STATE_SKIP_DATA, + ZSTD2_STATE_FRAME_HEADER, + ZSTD2_STATE_AFTER_HEADER, + ZSTD2_STATE_BLOCK, + ZSTD2_STATE_DATA, + ZSTD2_STATE_FINISHED +} EZstd2State; + + +struct CZstdDec +{ + EZstd2State frameState; + unsigned tempSize; + + Byte temp[14]; // 14 is required + + Byte descriptor; + Byte windowDescriptor; + Byte isLastBlock; + Byte blockType; + Byte isErrorState; + Byte hashError; + Byte disableHash; + Byte isCyclicMode; + + UInt32 blockSize; + UInt32 dictionaryId; + UInt32 curBlockUnpackRem; // for compressed blocks only + UInt32 inTempPos; + + UInt64 contentSize; + UInt64 contentProcessed; + CXxh64State xxh64; + + Byte *inTemp; + SizeT winBufSize_Allocated; + Byte *win_Base; + + ISzAllocPtr alloc_Small; + ISzAllocPtr alloc_Big; + + CZstdDec1 decoder; +}; + +#define ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p) \ + ((unsigned)(p)->contentProcessed & (Z7_XXH64_BLOCK_SIZE - 1)) + +#define ZSTD_DEC_IS_LAST_BLOCK(p) ((p)->isLastBlock) + + +static void ZstdDec_FreeWindow(CZstdDec * const p) +{ + if (p->win_Base) + { + ISzAlloc_Free(p->alloc_Big, p->win_Base); + p->win_Base = NULL; + // p->decoder.win = NULL; + p->winBufSize_Allocated = 0; + } +} + + +CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big) +{ + CZstdDec *p = (CZstdDec *)ISzAlloc_Alloc(alloc_Small, sizeof(CZstdDec)); + if (!p) + return NULL; + p->alloc_Small = alloc_Small; + p->alloc_Big = alloc_Big; + // ZstdDec_CONSTRUCT(p) + p->inTemp = NULL; + p->win_Base = NULL; + p->winBufSize_Allocated = 0; + p->disableHash = False; + ZstdDec1_Construct(&p->decoder); + return p; +} + +void ZstdDec_Destroy(CZstdDecHandle p) +{ + #ifdef SHOW_STAT + #define PRINT_STAT1(name, v) \ + printf("\n%25s = %9u", name, v); + PRINT_STAT1("g_Num_Blocks_Compressed", g_Num_Blocks_Compressed) + PRINT_STAT1("g_Num_Blocks_memcpy", g_Num_Blocks_memcpy) + PRINT_STAT1("g_Num_Wrap_memmove_Num", g_Num_Wrap_memmove_Num) + PRINT_STAT1("g_Num_Wrap_memmove_Bytes", g_Num_Wrap_memmove_Bytes) + if (g_Num_Blocks_Compressed) + { + #define PRINT_STAT(name, v) \ + printf("\n%17s = %9u, per_block = %8u", name, v, v / g_Num_Blocks_Compressed); + PRINT_STAT("g_NumSeqs", g_NumSeqs_total) + // PRINT_STAT("g_NumCopy", g_NumCopy) + PRINT_STAT("g_NumOver", g_NumOver) + PRINT_STAT("g_NumOver2", g_NumOver2) + PRINT_STAT("g_Num_Match", g_Num_Match) + PRINT_STAT("g_Num_Lits", g_Num_Lits) + PRINT_STAT("g_Num_LitsBig", g_Num_LitsBig) + PRINT_STAT("g_Num_Lit0", g_Num_Lit0) + PRINT_STAT("g_Num_Rep_0", g_Num_Rep0) + PRINT_STAT("g_Num_Rep_1", g_Num_Rep1) + PRINT_STAT("g_Num_Rep_2", g_Num_Rep2) + PRINT_STAT("g_Num_Rep_3", g_Num_Rep3) + PRINT_STAT("g_Num_Threshold_0", g_Num_Threshold_0) + PRINT_STAT("g_Num_Threshold_1", g_Num_Threshold_1) + PRINT_STAT("g_Num_Threshold_0sum", g_Num_Threshold_0sum) + PRINT_STAT("g_Num_Threshold_1sum", g_Num_Threshold_1sum) + } + printf("\n"); + #endif + + ISzAlloc_Free(p->alloc_Small, p->decoder.literalsBase); + // p->->decoder.literalsBase = NULL; + ISzAlloc_Free(p->alloc_Small, p->inTemp); + // p->inTemp = NULL; + ZstdDec_FreeWindow(p); + ISzAlloc_Free(p->alloc_Small, p); +} + + + +#define kTempBuffer_PreSize (1u << 6) +#if kTempBuffer_PreSize < MAX_BACKWARD_DEPTH + #error Stop_Compiling_Bad_kTempBuffer_PreSize +#endif + +static SRes ZstdDec_AllocateMisc(CZstdDec *p) +{ + #define k_Lit_AfterAvail (1u << 6) + #if k_Lit_AfterAvail < (COPY_CHUNK_SIZE - 1) + #error Stop_Compiling_Bad_k_Lit_AfterAvail + #endif + // return ZstdDec1_Allocate(&p->decoder, p->alloc_Small); + if (!p->decoder.literalsBase) + { + p->decoder.literalsBase = (Byte *)ISzAlloc_Alloc(p->alloc_Small, + kBlockSizeMax + k_Lit_AfterAvail); + if (!p->decoder.literalsBase) + return SZ_ERROR_MEM; + } + if (!p->inTemp) + { + // we need k_Lit_AfterAvail here for owerread from raw literals stream + p->inTemp = (Byte *)ISzAlloc_Alloc(p->alloc_Small, + kBlockSizeMax + kTempBuffer_PreSize + k_Lit_AfterAvail); + if (!p->inTemp) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + + +static void ZstdDec_Init_ForNewFrame(CZstdDec *p) +{ + p->frameState = ZSTD2_STATE_SIGNATURE; + p->tempSize = 0; + + p->isErrorState = False; + p->hashError = False; + p->isCyclicMode = False; + p->contentProcessed = 0; + Xxh64State_Init(&p->xxh64); + ZstdDec1_Init(&p->decoder); +} + + +void ZstdDec_Init(CZstdDec *p) +{ + ZstdDec_Init_ForNewFrame(p); + p->decoder.winPos = 0; + memset(p->temp, 0, sizeof(p->temp)); +} + + +#define DESCRIPTOR_Get_DictionaryId_Flag(d) ((d) & 3) +#define DESCRIPTOR_FLAG_CHECKSUM (1 << 2) +#define DESCRIPTOR_FLAG_RESERVED (1 << 3) +// #define DESCRIPTOR_FLAG_UNUSED (1 << 4) +#define DESCRIPTOR_FLAG_SINGLE (1 << 5) +#define DESCRIPTOR_Get_ContentSize_Flag3(d) ((d) >> 5) +#define DESCRIPTOR_Is_ContentSize_Defined(d) (((d) & 0xe0) != 0) + + +static EZstd2State ZstdDec_UpdateState(CZstdDec * const p, const Byte b, CZstdDecInfo * const info) +{ + unsigned tempSize = p->tempSize; + p->temp[tempSize++] = b; + p->tempSize = tempSize; + + if (p->frameState == ZSTD2_STATE_BLOCK) + { + if (tempSize < 3) + return ZSTD2_STATE_BLOCK; + { + UInt32 b0 = GetUi32(p->temp); + const unsigned type = ((unsigned)b0 >> 1) & 3; + if (type == kBlockType_RLE && tempSize == 3) + return ZSTD2_STATE_BLOCK; + // info->num_Blocks_forType[type]++; + info->num_Blocks++; + if (type == kBlockType_Reserved) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED + return ZSTD2_STATE_BLOCK; + } + p->blockType = (Byte)type; + p->isLastBlock = (Byte)(b0 & 1); + p->inTempPos = 0; + p->tempSize = 0; + b0 >>= 3; + b0 &= 0x1fffff; + // info->num_BlockBytes_forType[type] += b0; + if (b0 == 0) + { + // empty RAW/RLE blocks are allowed in original-zstd decoder + if (type == kBlockType_Compressed) + { + p->isErrorState = True; + return ZSTD2_STATE_BLOCK; + } + if (!ZSTD_DEC_IS_LAST_BLOCK(p)) + return ZSTD2_STATE_BLOCK; + if (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) + return ZSTD2_STATE_HASH; + return ZSTD2_STATE_FINISHED; + } + p->blockSize = b0; + { + UInt32 blockLim = ZstdDec1_GET_BLOCK_SIZE_LIMIT(&p->decoder); + // compressed and uncompressed block sizes cannot be larger than min(kBlockSizeMax, window_size) + if (b0 > blockLim) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED; + return ZSTD2_STATE_BLOCK; + } + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor)) + { + const UInt64 rem = p->contentSize - p->contentProcessed; + if (blockLim > rem) + blockLim = (UInt32)rem; + } + p->curBlockUnpackRem = blockLim; + // uncompressed block size cannot be larger than remain data size: + if (type != kBlockType_Compressed) + { + if (b0 > blockLim) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED; + return ZSTD2_STATE_BLOCK; + } + } + } + } + return ZSTD2_STATE_DATA; + } + + if ((unsigned)p->frameState < ZSTD2_STATE_SKIP_DATA) + { + UInt32 v; + if (tempSize != 4) + return p->frameState; + v = GetUi32(p->temp); + if ((unsigned)p->frameState < ZSTD2_STATE_HASH) // == ZSTD2_STATE_SIGNATURE + { + if (v == 0xfd2fb528) + { + p->tempSize = 0; + info->num_DataFrames++; + return ZSTD2_STATE_FRAME_HEADER; + } + if ((v & 0xfffffff0) == 0x184d2a50) + { + p->tempSize = 0; + info->num_SkipFrames++; + return ZSTD2_STATE_SKIP_HEADER; + } + p->isErrorState = True; + return ZSTD2_STATE_SIGNATURE; + // return ZSTD2_STATE_ERROR; // is not ZSTD stream + } + if (p->frameState == ZSTD2_STATE_HASH) + { + info->checksum_Defined = True; + info->checksum = v; + // #ifndef DISABLE_XXH_CHECK + if (!p->disableHash) + { + if (p->decoder.winPos < ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p)) + { + // unexpected code failure + p->isErrorState = True; + // SZ_ERROR_FAIL; + } + else + if ((UInt32)Xxh64State_Digest(&p->xxh64, + p->decoder.win + (p->decoder.winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p)), + p->contentProcessed) != v) + { + p->hashError = True; + // return ZSTD2_STATE_ERROR; // hash error + } + } + // #endif + return ZSTD2_STATE_FINISHED; + } + // (p->frameState == ZSTD2_STATE_SKIP_HEADER) + { + p->blockSize = v; + info->skipFrames_Size += v; + p->tempSize = 0; + /* we want the caller could know that there was finished frame + finished frame. So we allow the case where + we have ZSTD2_STATE_SKIP_DATA state with (blockSize == 0). + */ + // if (v == 0) return ZSTD2_STATE_SIGNATURE; + return ZSTD2_STATE_SKIP_DATA; + } + } + + // if (p->frameState == ZSTD2_STATE_FRAME_HEADER) + { + unsigned descriptor; + const Byte *h; + descriptor = p->temp[0]; + p->descriptor = (Byte)descriptor; + if (descriptor & DESCRIPTOR_FLAG_RESERVED) // reserved bit + { + p->isErrorState = True; + return ZSTD2_STATE_FRAME_HEADER; + // return ZSTD2_STATE_ERROR; + } + { + const unsigned n = DESCRIPTOR_Get_ContentSize_Flag3(descriptor); + // tempSize -= 1 + ((1u << (n >> 1)) | ((n + 1) & 1)); + tempSize -= (0x9a563422u >> (n * 4)) & 0xf; + } + if (tempSize != (4u >> (3 - DESCRIPTOR_Get_DictionaryId_Flag(descriptor)))) + return ZSTD2_STATE_FRAME_HEADER; + + info->descriptor_OR = (Byte)(info->descriptor_OR | descriptor); + info->descriptor_NOT_OR = (Byte)(info->descriptor_NOT_OR | ~descriptor); + + h = &p->temp[1]; + { + Byte w = 0; + if ((descriptor & DESCRIPTOR_FLAG_SINGLE) == 0) + { + w = *h++; + if (info->windowDescriptor_MAX < w) + info->windowDescriptor_MAX = w; + // info->are_WindowDescriptors = True; + // info->num_WindowDescriptors++; + } + else + { + // info->are_SingleSegments = True; + // info->num_SingleSegments++; + } + p->windowDescriptor = w; + } + { + unsigned n = DESCRIPTOR_Get_DictionaryId_Flag(descriptor); + UInt32 d = 0; + if (n) + { + n = 1u << (n - 1); + d = GetUi32(h) & ((UInt32)(Int32)-1 >> (32 - 8u * n)); + h += n; + } + p->dictionaryId = d; + // info->dictionaryId_Cur = d; + if (d != 0) + { + if (info->dictionaryId == 0) + info->dictionaryId = d; + else if (info->dictionaryId != d) + info->are_DictionaryId_Different = True; + } + } + { + unsigned n = DESCRIPTOR_Get_ContentSize_Flag3(descriptor); + UInt64 v = 0; + if (n) + { + n >>= 1; + if (n == 1) + v = 256; + v += GetUi64(h) & ((UInt64)(Int64)-1 >> (64 - (8u << n))); + // info->are_ContentSize_Known = True; + // info->num_Frames_with_ContentSize++; + if (info->contentSize_MAX < v) + info->contentSize_MAX = v; + info->contentSize_Total += v; + } + else + { + info->are_ContentSize_Unknown = True; + // info->num_Frames_without_ContentSize++; + } + p->contentSize = v; + } + // if ((size_t)(h - p->temp) != headerSize) return ZSTD2_STATE_ERROR; // it's unexpected internal code failure + p->tempSize = 0; + + info->checksum_Defined = False; + /* + if (descriptor & DESCRIPTOR_FLAG_CHECKSUM) + info->are_Checksums = True; + else + info->are_Non_Checksums = True; + */ + + return ZSTD2_STATE_AFTER_HEADER; // ZSTD2_STATE_BLOCK; + } +} + + +static void ZstdDec_Update_XXH(CZstdDec * const p, size_t xxh64_winPos) +{ + /* + #ifdef DISABLE_XXH_CHECK + UNUSED_VAR(data) + #else + */ + if (!p->disableHash && (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM)) + { + // const size_t pos = p->xxh64_winPos; + const size_t size = (p->decoder.winPos - xxh64_winPos) & ~(size_t)31; + if (size) + { + // p->xxh64_winPos = pos + size; + Xxh64State_UpdateBlocks(&p->xxh64, + p->decoder.win + xxh64_winPos, + p->decoder.win + xxh64_winPos + size); + } + } +} + + +/* +in: + (winLimit) : is relaxed limit, where this function is allowed to stop writing of decoded data (if possible). + - this function uses (winLimit) for RAW/RLE blocks only, + because this function can decode single RAW/RLE block in several different calls. + - this function DOESN'T use (winLimit) for Compressed blocks, + because this function decodes full compressed block in single call. + (CZstdDec1::winPos <= winLimit) + (winLimit <= CZstdDec1::cycSize). + Note: if (ds->outBuf_fromCaller) mode is used, then + { + (strong_limit) is stored in CZstdDec1::cycSize. + So (winLimit) is more strong than (strong_limit). + } + +exit: + Note: (CZstdDecState::winPos) will be set by caller after exit of this function. + + This function can exit for any of these conditions: + - (frameState == ZSTD2_STATE_AFTER_HEADER) + - (frameState == ZSTD2_STATE_FINISHED) : frame was finished : (status == ZSTD_STATUS_FINISHED_FRAME) is set + - finished non-empty non-last block. So (CZstdDec1::winPos_atExit != winPos_atFuncStart). + - ZSTD_STATUS_NEEDS_MORE_INPUT in src + - (CZstdDec1::winPos) have reached (winLimit) in non-finished RAW/RLE block + + This function decodes no more than one non-empty block. + So it fulfills the condition at exit: + (CZstdDec1::winPos_atExit - winPos_atFuncStart <= block_size_max) + Note: (winPos_atExit > winLimit) is possible in some cases after compressed block decoding. + + if (ds->outBuf_fromCaller) mode (useAdditionalWinLimit medo) + { + then this function uses additional strong limit from (CZstdDec1::cycSize). + So this function will not write any data after (CZstdDec1::cycSize) + And it fulfills the condition at exit: + (CZstdDec1::winPos_atExit <= CZstdDec1::cycSize) + } +*/ +static SRes ZstdDec_DecodeBlock(CZstdDec * const p, CZstdDecState * const ds, + SizeT winLimitAdd) +{ + const Byte *src = ds->inBuf; + SizeT * const srcLen = &ds->inPos; + const SizeT inSize = ds->inLim; + // const int useAdditionalWinLimit = ds->outBuf_fromCaller ? 1 : 0; + enum_ZstdStatus * const status = &ds->status; + CZstdDecInfo * const info = &ds->info; + SizeT winLimit; + + const SizeT winPos_atFuncStart = p->decoder.winPos; + src += *srcLen; + *status = ZSTD_STATUS_NOT_SPECIFIED; + + // finishMode = ZSTD_FINISH_ANY; + if (ds->outSize_Defined) + { + if (ds->outSize < ds->outProcessed) + { + // p->isAfterSizeMode = 2; // we have extra bytes already + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + // size = 0; + } + else + { + // p->outSize >= p->outProcessed + const UInt64 rem = ds->outSize - ds->outProcessed; + /* + if (rem == 0) + p->isAfterSizeMode = 1; // we have reached exact required size + */ + if (winLimitAdd >= rem) + { + winLimitAdd = (SizeT)rem; + // if (p->finishMode) finishMode = ZSTD_FINISH_END; + } + } + } + + winLimit = p->decoder.winPos + winLimitAdd; + // (p->decoder.winPos <= winLimit) + + // while (p->frameState != ZSTD2_STATE_ERROR) + while (!p->isErrorState) + { + SizeT inCur = inSize - *srcLen; + + if (p->frameState == ZSTD2_STATE_DATA) + { + /* (p->decoder.winPos == winPos_atFuncStart) is expected, + because this function doesn't start new block. + if it have finished some non-empty block in this call. */ + if (p->decoder.winPos != winPos_atFuncStart) + return SZ_ERROR_FAIL; // it's unexpected + + /* + if (p->decoder.winPos > winLimit) + { + // we can be here, if in this function call + // - we have extracted non-empty compressed block, and (winPos > winLimit) after that. + // - we have started new block decoding after that. + // It's unexpected case, because we exit after non-empty non-last block. + *status = (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED; + return SZ_OK; + } + */ + // p->decoder.winPos <= winLimit + + if (p->blockType != kBlockType_Compressed) + { + // it's RLE or RAW block. + // p->BlockSize != 0_ + // winLimit <= p->decoder.cycSize + /* So here we use more strong (winLimit), even for + (ds->outBuf_fromCaller) mode. */ + SizeT outCur = winLimit - p->decoder.winPos; + { + const UInt32 rem = p->blockSize; + if (outCur > rem) + outCur = rem; + } + if (p->blockType == kBlockType_Raw) + { + if (outCur > inCur) + outCur = inCur; + /* output buffer is better aligned for XXH code. + So we use hash for output buffer data */ + // ZstdDec_Update_XXH(p, src, outCur); // for debug: + memcpy(p->decoder.win + p->decoder.winPos, src, outCur); + src += outCur; + *srcLen += outCur; + } + else // kBlockType_RLE + { + #define RLE_BYTE_INDEX_IN_temp 3 + memset(p->decoder.win + p->decoder.winPos, + p->temp[RLE_BYTE_INDEX_IN_temp], outCur); + } + { + const SizeT xxh64_winPos = p->decoder.winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p); + p->decoder.winPos += outCur; + UPDATE_TOTAL_OUT(&p->decoder, outCur) + p->contentProcessed += outCur; + ZstdDec_Update_XXH(p, xxh64_winPos); + } + // ds->winPos = p->decoder.winPos; // the caller does it instead. for debug: + ds->outProcessed += outCur; + if (p->blockSize -= (UInt32)outCur) + { + /* + if (ds->outSize_Defined) + { + if (ds->outSize <= ds->outProcessed) ds->isAfterSizeMode = (enum_ZstdStatus) + (ds->outSize == ds->outProcessed ? 1u: 2u); + } + */ + *status = (enum_ZstdStatus) + (ds->outSize_Defined && ds->outSize <= ds->outProcessed ? + ZSTD_STATUS_OUT_REACHED : (p->blockType == kBlockType_Raw && inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED); + return SZ_OK; + } + } + else // kBlockType_Compressed + { + // p->blockSize != 0 + // (uncompressed_size_of_block == 0) is allowed + // (p->curBlockUnpackRem == 0) is allowed + /* + if (p->decoder.winPos >= winLimit) + { + if (p->decoder.winPos != winPos_atFuncStart) + { + // it's unexpected case + // We already have some data in finished blocks in this function call. + // So we don't decompress new block after (>=winLimit), + // even if it's empty block. + *status = (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED; + return SZ_OK; + } + // (p->decoder.winPos == winLimit == winPos_atFuncStart) + // we will decode current block, because that current + // block can be empty block and we want to make some visible + // change of (src) stream after function start. + } + */ + /* + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + // we don't want to start new block, if we have more extra decoded bytes already + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + } + */ + { + const Byte *comprStream; + size_t afterAvail; + UInt32 inTempPos = p->inTempPos; + const UInt32 rem = p->blockSize - inTempPos; + // rem != 0 + if (inTempPos != 0 // (inTemp) buffer already contains some input data + || inCur < rem // available input data size is smaller than compressed block size + || ZstdDec1_NeedTempBufferForInput(*srcLen, src, rem)) + { + if (inCur > rem) + inCur = rem; + if (inCur) + { + STAT_INC(g_Num_Blocks_memcpy) + // we clear data for backward lookahead reading + if (inTempPos == 0) + memset(p->inTemp + kTempBuffer_PreSize - MAX_BACKWARD_DEPTH, 0, MAX_BACKWARD_DEPTH); + // { unsigned y = 0; for(;y < 1000; y++) + memcpy(p->inTemp + inTempPos + kTempBuffer_PreSize, src, inCur); + // } + src += inCur; + *srcLen += inCur; + inTempPos += (UInt32)inCur; + p->inTempPos = inTempPos; + } + if (inTempPos != p->blockSize) + { + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + #if COPY_CHUNK_SIZE > 1 + memset(p->inTemp + kTempBuffer_PreSize + inTempPos, 0, COPY_CHUNK_SIZE); + #endif + comprStream = p->inTemp + kTempBuffer_PreSize; + afterAvail = k_Lit_AfterAvail; + // we don't want to read non-initialized data or junk in CopyMatch(): + } + else + { + // inCur >= rem + // we use direct decoding from (src) buffer: + afterAvail = inCur - rem; + comprStream = src; + src += rem; + *srcLen += rem; + } + + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + ZstdDec1_NeedTempBufferForInput(*srcLen, comprStream, p->blockSize); + #endif + // printf("\nblockSize=%u", p->blockSize); + // printf("%x\n", (unsigned)p->contentProcessed); + STAT_INC(g_Num_Blocks_Compressed) + { + SRes sres; + const size_t winPos = p->decoder.winPos; + /* + if ( useAdditionalWinLimit), we use strong unpack limit: smallest from + - limit from stream : (curBlockUnpackRem) + - limit from caller : (cycSize - winPos) + if (!useAdditionalWinLimit), we use only relaxed limit: + - limit from stream : (curBlockUnpackRem) + */ + SizeT outLimit = p->curBlockUnpackRem; + if (ds->outBuf_fromCaller) + // if (useAdditionalWinLimit) + { + const size_t limit = p->decoder.cycSize - winPos; + if (outLimit > limit) + outLimit = limit; + } + sres = ZstdDec1_DecodeBlock(&p->decoder, + comprStream, p->blockSize, afterAvail, outLimit); + // ds->winPos = p->decoder.winPos; // the caller does it instead. for debug: + if (sres) + { + p->isErrorState = True; + return sres; + } + { + const SizeT xxh64_winPos = winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p); + const size_t num = p->decoder.winPos - winPos; + ds->outProcessed += num; + p->contentProcessed += num; + ZstdDec_Update_XXH(p, xxh64_winPos); + } + } + // printf("\nwinPos=%x", (int)(unsigned)p->decoder.winPos); + } + } + + /* + if (ds->outSize_Defined) + { + if (ds->outSize <= ds->outProcessed) ds->isAfterSizeMode = (enum_ZstdStatus) + (ds->outSize == ds->outProcessed ? 1u: 2u); + } + */ + + if (!ZSTD_DEC_IS_LAST_BLOCK(p)) + { + p->frameState = ZSTD2_STATE_BLOCK; + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + } + // we exit only if (winPos) was changed in this function call: + if (p->decoder.winPos != winPos_atFuncStart) + { + // decoded block was not empty. So we exit: + *status = (enum_ZstdStatus)( + (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED); + return SZ_OK; + } + // (p->decoder.winPos == winPos_atFuncStart) + // so current decoded block was empty. + // we will try to decode more blocks in this function. + continue; + } + + // decoded block was last in frame + if (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) + { + p->frameState = ZSTD2_STATE_HASH; + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; // disable if want to + /* We want to get same return codes for any input buffer sizes. + We want to get faster ZSTD_STATUS_OUT_REACHED status. + So we exit with ZSTD_STATUS_OUT_REACHED here, + instead of ZSTD2_STATE_HASH and ZSTD2_STATE_FINISHED processing. + that depends from input buffer size and that can set + ZSTD_STATUS_NEEDS_MORE_INPUT or return SZ_ERROR_DATA or SZ_ERROR_CRC. + */ + } + } + else + { + /* ZSTD2_STATE_FINISHED proccesing doesn't depend from input buffer */ + p->frameState = ZSTD2_STATE_FINISHED; + } + /* + p->frameState = (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) ? + ZSTD2_STATE_HASH : + ZSTD2_STATE_FINISHED; + */ + /* it's required to process ZSTD2_STATE_FINISHED state in this function call, + because we must check contentSize and hashError in ZSTD2_STATE_FINISHED code, + while the caller can reinit full state for ZSTD2_STATE_FINISHED + So we can't exit from function here. */ + continue; + } + + if (p->frameState == ZSTD2_STATE_FINISHED) + { + *status = ZSTD_STATUS_FINISHED_FRAME; + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor) + && p->contentSize != p->contentProcessed) + return SZ_ERROR_DATA; + if (p->hashError) // for debug + return SZ_ERROR_CRC; + return SZ_OK; + // p->frameState = ZSTD2_STATE_SIGNATURE; + // continue; + } + + if (p->frameState == ZSTD2_STATE_AFTER_HEADER) + return SZ_OK; // we need memory allocation for that state + + if (p->frameState == ZSTD2_STATE_SKIP_DATA) + { + UInt32 blockSize = p->blockSize; + // (blockSize == 0) is possible + if (inCur > blockSize) + inCur = blockSize; + src += inCur; + *srcLen += inCur; + blockSize -= (UInt32)inCur; + p->blockSize = blockSize; + if (blockSize == 0) + { + p->frameState = ZSTD2_STATE_SIGNATURE; + // continue; // for debug: we can continue without return to caller. + // we notify the caller that skip frame was finished: + *status = ZSTD_STATUS_FINISHED_FRAME; + return SZ_OK; + } + // blockSize != 0 + // (inCur) was smaller than previous value of p->blockSize. + // (inSize == *srcLen) now + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (inCur == 0) + { + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + { + (*srcLen)++; + p->frameState = ZstdDec_UpdateState(p, *src++, info); + } + } + + *status = ZSTD_STATUS_NOT_SPECIFIED; + p->isErrorState = True; + // p->frameState = ZSTD2_STATE_ERROR; + // if (p->frameState = ZSTD2_STATE_SIGNATURE) return SZ_ERROR_NO_ARCHIVE + return SZ_ERROR_DATA; +} + + + + +SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p) +{ + p->needWrite_Size = 0; + p->status = ZSTD_STATUS_NOT_SPECIFIED; + dec->disableHash = p->disableHash; + + if (p->outBuf_fromCaller) + { + dec->decoder.win = p->outBuf_fromCaller; + dec->decoder.cycSize = p->outBufSize_fromCaller; + } + + // p->winPos = dec->decoder.winPos; + + for (;;) + { + SizeT winPos, size; + // SizeT outProcessed; + SRes res; + + if (p->wrPos > dec->decoder.winPos) + return SZ_ERROR_FAIL; + + if (dec->frameState == ZSTD2_STATE_FINISHED) + { + if (!p->outBuf_fromCaller) + { + // we need to set positions to zero for new frame. + if (p->wrPos != dec->decoder.winPos) + { + /* We have already asked the caller to flush all data + with (p->needWrite_Size) and (ZSTD_STATUS_FINISHED_FRAME) status. + So it's unexpected case */ + // p->winPos = dec->decoder.winPos; + // p->needWrite_Size = dec->decoder.winPos - p->wrPos; // flush size asking + // return SZ_OK; // ask to flush again + return SZ_ERROR_FAIL; + } + // (p->wrPos == dec->decoder.winPos), and we wrap to zero: + dec->decoder.winPos = 0; + p->winPos = 0; + p->wrPos = 0; + } + ZstdDec_Init_ForNewFrame(dec); + // continue; + } + + winPos = dec->decoder.winPos; + { + SizeT next = dec->decoder.cycSize; + /* cycSize == 0, if no buffer was allocated still, + or, if (outBuf_fromCaller) mode and (outBufSize_fromCaller == 0) */ + if (!p->outBuf_fromCaller + && next + && next <= winPos + && dec->isCyclicMode) + { + // (0 < decoder.cycSize <= winPos) in isCyclicMode. + // so we need to wrap (winPos) and (wrPos) over (cycSize). + const size_t delta = next; + // (delta) is how many bytes we remove from buffer. + /* + // we don't need data older than last (cycSize) bytes. + size_t delta = winPos - next; // num bytes after (cycSize) + if (delta <= next) // it's expected case + delta = next; + // delta == Max(cycSize, winPos - cycSize) + */ + if (p->wrPos < delta) + { + // (wrPos < decoder.cycSize) + // We have asked already the caller to flush required data + // p->status = ZSTD_STATUS_NOT_SPECIFIED; + // p->winPos = winPos; + // p->needWrite_Size = delta - p->wrPos; // flush size asking + // return SZ_OK; // ask to flush again + return SZ_ERROR_FAIL; + } + // p->wrPos >= decoder.cycSize + // we move extra data after (decoder.cycSize) to start of cyclic buffer: + winPos -= delta; + if (winPos) + { + if (winPos >= delta) + return SZ_ERROR_FAIL; + memmove(dec->decoder.win, dec->decoder.win + delta, winPos); + // printf("\nmemmove processed=%8x winPos=%8x\n", (unsigned)p->outProcessed, (unsigned)dec->decoder.winPos); + STAT_INC(g_Num_Wrap_memmove_Num) + STAT_UPDATE(g_Num_Wrap_memmove_Bytes += (unsigned)winPos;) + } + dec->decoder.winPos = winPos; + p->winPos = winPos; + p->wrPos -= delta; + // dec->xxh64_winPos -= delta; + + // (winPos < delta) + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + /* we set the data after cycSize, because + we don't want to read non-initialized data or junk in CopyMatch(). */ + memset(dec->decoder.win + next, 0, COPY_CHUNK_SIZE); + #endif + + /* + if (winPos == next) + { + if (winPos != p->wrPos) + { + // we already requested before to flush full data for that case. + // but we give the caller a second chance to flush data: + p->needWrite_Size = winPos - p->wrPos; + return SZ_OK; + } + // (decoder.cycSize == winPos == p->wrPos) + // so we do second wrapping to zero: + winPos = 0; + dec->decoder.winPos = 0; + p->winPos = 0; + p->wrPos = 0; + } + */ + // (winPos < next) + } + + if (winPos > next) + return SZ_ERROR_FAIL; // it's unexpected case + /* + if (!outBuf_fromCaller && isCyclicMode && cycSize != 0) + then (winPos < cycSize) + else (winPos <= cycSize) + */ + if (!p->outBuf_fromCaller) + { + // that code is optional. We try to optimize write chunk sizes. + /* (next2) is expected next write position in the caller, + if the caller writes by kBlockSizeMax chunks. + */ + /* + const size_t next2 = (winPos + kBlockSizeMax) & (kBlockSizeMax - 1); + if (winPos < next2 && next2 < next) + next = next2; + */ + } + size = next - winPos; + } + + // note: ZstdDec_DecodeBlock() uses (winLimit = winPos + size) only for RLE and RAW blocks + res = ZstdDec_DecodeBlock(dec, p, size); + /* + after one block decoding: + if (!outBuf_fromCaller && isCyclicMode && cycSize != 0) + then (winPos < cycSize + max_block_size) + else (winPos <= cycSize) + */ + + if (!p->outBuf_fromCaller) + p->win = dec->decoder.win; + p->winPos = dec->decoder.winPos; + + // outProcessed = dec->decoder.winPos - winPos; + // p->outProcessed += outProcessed; + + if (res != SZ_OK) + return res; + + if (dec->frameState != ZSTD2_STATE_AFTER_HEADER) + { + if (p->outBuf_fromCaller) + return SZ_OK; + { + // !p->outBuf_fromCaller + /* + if (ZSTD_STATUS_FINISHED_FRAME), we request full flushing here because + 1) it's simpler to work with allocation and extracting of next frame, + 2) it's better to start writing to next new frame with aligned memory + for faster xxh 64-bit reads. + */ + size_t end = dec->decoder.winPos; // end pos for all data flushing + if (p->status != ZSTD_STATUS_FINISHED_FRAME) + { + // we will request flush here only for cases when wrap in cyclic buffer can be required in next call. + if (!dec->isCyclicMode) + return SZ_OK; + // isCyclicMode + { + const size_t delta = dec->decoder.cycSize; + if (end < delta) + return SZ_OK; // (winPos < cycSize). no need for flush + // cycSize <= winPos + // So we ask the caller to flush of (cycSize - wrPos) bytes, + // and then we will wrap cylicBuffer in next call + end = delta; + } + } + p->needWrite_Size = end - p->wrPos; + } + return SZ_OK; + } + + // ZSTD2_STATE_AFTER_HEADER + { + BoolInt useCyclic = False; + size_t cycSize; + + // p->status = ZSTD_STATUS_NOT_FINISHED; + if (dec->dictionaryId != 0) + { + /* actually we can try to decode some data, + because it's possible that some data doesn't use dictionary */ + // p->status = ZSTD_STATUS_NOT_SPECIFIED; + return SZ_ERROR_UNSUPPORTED; + } + + { + UInt64 winSize = dec->contentSize; + UInt64 winSize_Allocate = winSize; + const unsigned descriptor = dec->descriptor; + + if ((descriptor & DESCRIPTOR_FLAG_SINGLE) == 0) + { + const Byte wd = dec->windowDescriptor; + winSize = (UInt64)(8 + (wd & 7)) << ((wd >> 3) + 10 - 3); + if (!DESCRIPTOR_Is_ContentSize_Defined(descriptor) + || winSize_Allocate > winSize) + { + winSize_Allocate = winSize; + useCyclic = True; + } + } + /* + else + { + if (p->info.singleSegment_ContentSize_MAX < winSize) + p->info.singleSegment_ContentSize_MAX = winSize; + // p->info.num_SingleSegments++; + } + */ + if (p->info.windowSize_MAX < winSize) + p->info.windowSize_MAX = winSize; + if (p->info.windowSize_Allocate_MAX < winSize_Allocate) + p->info.windowSize_Allocate_MAX = winSize_Allocate; + /* + winSize_Allocate is MIN(content_size, window_size_from_descriptor). + Wven if (content_size < (window_size_from_descriptor)) + original-zstd still uses (window_size_from_descriptor) to check that decoding is allowed. + We try to follow original-zstd, and here we check (winSize) instead of (winSize_Allocate)) + */ + if ( + // winSize_Allocate // it's relaxed check + winSize // it's more strict check to be compatible with original-zstd + > ((UInt64)1 << MAX_WINDOW_SIZE_LOG)) + return SZ_ERROR_UNSUPPORTED; // SZ_ERROR_MEM + cycSize = (size_t)winSize_Allocate; + if (cycSize != winSize_Allocate) + return SZ_ERROR_MEM; + // cycSize <= winSize + /* later we will use (CZstdDec1::winSize) to check match offsets and check block sizes. + if (there is window descriptor) + { + We will check block size with (window_size_from_descriptor) instead of (winSize_Allocate). + Does original-zstd do it that way also? + } + Here we must reduce full real 64-bit (winSize) to size_t for (CZstdDec1::winSize). + Also we don't want too big values for (CZstdDec1::winSize). + our (CZstdDec1::winSize) will meet the condition: + (CZstdDec1::winSize < kBlockSizeMax || CZstdDec1::winSize <= cycSize). + */ + dec->decoder.winSize = (winSize < kBlockSizeMax) ? (size_t)winSize: cycSize; + // note: (CZstdDec1::winSize > cycSize) is possible, if (!useCyclic) + } + + RINOK(ZstdDec_AllocateMisc(dec)) + + if (p->outBuf_fromCaller) + dec->isCyclicMode = False; + else + { + size_t d = cycSize; + + if (dec->decoder.winPos != p->wrPos) + return SZ_ERROR_FAIL; + + dec->decoder.winPos = 0; + p->wrPos = 0; + p->winPos = dec->decoder.winPos; + + /* + const size_t needWrite = dec->decoder.winPos - p->wrPos; + if (!needWrite) + { + dec->decoder.winPos = 0; + p->wrPos = 0; + p->winPos = dec->decoder.winPos; + } + */ + /* if (!useCyclic) we allocate only cycSize = ContentSize. + But if we want to support the case where new frame starts with winPos != 0, + then we will wrap over zero, and we still need + to set (useCyclic) and allocate additional buffer spaces. + Now we don't allow new frame starting with (winPos != 0). + so (dec->decoder->winPos == 0) + can use (!useCyclic) with reduced buffer sizes. + */ + /* + if (dec->decoder->winPos != 0) + useCyclic = True; + */ + + if (useCyclic) + { + /* cyclyc buffer size must be at least (COPY_CHUNK_SIZE - 1) bytes + larger than window size, because CopyMatch() can write additional + (COPY_CHUNK_SIZE - 1) bytes and overwrite oldests data in cyclyc buffer. + But for performance reasons we align (cycSize) for (kBlockSizeMax). + also we must provide (cycSize >= max_decoded_data_after_cycSize), + because after data move wrapping over zero we must provide (winPos < cycSize). + */ + const size_t alignSize = kBlockSizeMax; + /* here we add (1 << 7) instead of (COPY_CHUNK_SIZE - 1), because + we want to get same (cycSize) for different COPY_CHUNK_SIZE values. */ + // cycSize += (COPY_CHUNK_SIZE - 1) + (alignSize - 1); // for debug : we can get smallest (cycSize) + cycSize += (1 << 7) + alignSize; + cycSize &= ~(size_t)(alignSize - 1); + // cycSize must be aligned for 32, because xxh requires 32-bytes blocks. + // cycSize += 12345; // for debug + // cycSize += 1 << 10; // for debug + // cycSize += 32; // for debug + // cycSize += kBlockSizeMax; // for debug + if (cycSize < d) + return SZ_ERROR_MEM; + /* + in cyclic buffer mode we allow to decode one additional block + that exceeds (cycSize). + So we must allocate additional (kBlockSizeMax) bytes after (cycSize). + if defined(Z7_STD_DEC_USE_AFTER_CYC_BUF) + { + we can read (COPY_CHUNK_SIZE - 1) bytes after (cycSize) + but we aready allocate additional kBlockSizeMax that + is larger than COPY_CHUNK_SIZE. + So we don't need additional space of COPY_CHUNK_SIZE after (cycSize). + } + */ + /* + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + d = cycSize + (1 << 7); // we must add at least (COPY_CHUNK_SIZE - 1) + #endif + */ + d = cycSize + kBlockSizeMax; + if (d < cycSize) + return SZ_ERROR_MEM; + } + + { + const size_t kMinWinAllocSize = 1 << 12; + if (d < kMinWinAllocSize) + d = kMinWinAllocSize; + } + + if (d > dec->winBufSize_Allocated) + { + /* + if (needWrite) + { + p->needWrite_Size = needWrite; + return SZ_OK; + // return SZ_ERROR_FAIL; + } + */ + + if (dec->winBufSize_Allocated != 0) + { + const size_t k_extra = (useCyclic || d >= (1u << 20)) ? + 2 * kBlockSizeMax : 0; + unsigned i = useCyclic ? 17 : 12; + for (; i < sizeof(size_t) * 8; i++) + { + const size_t d2 = ((size_t)1 << i) + k_extra; + if (d2 >= d) + { + d = d2; + break; + } + } + } + // RINOK(ZstdDec_AllocateWindow(dec, d)) + ZstdDec_FreeWindow(dec); + dec->win_Base = (Byte *)ISzAlloc_Alloc(dec->alloc_Big, d); + if (!dec->win_Base) + return SZ_ERROR_MEM; + dec->decoder.win = dec->win_Base; + dec->winBufSize_Allocated = d; + } + /* + else + { + // for non-cyclycMode we want flush data, and set winPos = 0 + if (needWrite) + { + if (!useCyclic || dec->decoder.winPos >= cycSize) + { + p->needWrite_Size = needWrite; + return SZ_OK; + // return SZ_ERROR_FAIL; + } + } + } + */ + + dec->decoder.cycSize = cycSize; + p->win = dec->decoder.win; + // p->cycSize = dec->decoder.cycSize; + dec->isCyclicMode = (Byte)useCyclic; + } // (!p->outBuf_fromCaller) end + + // p->winPos = dec->decoder.winPos; + dec->frameState = ZSTD2_STATE_BLOCK; + // continue; + } // ZSTD2_STATE_AFTER_HEADER end + } +} + + +void ZstdDec_GetResInfo(const CZstdDec *dec, + const CZstdDecState *p, + SRes res, + CZstdDecResInfo *stat) +{ + // ZstdDecInfo_CLEAR(stat); + stat->extraSize = 0; + stat->is_NonFinishedFrame = False; + if (dec->frameState != ZSTD2_STATE_FINISHED) + { + if (dec->frameState == ZSTD2_STATE_SIGNATURE) + { + stat->extraSize = (Byte)dec->tempSize; + if (ZstdDecInfo_GET_NUM_FRAMES(&p->info) == 0) + res = SZ_ERROR_NO_ARCHIVE; + } + else + { + stat->is_NonFinishedFrame = True; + if (res == SZ_OK && p->status == ZSTD_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + } + } + stat->decode_SRes = res; +} + + +size_t ZstdDec_ReadUnusedFromInBuf( + CZstdDecHandle dec, + size_t afterDecoding_tempPos, + void *data, size_t size) +{ + size_t processed = 0; + if (dec->frameState == ZSTD2_STATE_SIGNATURE) + { + Byte *dest = (Byte *)data; + const size_t tempSize = dec->tempSize; + while (afterDecoding_tempPos < tempSize) + { + if (size == 0) + break; + size--; + *dest++ = dec->temp[afterDecoding_tempPos++]; + processed++; + } + } + return processed; +} + + +void ZstdDecState_Clear(CZstdDecState *p) +{ + memset(p, 0 , sizeof(*p)); +} diff -Nru 7zip-22.01+dfsg/C/ZstdDec.h 7zip-22.01+really25.01+dfsg/C/ZstdDec.h --- 7zip-22.01+dfsg/C/ZstdDec.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/ZstdDec.h 2024-01-21 11:00:00.000000000 +0000 @@ -0,0 +1,173 @@ +/* ZstdDec.h -- Zstd Decoder interfaces +2024-01-21 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ZSTD_DEC_H +#define ZIP7_INC_ZSTD_DEC_H + +EXTERN_C_BEGIN + +typedef struct CZstdDec CZstdDec; +typedef CZstdDec * CZstdDecHandle; + +CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big); +void ZstdDec_Destroy(CZstdDecHandle p); + +typedef enum +{ + ZSTD_STATUS_NOT_SPECIFIED, /* use main error code instead */ + ZSTD_STATUS_FINISHED_FRAME, /* data frame or skip frame was finished */ + ZSTD_STATUS_NOT_FINISHED, /* just finished non-empty block or unfinished RAW/RLE block */ + ZSTD_STATUS_NEEDS_MORE_INPUT, /* the callee needs more input bytes. It has more priority over ZSTD_STATUS_NOT_FINISHED */ + ZSTD_STATUS_OUT_REACHED /* is not finihed frame and ((outProcessed > outSize) || (outProcessed == outSize && unfinished RAW/RLE block) */ +} enum_ZstdStatus_Dummy; + +#define ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(p) \ + ((p)->status & ZSTD_STATUS_FINISHED_FRAME) +/* + ((p)->status == ZSTD_STATUS_NEEDS_MORE_INPUT || \ + (p)->status == ZSTD_STATUS_FINISHED_FRAME) +*/ + +typedef Byte enum_ZstdStatus; + + +void ZstdDec_Init(CZstdDecHandle p); + +typedef struct +{ + UInt64 num_Blocks; + Byte descriptor_OR; + Byte descriptor_NOT_OR; + Byte are_ContentSize_Unknown; + Byte windowDescriptor_MAX; + + // Byte are_ContentSize_Known; + // Byte are_SingleSegments; + // Byte are_WindowDescriptors; + Byte checksum_Defined; + // Byte are_Checksums; + // Byte are_Non_Checksums; + + // Byte are_DictionaryId; + Byte are_DictionaryId_Different; + + // Byte reserved[3]; + + UInt32 checksum; // checksum of last data frame + /// UInt32 dictionaryId_Cur; + UInt32 dictionaryId; // if there are non-zero dictionary IDs, then it's first dictionaryId + + UInt64 num_DataFrames; + UInt64 num_SkipFrames; + UInt64 skipFrames_Size; + UInt64 contentSize_Total; + UInt64 contentSize_MAX; + // UInt64 num_Checksums; + // UInt64 num_Non_Checksums; // frames without checksum + // UInt64 num_WindowDescriptors; + // UInt64 num_SingleSegments; + // UInt64 num_Frames_with_ContentSize; + // UInt64 num_Frames_without_ContentSize; + UInt64 windowSize_MAX; + UInt64 windowSize_Allocate_MAX; + // UInt64 num_DictionaryIds; + // UInt64 num_Blocks_forType[4]; + // UInt64 num_BlockBytes_forType[4]; + // UInt64 num_SingleSegments; + // UInt64 singleSegment_ContentSize_MAX; +} CZstdDecInfo; + +#define ZstdDecInfo_CLEAR(p) { memset(p, 0, sizeof(*(p))); } + +#define ZstdDecInfo_GET_NUM_FRAMES(p) ((p)->num_DataFrames + (p)->num_SkipFrames) + + +typedef struct CZstdDecState +{ + enum_ZstdStatus status; // out + Byte disableHash; + // Byte mustBeFinished; + Byte outSize_Defined; + // Byte isAfterSizeMode; + // UInt64 inProcessed; + // SRes codeRes; + // Byte needWrite_IsStrong; + + const Byte *inBuf; + size_t inPos; // in/out + size_t inLim; + + const Byte *win; // out + size_t winPos; // out + size_t wrPos; // in/out + // size_t cycSize; // out : if (!outBuf_fromCaller) + size_t needWrite_Size; // out + + Byte *outBuf_fromCaller; + size_t outBufSize_fromCaller; + /* (outBufSize_fromCaller >= full_uncompressed_size_of_all_frames) is required + for success decoding. + If outBufSize_fromCaller < full_uncompressed_size_of_all_frames), + decoding can give error message, because we decode per block basis. + */ + + // size_t outStep; + UInt64 outSize; // total in all frames + UInt64 outProcessed; // out decoded in all frames (it can be >= outSize) + + CZstdDecInfo info; +} CZstdDecState; + +void ZstdDecState_Clear(CZstdDecState *p); + +/* +ZstdDec_Decode() +return: + SZ_OK - no error + SZ_ERROR_DATA - Data Error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - XXH hash Error + // SZ_ERROR_ARCHIVE - Headers error (not used now) +*/ +SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p); + +/* +ZstdDec_ReadUnusedFromInBuf(): +returns: the number of bytes that were read from InBuf +(*afterDecoding_tempPos) must be set to zero before first call of ZstdDec_ReadUnusedFromInBuf() +*/ +size_t ZstdDec_ReadUnusedFromInBuf( + CZstdDecHandle dec, + size_t afterDecoding_tempPos, // in/out + void *data, size_t size); + +typedef struct +{ + SRes decode_SRes; // error code of data decoding + Byte is_NonFinishedFrame; // there is unfinished decoding for data frame or skip frame + Byte extraSize; +} CZstdDecResInfo; + +/* +#define ZstdDecResInfo_CLEAR(p) \ +{ (p)->decode_SRes = 0; \ + (p)->is_NonFinishedFrame; \ + (p)->extraSize = 0; \ +} +// memset(p, 0, sizeof(*p)); +*/ + +/* +additional error codes for CZstdDecResInfo::decode_SRes: + SZ_ERROR_NO_ARCHIVE - is not zstd stream (no frames) + SZ_ERROR_INPUT_EOF - need more data in input stream +*/ +void ZstdDec_GetResInfo(const CZstdDec *dec, + const CZstdDecState *p, + SRes res, // it's result from ZstdDec_Decode() + CZstdDecResInfo *info); + +EXTERN_C_END + +#endif diff -Nru 7zip-22.01+dfsg/C/var_clang_arm64.mak 7zip-22.01+really25.01+dfsg/C/var_clang_arm64.mak --- 7zip-22.01+dfsg/C/var_clang_arm64.mak 2021-04-28 11:26:32.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/var_clang_arm64.mak 2024-02-28 10:00:00.000000000 +0000 @@ -6,6 +6,7 @@ CROSS_COMPILE= MY_ARCH= USE_ASM=1 +ASM_FLAGS=-Wno-unused-macros CC=$(CROSS_COMPILE)clang CXX=$(CROSS_COMPILE)clang++ USE_CLANG=1 diff -Nru 7zip-22.01+dfsg/C/warn_clang.mak 7zip-22.01+really25.01+dfsg/C/warn_clang.mak --- 7zip-22.01+dfsg/C/warn_clang.mak 2021-04-28 11:21:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/warn_clang.mak 2023-05-06 05:00:00.000000000 +0000 @@ -1,37 +1 @@ -CFLAGS_WARN_CLANG_3_8_UNIQ = \ - -Wno-reserved-id-macro \ - -Wno-old-style-cast \ - -Wno-c++11-long-long \ - -Wno-unused-macros \ - -CFLAGS_WARN_CLANG_3_8 = \ - $(CFLAGS_WARN_CLANG_3_8_UNIQ) \ - -Weverything \ - -Wno-extra-semi \ - -Wno-sign-conversion \ - -Wno-language-extension-token \ - -Wno-global-constructors \ - -Wno-non-virtual-dtor \ - -Wno-switch-enum \ - -Wno-covered-switch-default \ - -Wno-cast-qual \ - -Wno-padded \ - -Wno-exit-time-destructors \ - -Wno-weak-vtables \ - -CFLAGS_WARN_CLANG_12= $(CFLAGS_WARN_CLANG_3_8) \ - -Wno-extra-semi-stmt \ - -Wno-zero-as-null-pointer-constant \ - -Wno-deprecated-dynamic-exception-spec \ - -Wno-c++98-compat-pedantic \ - -Wno-atomic-implicit-seq-cst \ - -Wconversion \ - -Wno-sign-conversion \ - -CFLAGS_WARN_1 = \ - -Wno-deprecated-copy-dtor \ - - - - -CFLAGS_WARN = $(CFLAGS_WARN_CLANG_12) $(CFLAGS_WARN_1) +CFLAGS_WARN = -Weverything -Wfatal-errors diff -Nru 7zip-22.01+dfsg/C/warn_clang_mac.mak 7zip-22.01+really25.01+dfsg/C/warn_clang_mac.mak --- 7zip-22.01+dfsg/C/warn_clang_mac.mak 2021-04-28 11:21:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/C/warn_clang_mac.mak 2023-05-03 13:00:00.000000000 +0000 @@ -1,37 +1 @@ -CFLAGS_WARN_CLANG_3_8_UNIQ = \ - -Wno-reserved-id-macro \ - -Wno-old-style-cast \ - -Wno-c++11-long-long \ - -Wno-unused-macros \ - -CFLAGS_WARN_CLANG_3_8 = \ - $(CFLAGS_WARN_CLANG_3_8_UNIQ) \ - -Weverything \ - -Wno-extra-semi \ - -Wno-sign-conversion \ - -Wno-language-extension-token \ - -Wno-global-constructors \ - -Wno-non-virtual-dtor \ - -Wno-switch-enum \ - -Wno-covered-switch-default \ - -Wno-cast-qual \ - -Wno-padded \ - -Wno-exit-time-destructors \ - -Wno-weak-vtables \ - -CFLAGS_WARN_CLANG_12= $(CFLAGS_WARN_CLANG_3_8) \ - -Wno-extra-semi-stmt \ - -Wno-zero-as-null-pointer-constant \ - -Wno-deprecated-dynamic-exception-spec \ - -Wno-c++98-compat-pedantic \ - -Wno-atomic-implicit-seq-cst \ - -Wconversion \ - -Wno-sign-conversion \ - -CFLAGS_WARN_MAC = \ - -Wno-poison-system-directories \ - -Wno-c++11-long-long \ - -Wno-atomic-implicit-seq-cst \ - - -CFLAGS_WARN = $(CFLAGS_WARN_CLANG_12) $(CFLAGS_WARN_MAC) +CFLAGS_WARN = -Weverything -Wfatal-errors -Wno-poison-system-directories diff -Nru 7zip-22.01+dfsg/CPP/7zip/7zip.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip.mak --- 7zip-22.01+dfsg/CPP/7zip/7zip.mak 2014-06-23 15:56:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip.mak 2024-01-29 08:00:00.000000000 +0000 @@ -5,14 +5,14 @@ $(WIN_OBJS) \ $(WIN_CTRL_OBJS) \ $(7ZIP_COMMON_OBJS) \ - $(AR_OBJS) \ - $(AR_COMMON_OBJS) \ $(UI_COMMON_OBJS) \ $(AGENT_OBJS) \ $(CONSOLE_OBJS) \ $(EXPLORER_OBJS) \ $(FM_OBJS) \ $(GUI_OBJS) \ + $(AR_COMMON_OBJS) \ + $(AR_OBJS) \ $(7Z_OBJS) \ $(CAB_OBJS) \ $(CHM_OBJS) \ @@ -124,7 +124,7 @@ !IFDEF ZIP_OBJS $(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp - $(COMPL) + $(COMPL) $(ZIP_FLAGS) !ENDIF !IFDEF COMPRESS_OBJS @@ -149,7 +149,7 @@ !IFDEF CONSOLE_OBJS $(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp - $(COMPL) + $(COMPL) $(CONSOLE_VARIANT_FLAGS) !ENDIF !IFDEF EXPLORER_OBJS @@ -191,7 +191,7 @@ {../../UI/Agent}.cpp{$O}.obj:: $(COMPLB) {../../UI/Console}.cpp{$O}.obj:: - $(COMPLB) + $(COMPLB) $(CONSOLE_VARIANT_FLAGS) {../../UI/Explorer}.cpp{$O}.obj:: $(COMPLB) {../../UI/FileManager}.cpp{$O}.obj:: @@ -226,7 +226,7 @@ {../../Archive/Wim}.cpp{$O}.obj:: $(COMPLB) {../../Archive/Zip}.cpp{$O}.obj:: - $(COMPLB) + $(COMPLB) $(ZIP_FLAGS) {../../Compress}.cpp{$O}.obj:: $(COMPLB_O2) diff -Nru 7zip-22.01+dfsg/CPP/7zip/7zip_gcc.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip_gcc.mak --- 7zip-22.01+dfsg/CPP/7zip/7zip_gcc.mak 2022-07-15 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/7zip_gcc.mak 2025-07-02 05:00:00.000000000 +0000 @@ -12,23 +12,52 @@ MY_ASM = jwasm endif +ifndef RC +RC=windres.exe --target=pe-x86-64 +RC=windres.exe -F pe-i386 +RC=windres.exe +endif + PROGPATH = $(O)/$(PROG) PROGPATH_STATIC = $(O)/$(PROG)s ifneq ($(CC), xlc) -CFLAGS_WARN_WALL = -Wall -Werror -Wextra +CFLAGS_WARN_WALL = -Werror -Wall -Wextra endif # for object file +# -Wa,-aln=test.s +# -save-temps +FLAGS_BASE = -mbranch-protection=standard -march=armv8.5-a +FLAGS_BASE = -mbranch-protection=standard +FLAGS_BASE = +# FLAGS_BASE = -DZ7_NO_UNICODE + CFLAGS_BASE_LIST = -c + + +#DEBUG_BUILD=1 + +ifdef DEBUG_BUILD +CFLAGS_DEBUG = -g +else +CFLAGS_DEBUG = -DNDEBUG +ifneq ($(CC), $(CROSS_COMPILE)clang) +LFLAGS_STRIP = -s +endif +endif + # CFLAGS_BASE_LIST = -S CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ - -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ + $(CFLAGS_DEBUG) -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ -fPIC -# -D_7ZIP_AFFINITY_DISABLE +FLAGS_FLTO = -ffunction-sections +FLAGS_FLTO = -flto +FLAGS_FLTO = $(FLAGS_BASE) +# -DZ7_AFFINITY_DISABLE ifdef SystemDrive @@ -56,7 +85,7 @@ endif endif -LDFLAGS_STATIC = -DNDEBUG $(LDFLAGS_STATIC_2) +LDFLAGS_STATIC = $(CFLAGS_DEBUG) $(LDFLAGS_STATIC_2) $(LDFLAGS_STATIC_3) ifndef O ifdef IS_MINGW @@ -83,8 +112,8 @@ else LDFLAGS = $(LDFLAGS_STATIC) -# -s is not required for clang, do we need it for GGC ??? -# -s +# -z force-bti +# -s is not required for clang, do we need it for GCC ??? #-static -static-libgcc -static-libstdc++ @@ -113,10 +142,11 @@ DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll endif -LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32 $(LIB_HTMLHELP) +LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32 -lShell32 $(LIB_HTMLHELP) LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32 $(LIB2_GUI) -CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE +# v24.00: -DUNICODE and -D_UNICODE are defined in precompilation header files +# CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE # -Wno-delete-non-virtual-dtor @@ -126,11 +156,12 @@ MY_MKDIR=mkdir -p DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) -# CFLAGS_BASE := $(CFLAGS_BASE) -D_7ZIP_ST +# CFLAGS_BASE := $(CFLAGS_BASE) -DZ7_ST # CXXFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE # LOCAL_LIBS=-lpthread # LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl +LIB2 = -lpthread LIB2 = -lpthread -ldl @@ -138,7 +169,7 @@ -CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(CC_SHARED) -o $@ +CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CC_SHARED) -o $@ ifdef IS_MINGW @@ -170,7 +201,7 @@ ifdef USE_ASM -CONSOLE_ASM_FLAGS=-D_7ZIP_ASM +CONSOLE_ASM_FLAGS=-DZ7_7ZIP_ASM else CONSOLE_ASM_FLAGS= endif @@ -179,7 +210,7 @@ #-Wno-invalid-offsetof #-Wno-reorder -CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS) +CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CXXFLAGS_EXTRA) $(CC_SHARED) $(CXX_WARN_FLAGS) $(CXX_STD_FLAGS) $(CXX_INCLUDE_FLAGS) -o $@ STATIC_TARGET= ifdef COMPL_STATIC @@ -189,10 +220,43 @@ all: $(O) $(PROGPATH) $(STATIC_TARGET) +# we need $(O) as order-only-prerequisites: +$(OBJS): | $(O) + $(O): $(MY_MKDIR) $(O) -LFLAGS_ALL = -s $(MY_ARCH_2) $(LDFLAGS) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) +# LDFLAGS3= -flto +# LDFLAGS3= -Wl,--gc-sections +# -Wl,--print-gc-sections + +ifndef IS_MINGW + +# LFLAGS_NOEXECSTACK= + +ifdef Z7_USE_OS_UNAME_FOR_NOEXECSTACK +Z7_OS := $(shell uname) +show_os: + echo $(Z7_OS) + +# ifeq ($(CXX), $(CROSS_COMPILE)g++) +ifeq ($(Z7_OS), Linux) +LFLAGS_NOEXECSTACK ?= -z noexecstack +endif + +else +LFLAGS_NOEXECSTACK ?= $(shell echo 'int main(){return 0;}' | $(CC) $(MY_ARCH_2) -z noexecstack -o /dev/null -x c - 2>/dev/null && echo -z noexecstack || echo) +endif + +endif + + +LFLAGS_ALL = $(LFLAGS_STRIP) $(MY_ARCH_2) $(LDFLAGS) $(FLAGS_FLTO) $(LD_arch) $(LFLAGS_NOEXECSTACK) $(OBJS) $(MY_LIBS) $(LIB2) + +# -s : GCC : Remove all symbol table and relocation information from the executable. +# -s : CLANG : unsupported +# -s + $(PROGPATH): $(OBJS) $(CXX) -o $(PROGPATH) $(LFLAGS_ALL) @@ -206,7 +270,14 @@ ifndef NO_DEFAULT_RES $O/resource.o: resource.rc - windres.exe $(RFLAGS) resource.rc $O/resource.o + $(RC) $(RFLAGS) resource.rc $@ + +# windres.exe : in old version mingw: +# $(RFLAGS) resource.rc $O/resource.o +# windres.exe : in new version mingw: +# $(RC) $(RFLAGS) resource.rc -FO $@ + + endif $O/LzmaAlone.o: LzmaAlone.cpp @@ -231,6 +302,8 @@ $(CXX) $(CXXFLAGS) $< $O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp $(CXX) $(CXXFLAGS) $< +$O/Md5Reg.o: ../../../Common/Md5Reg.cpp + $(CXX) $(CXXFLAGS) $< $O/MyMap.o: ../../../Common/MyMap.cpp $(CXX) $(CXXFLAGS) $< $O/MyString.o: ../../../Common/MyString.cpp @@ -255,6 +328,12 @@ $(CXX) $(CXXFLAGS) $< $O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp $(CXX) $(CXXFLAGS) $< +$O/Sha3Reg.o: ../../../Common/Sha3Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Prepare.o: ../../../Common/Sha512Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Reg.o: ../../../Common/Sha512Reg.cpp + $(CXX) $(CXXFLAGS) $< $O/StdInStream.o: ../../../Common/StdInStream.cpp $(CXX) $(CXXFLAGS) $< $O/StdOutStream.o: ../../../Common/StdOutStream.cpp @@ -273,6 +352,8 @@ $(CXX) $(CXXFLAGS) $< $O/XzCrc64Reg.o: ../../../Common/XzCrc64Reg.cpp $(CXX) $(CXXFLAGS) $< +$O/Xxh64Reg.o: ../../../Common/Xxh64Reg.cpp + $(CXX) $(CXXFLAGS) $< @@ -383,6 +464,8 @@ $(CXX) $(CXXFLAGS) $< $O/MethodProps.o: ../../Common/MethodProps.cpp $(CXX) $(CXXFLAGS) $< +$O/MultiOutStream.o: ../../Common/MultiOutStream.cpp + $(CXX) $(CXXFLAGS) $< $O/OffsetStream.o: ../../Common/OffsetStream.cpp $(CXX) $(CXXFLAGS) $< $O/OutBuffer.o: ../../Common/OutBuffer.cpp @@ -457,6 +540,8 @@ $(CXX) $(CXXFLAGS) $< $O/LpHandler.o: ../../Archive/LpHandler.cpp $(CXX) $(CXXFLAGS) $< +$O/LvmHandler.o: ../../Archive/LvmHandler.cpp + $(CXX) $(CXXFLAGS) $< $O/LzhHandler.o: ../../Archive/LzhHandler.cpp $(CXX) $(CXXFLAGS) $< $O/LzmaHandler.o: ../../Archive/LzmaHandler.cpp @@ -503,6 +588,8 @@ $(CXX) $(CXXFLAGS) $< $O/ZHandler.o: ../../Archive/ZHandler.cpp $(CXX) $(CXXFLAGS) $< +$O/ZstdHandler.o: ../../Archive/ZstdHandler.cpp + $(CXX) $(CXXFLAGS) $< $O/7zCompressionMode.o: ../../Archive/7z/7zCompressionMode.cpp @@ -609,7 +696,7 @@ $O/ZipAddCommon.o: ../../Archive/Zip/ZipAddCommon.cpp $(CXX) $(CXXFLAGS) $< $O/ZipHandler.o: ../../Archive/Zip/ZipHandler.cpp - $(CXX) $(CXXFLAGS) $< + $(CXX) $(CXXFLAGS) $(ZIP_FLAGS) $< $O/ZipHandlerOut.o: ../../Archive/Zip/ZipHandlerOut.cpp $(CXX) $(CXXFLAGS) $< $O/ZipIn.o: ../../Archive/Zip/ZipIn.cpp @@ -730,6 +817,10 @@ $(CXX) $(CXXFLAGS) $< $O/ZlibEncoder.o: ../../Compress/ZlibEncoder.cpp $(CXX) $(CXXFLAGS) $< +$O/ZstdDecoder.o: ../../Compress/ZstdDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZstdRegister.o: ../../Compress/ZstdRegister.cpp + $(CXX) $(CXXFLAGS) $< $O/7zAes.o: ../../Crypto/7zAes.cpp @@ -920,6 +1011,8 @@ $(CXX) $(CXXFLAGS) $< $O/BrowseDialog.o: ../../UI/FileManager/BrowseDialog.cpp $(CXX) $(CXXFLAGS) $< +$O/BrowseDialog2.o: ../../UI/FileManager/BrowseDialog2.cpp + $(CXX) $(CXXFLAGS) $< $O/ClassDefs.o: ../../UI/FileManager/ClassDefs.cpp $(CXX) $(CXXFLAGS) $< $O/ComboDialog.o: ../../UI/FileManager/ComboDialog.cpp @@ -960,6 +1053,8 @@ $(CXX) $(CXXFLAGS) $< $O/ListViewDialog.o: ../../UI/FileManager/ListViewDialog.cpp $(CXX) $(CXXFLAGS) $< +$O/MemDialog.o: ../../UI/FileManager/MemDialog.cpp + $(CXX) $(CXXFLAGS) $< $O/MenuPage.o: ../../UI/FileManager/MenuPage.cpp $(CXX) $(CXXFLAGS) $< $O/MessagesDialog.o: ../../UI/FileManager/MessagesDialog.cpp @@ -1120,6 +1215,8 @@ $(CC) $(CFLAGS) $< $O/LzmaLib.o: ../../../../C/LzmaLib.c $(CC) $(CFLAGS) $< +$O/Md5.o: ../../../../C/Md5.c + $(CC) $(CFLAGS) $< $O/MtCoder.o: ../../../../C/MtCoder.c $(CC) $(CFLAGS) $< $O/MtDec.o: ../../../../C/MtDec.c @@ -1142,12 +1239,29 @@ $(CC) $(CFLAGS) $< $O/Sha256.o: ../../../../C/Sha256.c $(CC) $(CFLAGS) $< -$O/Sort.o: ../../../../C/Sort.c +$O/Sha3.o: ../../../../C/Sha3.c + $(CC) $(CFLAGS) $< +$O/Sha512.o: ../../../../C/Sha512.c + $(CC) $(CFLAGS) $< +$O/Sha512Opt.o: ../../../../C/Sha512Opt.c + $(CC) $(CFLAGS) $< +$O/SwapBytes.o: ../../../../C/SwapBytes.c + $(CC) $(CFLAGS) $< +$O/Xxh64.o: ../../../../C/Xxh64.c $(CC) $(CFLAGS) $< $O/Xz.o: ../../../../C/Xz.c $(CC) $(CFLAGS) $< $O/XzCrc64.o: ../../../../C/XzCrc64.c $(CC) $(CFLAGS) $< +$O/XzDec.o: ../../../../C/XzDec.c + $(CC) $(CFLAGS) $< +$O/XzEnc.o: ../../../../C/XzEnc.c + $(CC) $(CFLAGS) $< +$O/XzIn.o: ../../../../C/XzIn.c + $(CC) $(CFLAGS) $< +$O/ZstdDec.o: ../../../../C/ZstdDec.c + $(CC) $(CFLAGS) $< + ifdef USE_ASM ifdef IS_X64 @@ -1169,6 +1283,8 @@ $(MY_ASM) $(AFLAGS) $< $O/Sha256Opt.o: ../../../../Asm/x86/Sha256Opt.asm $(MY_ASM) $(AFLAGS) $< +$O/Sort.o: ../../../../Asm/x86/Sort.asm + $(MY_ASM) $(AFLAGS) $< ifndef USE_JWASM USE_X86_ASM_AES=1 @@ -1183,6 +1299,8 @@ $(CC) $(CFLAGS) $< $O/Sha256Opt.o: ../../../../C/Sha256Opt.c $(CC) $(CFLAGS) $< +$O/Sort.o: ../../../../C/Sort.c + $(CC) $(CFLAGS) $< endif @@ -1212,11 +1330,11 @@ ifdef IS_ARM64 $O/LzmaDecOpt.o: ../../../../Asm/arm64/LzmaDecOpt.S ../../../../Asm/arm64/7zAsm.S - $(CC) $(CFLAGS) $< + $(CC) $(CFLAGS) $(ASM_FLAGS) $< endif $O/LzmaDec.o: ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) -D_LZMA_DEC_OPT $< + $(CC) $(CFLAGS) -DZ7_LZMA_DEC_OPT $< else @@ -1227,13 +1345,6 @@ -$O/XzDec.o: ../../../../C/XzDec.c - $(CC) $(CFLAGS) $< -$O/XzEnc.o: ../../../../C/XzEnc.c - $(CC) $(CFLAGS) $< -$O/XzIn.o: ../../../../C/XzIn.c - $(CC) $(CFLAGS) $< - $O/7zMain.o: ../../../../C/Util/7z/7zMain.c $(CC) $(CFLAGS) $< diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7z.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7z.dsp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7z.dsp 2015-10-18 10:00:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7z.dsp 2023-04-04 20:00:00.000000000 +0000 @@ -43,7 +43,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -53,7 +53,7 @@ # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\Formats\7z.dll" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "7z - Win32 Debug" @@ -70,7 +70,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -80,7 +80,7 @@ # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\Formats\7z.dll" /pdbtype:sept !ENDIF @@ -101,7 +101,11 @@ # End Source File # Begin Source File -SOURCE=..\DllExports.cpp +SOURCE=..\..\Compress\CodecExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\DllExports2.cpp # End Source File # Begin Source File @@ -514,14 +518,6 @@ # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Windows\DLL.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\DLL.h -# End Source File -# Begin Source File - SOURCE=..\..\..\Windows\FileDir.cpp # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zCompressionMode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zCompressionMode.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zCompressionMode.h 2021-08-27 09:21:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zCompressionMode.h 2024-12-14 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zCompressionMode.h -#ifndef __7Z_COMPRESSION_MODE_H -#define __7Z_COMPRESSION_MODE_H +#ifndef ZIP7_INC_7Z_COMPRESSION_MODE_H +#define ZIP7_INC_7Z_COMPRESSION_MODE_H #include "../../Common/MethodId.h" #include "../../Common/MethodProps.h" @@ -52,33 +52,38 @@ bool DefaultMethod_was_Inserted; bool Filter_was_Inserted; + bool PasswordIsDefined; + bool MemoryUsageLimit_WasSet; - #ifndef _7ZIP_ST - UInt32 NumThreads; + #ifndef Z7_ST bool NumThreads_WasForced; bool MultiThreadMixer; + UInt32 NumThreads; + UInt32 NumThreadGroups; #endif - UInt64 MemoryUsageLimit; - bool MemoryUsageLimit_WasSet; - - bool PasswordIsDefined; UString Password; // _Wipe - + UInt64 MemoryUsageLimit; + bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } CCompressionMethodMode(): DefaultMethod_was_Inserted(false) , Filter_was_Inserted(false) - #ifndef _7ZIP_ST - , NumThreads(1) + , PasswordIsDefined(false) + , MemoryUsageLimit_WasSet(false) + #ifndef Z7_ST , NumThreads_WasForced(false) , MultiThreadMixer(true) + , NumThreads(1) + , NumThreadGroups(0) #endif , MemoryUsageLimit((UInt64)1 << 30) - , MemoryUsageLimit_WasSet(false) - , PasswordIsDefined(false) {} +#ifdef Z7_CPP_IS_SUPPORTED_default + CCompressionMethodMode(const CCompressionMethodMode &) = default; + CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default; +#endif ~CCompressionMethodMode() { Password.Wipe_and_Empty(); } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zDecode.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zDecode.cpp 2021-03-07 16:25:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.cpp 2024-02-17 09:00:00.000000000 +0000 @@ -5,25 +5,23 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" #include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" #include "7zDecode.h" namespace NArchive { namespace N7z { -class CDecProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CDecProgress + , ICompressProgressInfo +) CMyComPtr _progress; public: CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize) +Z7_COM7F_IMF(CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)) { return _progress->SetRatioInfo(NULL, outSize); } @@ -110,20 +108,23 @@ } CDecoder::CDecoder(bool useMixerMT): - _bindInfoPrev_Defined(false), - _useMixerMT(useMixerMT) -{} + _bindInfoPrev_Defined(false) +{ + #if defined(USE_MIXER_ST) && defined(USE_MIXER_MT) + _useMixerMT = useMixerMT; + #else + UNUSED_VAR(useMixerMT) + #endif +} -struct CLockedInStream: - public IUnknown, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_0( + CLockedInStream +) +public: CMyComPtr Stream; UInt64 Pos; - MY_UNKNOWN_IMP - #ifdef USE_MIXER_MT NWindows::NSynchronization::CCriticalSection CriticalSection; #endif @@ -132,10 +133,10 @@ #ifdef USE_MIXER_MT -class CLockedSequentialInStreamMT: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamMT + , ISequentialInStream +) CLockedInStream *_glob; UInt64 _pos; CMyComPtr _globRef; @@ -146,24 +147,20 @@ _glob = lockedInStream; _pos = startPos; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)) { NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); if (_pos != _glob->Pos) { - RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_glob->Stream, _pos)) _glob->Pos = _pos; } UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); _pos += realProcessedSize; _glob->Pos = _pos; if (processedSize) @@ -176,10 +173,10 @@ #ifdef USE_MIXER_ST -class CLockedSequentialInStreamST: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamST + , ISequentialInStream +) CLockedInStream *_glob; UInt64 _pos; CMyComPtr _globRef; @@ -190,22 +187,18 @@ _glob = lockedInStream; _pos = startPos; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (_pos != _glob->Pos) { - RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_glob->Stream, _pos)) _glob->Pos = _pos; } UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); _pos += realProcessedSize; _glob->Pos = _pos; if (processedSize) @@ -234,9 +227,9 @@ , bool &dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL - #if !defined(_7ZIP_ST) + #if !defined(Z7_ST) , bool mtMode, UInt32 numThreads, UInt64 memUsage #endif ) @@ -268,7 +261,7 @@ We don't need to init isEncrypted and passwordIsDefined We must upgrade them only - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO isEncrypted = false; passwordIsDefined = false; #endif @@ -300,13 +293,13 @@ #endif } - RINOK(_mixer->SetBindInfo(bindInfo)); + RINOK(_mixer->SetBindInfo(bindInfo)) FOR_VECTOR(i, folderInfo.Coders) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; - #ifndef _SFX + #ifndef Z7_SFX // we don't support RAR codecs here if ((coderInfo.MethodID >> 8) == 0x403) return E_NOTIMPL; @@ -315,7 +308,7 @@ CCreatedCoder cod; RINOK(CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS - coderInfo.MethodID, false, cod)); + coderInfo.MethodID, false, cod)) if (coderInfo.IsSimpleCoder()) { @@ -333,13 +326,13 @@ // now there is no codec that uses another external codec /* - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CMyComPtr setCompressCodecsInfo; decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); } #endif */ @@ -349,14 +342,14 @@ _bindInfoPrev_Defined = true; } - RINOK(_mixer->ReInit2()); + RINOK(_mixer->ReInit2()) UInt32 packStreamIndex = 0; UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; unsigned i; - #if !defined(_7ZIP_ST) + #if !defined(Z7_ST) bool mt_wasUsed = false; #endif @@ -365,59 +358,81 @@ const CCoderInfo &coderInfo = folderInfo.Coders[i]; IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); - #if !defined(_7ZIP_ST) + // now there is no codec that uses another external codec + /* + #ifdef Z7_EXTERNAL_CODECS + { + Z7_DECL_CMyComPtr_QI_FROM(ISetCompressCodecsInfo, + setCompressCodecsInfo, decoder) + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) + } + } + #endif + */ + + #if !defined(Z7_ST) if (!mt_wasUsed) { if (mtMode) { - CMyComPtr setCoderMt; - decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetCoderMt, + setCoderMt, decoder) if (setCoderMt) { mt_wasUsed = true; - RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + RINOK(setCoderMt->SetNumberOfThreads(numThreads)) } } // if (memUsage != 0) { - CMyComPtr setMemLimit; - decoder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit); + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetMemLimit, + setMemLimit, decoder) if (setMemLimit) { mt_wasUsed = true; - RINOK(setMemLimit->SetMemLimit(memUsage)); + RINOK(setMemLimit->SetMemLimit(memUsage)) } } } #endif { - CMyComPtr setDecoderProperties; - decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetDecoderProperties2, + setDecoderProperties, decoder) + const CByteBuffer &props = coderInfo.Props; + const UInt32 size32 = (UInt32)props.Size(); + if (props.Size() != size32) + return E_NOTIMPL; if (setDecoderProperties) { - const CByteBuffer &props = coderInfo.Props; - const UInt32 size32 = (UInt32)props.Size(); - if (props.Size() != size32) - return E_NOTIMPL; HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32); if (res == E_INVALIDARG) res = E_NOTIMPL; - RINOK(res); + RINOK(res) + } + else if (size32 != 0) + { + // v23: we fail, if decoder doesn't support properties + return E_NOTIMPL; } } - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO { - CMyComPtr cryptoSetPassword; - decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword); + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoSetPassword, + cryptoSetPassword, decoder) if (cryptoSetPassword) { isEncrypted = true; if (!getTextPassword) return E_NOTIMPL; CMyComBSTR_Wipe passwordBSTR; - RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); + RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)) passwordIsDefined = true; password.Wipe_and_Empty(); size_t len = 0; @@ -427,25 +442,27 @@ len = password.Len(); } CByteBuffer_Wipe buffer(len * 2); + const LPCOLESTR psw = passwordBSTR; for (size_t k = 0; k < len; k++) { - wchar_t c = passwordBSTR[k]; + const wchar_t c = psw[k]; ((Byte *)buffer)[k * 2] = (Byte)c; ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())) } } #endif bool finishMode = false; { - CMyComPtr setFinishMode; - decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetFinishMode, + setFinishMode, decoder) if (setFinishMode) { finishMode = fullUnpack; - RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode))); + RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode))) } } @@ -485,8 +502,7 @@ CObjectVector< CMyComPtr > inStreams; - CLockedInStream *lockedInStreamSpec = new CLockedInStream; - CMyComPtr lockedInStream = lockedInStreamSpec; + CMyComPtr2_Create lockedInStream; #ifdef USE_MIXER_MT #ifdef USE_MIXER_ST @@ -497,9 +513,9 @@ if (folderInfo.PackStreams.Size() > 1) { // lockedInStream.Pos = (UInt64)(Int64)-1; - // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos)); - RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStreamSpec->Pos)); - lockedInStreamSpec->Stream = inStream; + // RINOK(InStream_GetPos(inStream, lockedInStream.Pos)) + RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStream->Pos)) + lockedInStream->Stream = inStream; #ifdef USE_MIXER_MT #ifdef USE_MIXER_ST @@ -523,7 +539,7 @@ if (folderInfo.PackStreams.Size() == 1) { - RINOK(inStream->Seek((Int64)packPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, packPos)) packStream = inStream; } else @@ -535,7 +551,7 @@ { CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; packStream = lockedStreamImpSpec; - lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); + lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); } #ifdef USE_MIXER_ST else @@ -545,7 +561,7 @@ #ifdef USE_MIXER_ST CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST; packStream = lockedStreamImpSpec; - lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); + lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); #endif } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zDecode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zDecode.h 2017-09-16 12:23:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zDecode.h 2023-03-04 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zDecode.h -#ifndef __7Z_DECODE_H -#define __7Z_DECODE_H +#ifndef ZIP7_INC_7Z_DECODE_H +#define ZIP7_INC_7Z_DECODE_H #include "../Common/CoderMixer2.h" @@ -24,10 +24,13 @@ class CDecoder { bool _bindInfoPrev_Defined; + #ifdef USE_MIXER_ST + #ifdef USE_MIXER_MT + bool _useMixerMT; + #endif + #endif CBindInfoEx _bindInfoPrev; - bool _useMixerMT; - #ifdef USE_MIXER_ST NCoderMixer2::CMixerST *_mixerST; #endif @@ -57,9 +60,9 @@ , ISequentialInStream **inStreamMainRes , bool &dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL - #if !defined(_7ZIP_ST) + #if !defined(Z7_ST) , bool mtMode, UInt32 numThreads, UInt64 memUsage #endif ); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zEncode.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zEncode.cpp 2021-08-02 10:33:10.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.cpp 2023-12-20 09:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../Common/ComTry.h" + #include "../../Common/CreateCoder.h" #include "../../Common/FilterCoder.h" #include "../../Common/LimitedStreams.h" @@ -19,11 +21,11 @@ { unsigned numIn = _bindInfo.Coders.Size(); - _SrcIn_to_DestOut.ClearAndSetSize(numIn); - _DestOut_to_SrcIn.ClearAndSetSize(numIn); + SrcIn_to_DestOut.ClearAndSetSize(numIn); + DestOut_to_SrcIn.ClearAndSetSize(numIn); unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams(); - _SrcOut_to_DestIn.ClearAndSetSize(numOut); + SrcOut_to_DestIn.ClearAndSetSize(numOut); // _DestIn_to_SrcOut.ClearAndSetSize(numOut); UInt32 destIn = 0; @@ -38,15 +40,15 @@ numIn--; numOut -= coder.NumStreams; - _SrcIn_to_DestOut[numIn] = destOut; - _DestOut_to_SrcIn[destOut] = numIn; + SrcIn_to_DestOut[numIn] = destOut; + DestOut_to_SrcIn[destOut] = numIn; destOut++; for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++) { UInt32 index = numOut + j; - _SrcOut_to_DestIn[index] = destIn; + SrcOut_to_DestIn[index] = destIn; // _DestIn_to_SrcOut[destIn] = index; } } @@ -62,8 +64,8 @@ { CBond &fb = folder.Bonds[i]; const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i]; - fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex]; - fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex]; + fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex]; + fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex]; } folder.Coders.SetSize(_bindInfo.Coders.Size()); @@ -81,15 +83,16 @@ folder.PackStreams.SetSize(_bindInfo.PackStreams.Size()); for (i = 0; i < _bindInfo.PackStreams.Size(); i++) - folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; + folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; } static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) { - CMyComPtr setCoderProperties; - coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderProperties, + setCoderProperties, coder) if (setCoderProperties) return props.SetCoderProps(setCoderProperties, dataSizeReduce); return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; @@ -103,11 +106,11 @@ OutSize = 0; } -STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { UInt64 outSize2; { - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); #endif outSize2 = OutSize; @@ -146,7 +149,7 @@ #endif } - RINOK(_mixer->SetBindInfo(_bindInfo)); + RINOK(_mixer->SetBindInfo(_bindInfo)) FOR_VECTOR (m, _options.Methods) { @@ -158,23 +161,27 @@ { RINOK(CreateCoder_Index( EXTERNAL_CODECS_LOC_VARS - (unsigned)methodFull.CodecIndex, true, cod)); + (unsigned)methodFull.CodecIndex, true, cod)) } else { RINOK(CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS - methodFull.Id, true, cod)); + methodFull.Id, true, cod)) } - if (cod.NumStreams != methodFull.NumStreams) - return E_FAIL; if (!cod.Coder && !cod.Coder2) + { + return E_NOTIMPL; // unsupported method, if encoder + // return E_FAIL; + } + + if (cod.NumStreams != methodFull.NumStreams) return E_FAIL; CMyComPtr encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (methodFull.Set_NumThreads) { CMyComPtr setCoderMt; @@ -184,12 +191,12 @@ RINOK(setCoderMt->SetNumberOfThreads( /* _options.NumThreads */ methodFull.NumThreads - )); + )) } } #endif - RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)); + RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)) /* CMyComPtr resetSalt; @@ -202,13 +209,13 @@ // now there is no codec that uses another external codec /* - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CMyComPtr setCompressCodecsInfo; encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); } #endif */ @@ -226,7 +233,7 @@ ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)) } _mixer->AddCoder(cod); @@ -236,116 +243,112 @@ -class CSequentialOutTempBufferImp2: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; +Z7_CLASS_IMP_COM_1( + CSequentialOutTempBufferImp2 + , ISequentialOutStream +) public: - CMtEncMultiProgress *_mtProgresSpec; + CInOutTempBuffer TempBuffer; + CMtEncMultiProgress *_mtProgressSpec; - CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {} - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {} }; -STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed) +Z7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)) { - HRESULT res = _buf->Write_HRESULT(data, size); - if (res != S_OK) - { - if (processed) - *processed = 0; - return res; - } + COM_TRY_BEGIN + if (processed) + *processed = 0; + RINOK(TempBuffer.Write_HRESULT(data, size)) if (processed) *processed = size; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); return S_OK; + COM_TRY_END } -class CSequentialOutMtNotify: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CSequentialOutMtNotify + , ISequentialOutStream +) public: CMyComPtr _stream; - CMtEncMultiProgress *_mtProgresSpec; + CMtEncMultiProgress *_mtProgressSpec; - CSequentialOutMtNotify(): _mtProgresSpec(NULL) {} - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + CSequentialOutMtNotify(): _mtProgressSpec(NULL) {} }; -STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed) +Z7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)) { UInt32 realProcessed = 0; HRESULT res = _stream->Write(data, size, &realProcessed); if (processed) *processed = realProcessed; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); return res; } +static HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props) +{ + Z7_DECL_CMyComPtr_QI_FROM( + ICompressWriteCoderProperties, + writeCoderProperties, coder) + if (writeCoderProperties) + { + CMyComPtr2_Create outStreamSpec; + outStreamSpec->Init(); + RINOK(writeCoderProperties->WriteCoderProperties(outStreamSpec)) + outStreamSpec->CopyToBuffer(props); + } + else + props.Free(); + return S_OK; +} -HRESULT CEncoder::Encode( +HRESULT CEncoder::Encode1( DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, // const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, CFolder &folderItem, - CRecordVector &coderUnpackSizes, - UInt64 &unpackSize, + // CRecordVector &coderUnpackSizes, + // UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector &packSizes, ICompressProgressInfo *compressProgress) { - RINOK(EncoderConstr()); + RINOK(EncoderConstr()) if (!_mixerRef) { - RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)); + RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)) } - RINOK(_mixer->ReInit2()); + RINOK(_mixer->ReInit2()) - CMtEncMultiProgress *mtProgressSpec = NULL; - CMyComPtr mtProgress; + CMyComPtr2 mtProgress; + CMyComPtr2 mtOutStreamNotify; - CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL; - CMyComPtr mtOutStreamNotify; - - CObjectVector inOutTempBuffers; - CObjectVector tempBufferSpecs; + CRecordVector tempBufferSpecs; CObjectVector > tempBuffers; - unsigned numMethods = _bindInfo.Coders.Size(); - unsigned i; for (i = 1; i < _bindInfo.PackStreams.Size(); i++) { - CInOutTempBuffer &iotb = inOutTempBuffers.AddNew(); - iotb.Create(); - iotb.InitWriting(); - } - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - { - CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2; + CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2(); CMyComPtr tempBuffer = tempBufferSpec; - tempBufferSpec->Init(&inOutTempBuffers[i - 1]); - tempBuffers.Add(tempBuffer); tempBufferSpecs.Add(tempBufferSpec); + tempBuffers.Add(tempBuffer); } + const unsigned numMethods = _bindInfo.Coders.Size(); + for (i = 0; i < numMethods; i++) _mixer->SetCoderInfo(i, NULL, NULL, false); @@ -360,15 +363,19 @@ */ + /* CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; + */ CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; CMyComPtr outStreamSizeCount; - inStreamSizeCountSpec->Init(inStream); + // inStreamSizeCountSpec->Init(inStream); + + // ISequentialInStream *inStreamPointer = inStreamSizeCount; + ISequentialInStream *inStreamPointer = inStream; - ISequentialInStream *inStreamPointer = inStreamSizeCount; CRecordVector outStreamPointers; SetFolder(folderItem); @@ -376,49 +383,66 @@ for (i = 0; i < numMethods; i++) { IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + /* + { + CEncoder *sfEncoder = NULL; + Z7_DECL_CMyComPtr_QI_FROM( + IGetSfEncoderInternal, + sf, coder) + if (sf) + { + RINOK(sf->GetSfEncoder(&sfEncoder)); + if (!sfEncoder) + return E_FAIL; - CMyComPtr resetInitVector; - coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); - if (resetInitVector) + } + } + */ + /* + #ifdef Z7_EXTERNAL_CODECS { - resetInitVector->ResetInitVector(); + Z7_DECL_CMyComPtr_QI_FROM( + ISetCompressCodecsInfo, + setCompressCodecsInfo, coder) + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) + } } - + #endif + */ { - CMyComPtr optProps; - coder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps); - if (optProps) + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoResetInitVector, + resetInitVector, coder) + if (resetInitVector) { - PROPID propID = NCoderPropID::kExpectedDataSize; - NWindows::NCOM::CPropVariant prop = (UInt64)unpackSize; - RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)); + RINOK(resetInitVector->ResetInitVector()) } } - - CMyComPtr writeCoderProperties; - coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); - - CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props; - - if (writeCoderProperties) { - CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; - CMyComPtr dynOutStream(outStreamSpec); - outStreamSpec->Init(); - RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream)); - outStreamSpec->CopyToBuffer(props); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderPropertiesOpt, + optProps, coder) + if (optProps) + { + const PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; + RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + } } - else - props.Free(); + // we must write properties from coder after ResetInitVector() + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) } _mixer->SelectMainCoder(false); - UInt32 mainCoder = _mixer->MainCoderIndex; + const UInt32 mainCoder = _mixer->MainCoderIndex; bool useMtProgress = false; if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder)) { - #ifdef _7ZIP_ST + #ifdef Z7_ST if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder)) #endif useMtProgress = true; @@ -426,18 +450,16 @@ if (useMtProgress) { - mtProgressSpec = new CMtEncMultiProgress; - mtProgress = mtProgressSpec; - mtProgressSpec->Init(compressProgress); + mtProgress.SetFromCls(new CMtEncMultiProgress); + mtProgress->Init(compressProgress); - mtOutStreamNotifySpec = new CSequentialOutMtNotify; - mtOutStreamNotify = mtOutStreamNotifySpec; - mtOutStreamNotifySpec->_stream = outStream; - mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec; + mtOutStreamNotify.SetFromCls(new CSequentialOutMtNotify); + mtOutStreamNotify->_stream = outStream; + mtOutStreamNotify->_mtProgressSpec = mtProgress.ClsPtr(); - FOR_VECTOR(t, tempBufferSpecs) + FOR_VECTOR (t, tempBufferSpecs) { - tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec; + tempBufferSpecs[t]->_mtProgressSpec = mtProgress.ClsPtr(); } } @@ -446,7 +468,8 @@ { outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; outStreamSizeCount = outStreamSizeCountSpec; - outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream); + outStreamSizeCountSpec->SetStream(mtOutStreamNotify.IsDefined() ? + mtOutStreamNotify.Interface() : outStream); outStreamSizeCountSpec->Init(); outStreamPointers.Add(outStreamSizeCount); } @@ -458,36 +481,51 @@ RINOK(_mixer->Code( &inStreamPointer, - &outStreamPointers.Front(), - mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error)); + outStreamPointers.ConstData(), + mtProgress.IsDefined() ? mtProgress.Interface() : + compressProgress, dataAfterEnd_Error)) if (_bindInfo.PackStreams.Size() != 0) packSizes.Add(outStreamSizeCountSpec->GetSize()); for (i = 1; i < _bindInfo.PackStreams.Size(); i++) { - CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; - RINOK(inOutTempBuffer.WriteToStream(outStream)); - packSizes.Add(inOutTempBuffer.GetDataSize()); + CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer; + RINOK(iotb.WriteToStream(outStream)) + packSizes.Add(iotb.GetDataSize()); } - unpackSize = 0; - - for (i = 0; i < _bindInfo.Coders.Size(); i++) + /* Code() in some future codec can change properties. + v23: so we fill properties again after Code() */ + for (i = 0; i < numMethods; i++) + { + IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) + } + + return S_OK; +} + + +void CEncoder::Encode_Post( + UInt64 unpackSize, + CRecordVector &coderUnpackSizes) +{ + // unpackSize = 0; + for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++) { - int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]); + const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]); UInt64 streamSize; if (bond < 0) { - streamSize = inStreamSizeCountSpec->GetSize(); - unpackSize = streamSize; + // streamSize = inStreamSizeCountSpec->GetSize(); + // unpackSize = streamSize; + streamSize = unpackSize; } else streamSize = _mixer->GetBondStreamSize((unsigned)bond); coderUnpackSizes.Add(streamSize); } - - return S_OK; } @@ -610,15 +648,15 @@ if (_bindInfo.Coders[ci].NumStreams == 0) break; - UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; - int bond = _bindInfo.FindBond_for_PackStream(outIndex); + const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; + const int bond = _bindInfo.FindBond_for_PackStream(outIndex); if (bond >= 0) { ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex; continue; } - int si = _bindInfo.FindStream_in_PackStreams(outIndex); + const int si = _bindInfo.FindStream_in_PackStreams(outIndex); if (si >= 0) _bindInfo.PackStreams.MoveToFront((unsigned)si); break; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zEncode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zEncode.h 2021-01-26 19:01:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zEncode.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zEncode.h -#ifndef __7Z_ENCODE_H -#define __7Z_ENCODE_H +#ifndef ZIP7_INC_7Z_ENCODE_H +#define ZIP7_INC_7Z_ENCODE_H #include "7zCompressionMode.h" @@ -12,12 +12,12 @@ namespace NArchive { namespace N7z { -class CMtEncMultiProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CMtEncMultiProgress, + ICompressProgressInfo +) CMyComPtr _progress; - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSection CriticalSection; #endif @@ -30,18 +30,15 @@ void AddOutSize(UInt64 addOutSize) { - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); #endif OutSize += addOutSize; } - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -class CEncoder MY_UNCOPYABLE + +class CEncoder Z7_final MY_UNCOPYABLE { #ifdef USE_MIXER_ST NCoderMixer2::CMixerST *_mixerST; @@ -57,10 +54,10 @@ NCoderMixer2::CBindInfo _bindInfo; CRecordVector _decompressionMethods; - CRecordVector _SrcIn_to_DestOut; - CRecordVector _SrcOut_to_DestIn; - // CRecordVector _DestIn_to_SrcOut; - CRecordVector _DestOut_to_SrcIn; + CRecordVector SrcIn_to_DestOut; + CRecordVector SrcOut_to_DestIn; + // CRecordVector DestIn_to_SrcOut; + CRecordVector DestOut_to_SrcIn; void InitBindConv(); void SetFolder(CFolder &folder); @@ -74,17 +71,23 @@ CEncoder(const CCompressionMethodMode &options); ~CEncoder(); HRESULT EncoderConstr(); - HRESULT Encode( + HRESULT Encode1( DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, // const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, CFolder &folderItem, - CRecordVector &coderUnpackSizes, - UInt64 &unpackSize, + // CRecordVector &coderUnpackSizes, + // UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector &packSizes, ICompressProgressInfo *compressProgress); + + void Encode_Post( + UInt64 unpackSize, + CRecordVector &coderUnpackSizes); + }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zExtract.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zExtract.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zExtract.cpp 2021-08-08 17:53:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zExtract.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -16,10 +16,11 @@ namespace NArchive { namespace N7z { -class CFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CFolderOutStream + , ISequentialOutStream + /* , ICompressGetSubStreamSize */ +) CMyComPtr _stream; public: bool TestMode; @@ -31,6 +32,7 @@ UInt64 _rem; const UInt32 *_indexes; + // unsigned _startIndex; unsigned _numFiles; unsigned _fileIndex; @@ -40,8 +42,6 @@ HRESULT ProcessEmptyFiles(); public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - const CDbEx *_db; CMyComPtr ExtractCallback; @@ -52,8 +52,6 @@ CheckCrc(true) {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles); HRESULT FlushCorrupted(Int32 callbackOperationResult); @@ -63,6 +61,7 @@ HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles) { + // _startIndex = startIndex; _fileIndex = startIndex; _indexes = indexes; _numFiles = numFiles; @@ -76,11 +75,10 @@ HRESULT CFolderOutStream::OpenFile(bool isCorrupted) { const CFileItem &fi = _db->Files[_fileIndex]; - UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); - Int32 askMode = (_fileIndex == nextFileIndex) ? - (TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : + const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); + Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract : NExtract::NAskMode::kSkip; if (isCorrupted @@ -90,7 +88,7 @@ askMode = NExtract::NAskMode::kTest; CMyComPtr realOutStream; - RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)); + RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)) _stream = realOutStream; _crc = CRC_INIT_VAL; @@ -136,13 +134,13 @@ { while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0) { - RINOK(OpenFile()); - RINOK(CloseFile()); + RINOK(OpenFile()) + RINOK(CloseFile()) } return S_OK; } -STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -170,16 +168,16 @@ _rem -= cur; if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) break; continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_numFiles == 0) { // we support partial extracting @@ -192,7 +190,7 @@ // return S_FALSE; return k_My_HRESULT_WritingWasCut; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; @@ -204,18 +202,32 @@ { if (_fileIsOpen) { - RINOK(CloseFile_and_SetResult(callbackOperationResult)); + RINOK(CloseFile_and_SetResult(callbackOperationResult)) } else { - RINOK(OpenFile(true)); + RINOK(OpenFile(true)) } } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) +/* +Z7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + *value = 0; + // const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex; + const unsigned numFiles_Original = _numFiles; + if (subStream >= numFiles_Original) + return S_FALSE; // E_FAIL; + *value = _db->Files[_startIndex + (unsigned)subStream].Size; + return S_OK; +} +*/ + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)) { // for GCC // CFolderOutStream *folderOutStream = new CFolderOutStream; @@ -229,7 +241,7 @@ // numItems = (UInt32)(Int32)-1; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _db.Files.Size(); @@ -244,8 +256,8 @@ for (i = 0; i < numItems; i++) { - UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + const UInt32 fileIndex = allFilesMode ? i : indices[i]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; if (folderIndex == kNumNoIndex) continue; if (folderIndex != prevFolder || fileIndex < nextFile) @@ -257,10 +269,9 @@ } } - RINOK(extractCallback->SetTotal(importantTotalUnpacked)); + RINOK(extractCallback->SetTotal(importantTotalUnpacked)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); CDecoder decoder( @@ -268,8 +279,8 @@ false #elif !defined(USE_MIXER_ST) true - #elif !defined(__7Z_SET_PROPERTIES) - #ifdef _7ZIP_ST + #elif !defined(Z7_7Z_SET_PROPERTIES) + #ifdef Z7_ST false #else true @@ -281,8 +292,8 @@ UInt64 curPacked, curUnpacked; - CMyComPtr callbackMessage; - extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); + CMyComPtr callbackMessage; + extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); CFolderOutStream *folderOutStream = new CFolderOutStream; CMyComPtr outStream(folderOutStream); @@ -294,7 +305,7 @@ for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked) { - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) if (i >= numItems) break; @@ -303,7 +314,7 @@ curPacked = 0; UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; UInt32 numSolidFiles = 1; @@ -316,7 +327,7 @@ for (k = i + 1; k < numItems; k++) { - UInt32 fileIndex2 = allFilesMode ? k : indices[k]; + const UInt32 fileIndex2 = allFilesMode ? k : indices[k]; if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex || fileIndex2 < nextFile) break; @@ -330,20 +341,26 @@ } { - HRESULT result = folderOutStream->Init(fileIndex, + const HRESULT result = folderOutStream->Init(fileIndex, allFilesMode ? NULL : indices + i, numSolidFiles); i += numSolidFiles; - RINOK(result); + RINOK(result) } - // to test solid block with zero unpacked size we disable that code if (folderOutStream->WasWritingFinished()) + { + // for debug: to test zero size stream unpacking + // if (folderIndex == kNumNoIndex) // enable this check for debug continue; + } + + if (folderIndex == kNumNoIndex) + return E_FAIL; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr getTextPassword; if (extractCallback) extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); @@ -351,16 +368,15 @@ try { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; UString_Wipe password; #endif - bool dataAfterEnd_Error = false; - HRESULT result = decoder.Decode( + const HRESULT result = decoder.Decode( EXTERNAL_CODECS_VARS _inStream, _db.ArcInfo.DataStartPosition, @@ -368,19 +384,19 @@ &curUnpacked, outStream, - progress, + lps, NULL // *inStreamMainRes , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) , true, _numThreads, _memUsage_Decompress #endif ); if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error) { - bool wasFinished = folderOutStream->WasWritingFinished(); + const bool wasFinished = folderOutStream->WasWritingFinished(); int resOp = NExtract::NOperationResult::kDataError; @@ -392,14 +408,14 @@ resOp = NExtract::NOperationResult::kDataAfterEnd; } - RINOK(folderOutStream->FlushCorrupted(resOp)); + RINOK(folderOutStream->FlushCorrupted(resOp)) if (wasFinished) { // we don't show error, if it's after required files if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage) { - RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)); + RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)) } } continue; @@ -408,12 +424,12 @@ if (result != S_OK) return result; - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) continue; } catch(...) { - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) // continue; // return E_FAIL; throw; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.cpp 2022-05-04 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.cpp 2023-05-11 16:00:00.000000000 +0000 @@ -15,32 +15,38 @@ _updateCallback = updateCallback; _indexes = indexes; _numFiles = numFiles; + + _totalSize_for_Coder = 0; + ClearFileInfo(); Processed.ClearAndReserve(numFiles); - CRCs.ClearAndReserve(numFiles); Sizes.ClearAndReserve(numFiles); - - if (Need_CTime) CTimes.ClearAndReserve(numFiles); - if (Need_ATime) ATimes.ClearAndReserve(numFiles); - if (Need_MTime) MTimes.ClearAndReserve(numFiles); - if (Need_Attrib) Attribs.ClearAndReserve(numFiles); + CRCs.ClearAndReserve(numFiles); TimesDefined.ClearAndReserve(numFiles); - + MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0); + CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0); + ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0); + Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0); + + // FolderCrc = CRC_INIT_VAL; _stream.Release(); } -HRESULT CFolderInStream::OpenStream() +void CFolderInStream::ClearFileInfo() { _pos = 0; _crc = CRC_INIT_VAL; _size_Defined = false; _times_Defined = false; _size = 0; + FILETIME_Clear(_mTime); FILETIME_Clear(_cTime); FILETIME_Clear(_aTime); - FILETIME_Clear(_mTime); _attrib = 0; +} +HRESULT CFolderInStream::OpenStream() +{ while (Processed.Size() < _numFiles) { CMyComPtr stream; @@ -83,7 +89,7 @@ } } - RINOK(AddFileInfo(result == S_OK)); + RINOK(AddFileInfo(result == S_OK)) } return S_OK; } @@ -117,13 +123,13 @@ // const UInt32 index = _indexes[Processed.Size()]; Processed.AddInReserved(isProcessed); Sizes.AddInReserved(_pos); - const UInt32 crc = CRC_GET_DIGEST(_crc); - CRCs.AddInReserved(crc); + CRCs.AddInReserved(CRC_GET_DIGEST(_crc)); + if (Need_Attrib) Attribs.AddInReserved(_attrib); TimesDefined.AddInReserved(_times_Defined); + if (Need_MTime) AddFt(MTimes, _mTime); if (Need_CTime) AddFt(CTimes, _cTime); if (Need_ATime) AddFt(ATimes, _aTime); - if (Need_MTime) AddFt(MTimes, _mTime); - if (Need_Attrib) Attribs.AddInReserved(_attrib); + ClearFileInfo(); /* if (isProcessed && _reportArcProp) RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc)) @@ -131,7 +137,7 @@ return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); } -STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -139,38 +145,65 @@ { if (_stream) { + /* + if (_pos == 0) + { + const UInt32 align = (UInt32)1 << AlignLog; + const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1); + if (offset != 0) + { + UInt32 cur = align - offset; + if (cur > size) + cur = size; + memset(data, 0, cur); + data = (Byte *)data + cur; + size -= cur; + // _pos += cur; // for debug + _totalSize_for_Coder += cur; + if (processedSize) + *processedSize += cur; + continue; + } + } + */ UInt32 cur = size; const UInt32 kMax = (UInt32)1 << 20; if (cur > kMax) cur = kMax; - RINOK(_stream->Read(data, cur, &cur)); + RINOK(_stream->Read(data, cur, &cur)) if (cur != 0) { + // if (Need_Crc) _crc = CrcUpdate(_crc, data, cur); + /* + if (FolderCrc) + FolderCrc = CrcUpdate(FolderCrc, data, cur); + */ _pos += cur; + _totalSize_for_Coder += cur; if (processedSize) - *processedSize = cur; + *processedSize = cur; // use +=cur, if continue is possible in loop return S_OK; } _stream.Release(); - RINOK(AddFileInfo(true)); + RINOK(AddFileInfo(true)) } if (Processed.Size() >= _numFiles) break; - RINOK(OpenStream()); + RINOK(OpenStream()) } return S_OK; } -STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { *value = 0; if (subStream > Sizes.Size()) return S_FALSE; // E_FAIL; - unsigned index = (unsigned)subStream; + const unsigned index = (unsigned)subStream; if (index < Sizes.Size()) { *value = Sizes[index]; @@ -187,4 +220,45 @@ return S_OK; } + +/* +HRESULT CFolderInStream::CloseCrcStream() +{ + if (!_crcStream) + return S_OK; + if (!_crcStream_Spec->WasFinished()) + return E_FAIL; + _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it + const UInt64 size = _crcStream_Spec->GetSize(); + _pos = size; + _totalSize_for_Coder += size; + _crcStream.Release(); + // _crcStream->ReleaseStream(); + _stream.Release(); + return AddFileInfo(true); +} + +Z7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream) +{ + RINOK(CloseCrcStream()) + *stream = NULL; + *streamIndexRes = Processed.Size(); + if (Processed.Size() >= _numFiles) + return S_OK; + RINOK(OpenStream()); + if (!_stream) + return S_OK; + if (!_crcStream) + { + _crcStream_Spec = new CSequentialInStreamWithCRC; + _crcStream = _crcStream_Spec; + } + _crcStream_Spec->Init(); + _crcStream_Spec->SetStream(_stream); + *stream = _crcStream; + _crcStream->AddRef(); + return S_OK; +} +*/ + }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.h 2022-05-04 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zFolderInStream.h 2023-05-11 16:00:00.000000000 +0000 @@ -1,12 +1,13 @@ // 7zFolderInStream.h -#ifndef __7Z_FOLDER_IN_STREAM_H -#define __7Z_FOLDER_IN_STREAM_H +#ifndef ZIP7_INC_7Z_FOLDER_IN_STREAM_H +#define ZIP7_INC_7Z_FOLDER_IN_STREAM_H #include "../../../../C/7zCrc.h" #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" +// #include "../Common/InStreamWithCRC.h" #include "../../ICoder.h" #include "../IArchive.h" @@ -14,20 +15,26 @@ namespace NArchive { namespace N7z { -class CFolderInStream: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + CFolderInStream + , ISequentialInStream + , ICompressGetSubStreamSize +) + /* + Z7_COM7F_IMP(GetNextStream(UInt64 *streamIndex)) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + */ + CMyComPtr _stream; + UInt64 _totalSize_for_Coder; UInt64 _pos; UInt32 _crc; bool _size_Defined; bool _times_Defined; UInt64 _size; + FILETIME _mTime; FILETIME _cTime; FILETIME _aTime; - FILETIME _mTime; UInt32 _attrib; unsigned _numFiles; @@ -35,34 +42,40 @@ CMyComPtr _updateCallback; + void ClearFileInfo(); HRESULT OpenStream(); HRESULT AddFileInfo(bool isProcessed); - + // HRESULT CloseCrcStream(); public: + bool Need_MTime; + bool Need_CTime; + bool Need_ATime; + bool Need_Attrib; + // bool Need_Crc; + // bool Need_FolderCrc; + // unsigned AlignLog; + CRecordVector Processed; - CRecordVector CRCs; CRecordVector Sizes; - CRecordVector CTimes; - CRecordVector ATimes; - CRecordVector MTimes; + CRecordVector CRCs; CRecordVector Attribs; CRecordVector TimesDefined; + CRecordVector MTimes; + CRecordVector CTimes; + CRecordVector ATimes; + // UInt32 FolderCrc; - bool Need_CTime; - bool Need_ATime; - bool Need_MTime; - bool Need_Attrib; - + // UInt32 GetFolderCrc() const { return CRC_GET_DIGEST(FolderCrc); } + // CSequentialInStreamWithCRC *_crcStream_Spec; + // CMyComPtr _crcStream; // CMyComPtr _reportArcProp; - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); - void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles); bool WasFinished() const { return Processed.Size() == _numFiles; } + UInt64 Get_TotalSize_for_Coder() const { return _totalSize_for_Coder; } + /* UInt64 GetFullSize() const { UInt64 size = 0; @@ -70,12 +83,16 @@ size += Sizes[i]; return size; } + */ CFolderInStream(): + Need_MTime(false), Need_CTime(false), Need_ATime(false), - Need_MTime(false), Need_Attrib(false) + // , Need_Crc(true) + // , Need_FolderCrc(false) + // , AlignLog(0) {} }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandler.cpp 2022-03-30 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -7,7 +7,7 @@ #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" -#ifndef __7Z_SET_PROPERTIES +#ifndef Z7_7Z_SET_PROPERTIES #include "../../../Windows/System.h" #endif @@ -16,8 +16,8 @@ #include "7zHandler.h" #include "7zProperties.h" -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY #include "../Common/ParseProperties.h" #endif #endif @@ -30,40 +30,40 @@ CHandler::CHandler() { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO _isEncrypted = false; _passwordIsDefined = false; #endif - #ifdef EXTRACT_ONLY + #ifdef Z7_EXTRACT_ONLY _crcSize = 4; - #ifdef __7Z_SET_PROPERTIES + #ifdef Z7_7Z_SET_PROPERTIES _useMultiThreadMixer = true; #endif #endif } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _db.Files.Size(); return S_OK; } -#ifdef _SFX +#ifdef Z7_SFX IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)) { return E_NOTIMPL; } @@ -110,8 +110,7 @@ static char *GetStringForSizeValue(char *s, UInt32 val) { - unsigned i; - for (i = 0; i <= 31; i++) + for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == val) { if (i >= 10) @@ -190,15 +189,15 @@ #endif -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { - #ifndef _SFX + #ifndef Z7_SFX COM_TRY_BEGIN #endif NCOM::CPropVariant prop; switch (propID) { - #ifndef _SFX + #ifndef Z7_SFX case kpidMethod: { AString s; @@ -220,6 +219,12 @@ GetStringForSizeValue(temp, pm.LzmaDic); s += temp; } + /* + else if (id == k_ZSTD) + { + s += "ZSTD"; + } + */ else AddMethodName(s, id); } @@ -267,9 +272,10 @@ prop = true; break; } + default: break; } return prop.Detach(value); - #ifndef _SFX + #ifndef Z7_SFX COM_TRY_END #endif } @@ -285,17 +291,17 @@ { if (folderIndex == kNumNoIndex) return false; - size_t startPos = _db.FoCodersDataOffset[folderIndex]; - const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData.ConstData() + startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; CInByte2 inByte; inByte.Init(p, size); CNum numCoders = inByte.ReadNum(); for (; numCoders != 0; numCoders--) { - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); + const Byte mainByte = inByte.ReadByte(); + const unsigned idSize = (mainByte & 0xF); const Byte *longID = inByte.GetPtr(); UInt64 id64 = 0; for (unsigned j = 0; j < idSize; j++) @@ -309,20 +315,20 @@ return false; } -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = kpidNtSecure; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) { /* const CFileItem &file = _db.Files[index]; @@ -334,7 +340,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -345,11 +351,11 @@ { if (_db.NameOffsets && _db.NamesBuf) { - size_t offset = _db.NameOffsets[index]; - size_t size = (_db.NameOffsets[index + 1] - offset) * 2; + const size_t offset = _db.NameOffsets[index]; + const size_t size = (_db.NameOffsets[index + 1] - offset) * 2; if (size < ((UInt32)1 << 31)) { - *data = (const void *)(_db.NamesBuf + offset * 2); + *data = (const void *)(_db.NamesBuf.ConstData() + offset * 2); *dataSize = (UInt32)size; *propType = NPropDataType::kUtf16z; } @@ -376,7 +382,7 @@ return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const { @@ -389,9 +395,9 @@ unsigned pos = kTempSize; temp[--pos] = 0; - size_t startPos = _db.FoCodersDataOffset[folderIndex]; - const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData.ConstData() + startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; CInByte2 inByte; inByte.Init(p, size); @@ -403,10 +409,10 @@ { if (pos < 32) // max size of property break; - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); - const Byte *longID = inByte.GetPtr(); + const Byte mainByte = inByte.ReadByte(); UInt64 id64 = 0; + const unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); for (unsigned j = 0; j < idSize; j++) id64 = ((id64 << 8) | longID[j]); inByte.SkipDataNoCheck(idSize); @@ -432,21 +438,21 @@ if (id64 <= (UInt32)0xFFFFFFFF) { - UInt32 id = (UInt32)id64; + const UInt32 id = (UInt32)id64; if (id == k_LZMA) { name = "LZMA"; if (propsSize == 5) { - UInt32 dicSize = GetUi32((const Byte *)props + 1); + const UInt32 dicSize = GetUi32((const Byte *)props + 1); char *dest = GetStringForSizeValue(s, dicSize); UInt32 d = props[0]; if (d != 0x5D) { - UInt32 lc = d % 9; + const UInt32 lc = d % 9; d /= 9; - UInt32 pb = d / 5; - UInt32 lp = d % 5; + const UInt32 pb = d / 5; + const UInt32 lp = d % 5; if (lc != 3) dest = AddProp32(dest, "lc", lc); if (lp != 0) dest = AddProp32(dest, "lp", lp); if (pb != 2) dest = AddProp32(dest, "pb", pb); @@ -477,6 +483,16 @@ if (propsSize == 1) ConvertUInt32ToString((UInt32)props[0] + 1, s); } + else if (id == k_ARM64 || id == k_RISCV) + { + name = id == k_ARM64 ? "ARM64" : "RISCV"; + if (propsSize == 4) + ConvertUInt32ToString(GetUi32(props), s); + /* + else if (propsSize != 0) + MyStringCopy(s, "unsupported"); + */ + } else if (id == k_BCJ2) name = "BCJ2"; else if (id == k_BCJ) name = "BCJ"; else if (id == k_AES) @@ -484,8 +500,8 @@ name = "7zAES"; if (propsSize >= 1) { - Byte firstByte = props[0]; - UInt32 numCyclesPower = firstByte & 0x3F; + const Byte firstByte = props[0]; + const UInt32 numCyclesPower = firstByte & 0x3F; ConvertUInt32ToString(numCyclesPower, s); } } @@ -493,8 +509,8 @@ if (name) { - unsigned nameLen = MyStringLen(name); - unsigned propsLen = MyStringLen(s); + const unsigned nameLen = MyStringLen(name); + const unsigned propsLen = MyStringLen(s); unsigned totalLen = nameLen + propsLen; if (propsLen != 0) totalLen++; @@ -523,7 +539,7 @@ pos -= ConvertMethodIdToString_Back(temp + pos, id64); else { - unsigned len = methodName.Len(); + const unsigned len = methodName.Len(); if (len + 5 > pos) break; pos -= len; @@ -547,9 +563,9 @@ #endif -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { - RINOK(PropVariant_Clear(value)); + RINOK(PropVariant_Clear(value)) // COM_TRY_BEGIN // NCOM::CPropVariant prop; @@ -576,7 +592,7 @@ { // prop = ref2.PackSize; { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) @@ -617,24 +633,24 @@ case kpidPath: return _db.GetPath_Prop(index, value); - #ifndef _SFX + #ifndef Z7_SFX case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); case kpidBlock: { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) PropVarEm_Set_UInt32(value, (UInt32)folderIndex); } break; - /* + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES case kpidPackedSize0: case kpidPackedSize1: case kpidPackedSize2: case kpidPackedSize3: case kpidPackedSize4: { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && @@ -648,22 +664,23 @@ PropVarEm_Set_UInt64(value, 0); } break; - */ + #endif #endif + default: break; } // return prop.Detach(value); return S_OK; // COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN Close(); - #ifndef _SFX + #ifndef Z7_SFX _fileInfoPopIDs.Clear(); #endif @@ -671,31 +688,31 @@ { CMyComPtr openArchiveCallbackTemp = openArchiveCallback; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr getTextPassword; if (openArchiveCallback) openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); #endif CInArchive archive( - #ifdef __7Z_SET_PROPERTIES + #ifdef Z7_7Z_SET_PROPERTIES _useMultiThreadMixer #else true #endif ); _db.IsArc = false; - RINOK(archive.Open(stream, maxCheckStartPosition)); + RINOK(archive.Open(stream, maxCheckStartPosition)) _db.IsArc = true; HRESULT result = archive.ReadDatabase( EXTERNAL_CODECS_VARS _db - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , getTextPassword, _isEncrypted, _passwordIsDefined, _password #endif ); - RINOK(result); + RINOK(result) _inStream = stream; } @@ -708,19 +725,19 @@ return E_OUTOFMEMORY; } // _inStream = stream; - #ifndef _SFX + #ifndef Z7_SFX FillPopIDs(); #endif return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { COM_TRY_BEGIN _inStream.Release(); _db.Clear(); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO _isEncrypted = false; _passwordIsDefined = false; _password.Wipe_and_Empty(); @@ -729,10 +746,10 @@ COM_TRY_END } -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN @@ -747,19 +764,19 @@ return E_INVALIDARG; const PROPVARIANT &value = values[i]; UInt32 number; - unsigned index = ParseStringToUInt32(name, number); + const unsigned index = ParseStringToUInt32(name, number); if (index == 0) { if (name.IsEqualTo("mtf")) { - RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)); + RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)) continue; } { HRESULT hres; if (SetCommonProperty(name, value, hres)) { - RINOK(hres); + RINOK(hres) continue; } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandler.h 2022-05-10 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandler.h 2024-05-12 11:00:00.000000000 +0000 @@ -1,26 +1,26 @@ // 7z/Handler.h -#ifndef __7Z_HANDLER_H -#define __7Z_HANDLER_H +#ifndef ZIP7_7Z_HANDLER_H +#define ZIP7_7Z_HANDLER_H #include "../../ICoder.h" #include "../IArchive.h" #include "../../Common/CreateCoder.h" -#ifndef __7Z_SET_PROPERTIES +#ifndef Z7_7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY - #if !defined(_7ZIP_ST) && !defined(_SFX) - #define __7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY + #if !defined(Z7_ST) && !defined(Z7_SFX) + #define Z7_7Z_SET_PROPERTIES #endif #else - #define __7Z_SET_PROPERTIES + #define Z7_7Z_SET_PROPERTIES #endif #endif -// #ifdef __7Z_SET_PROPERTIES +// #ifdef Z7_7Z_SET_PROPERTIES #include "../Common/HandlerOut.h" // #endif @@ -31,7 +31,7 @@ namespace N7z { -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY class COutHandler: public CMultiMethodProps { @@ -54,11 +54,13 @@ CBoolPair Write_Attrib; bool _useMultiThreadMixer; - bool _removeSfxBlock; - // bool _volumeMode; + UInt32 _decoderCompatibilityVersion; + CUIntVector _enabledFilters; + CUIntVector _disabledFilters; + void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } void InitSolid() @@ -79,73 +81,63 @@ #endif -class CHandler: +class CHandler Z7_final: public IInArchive, public IArchiveGetRawProps, - #ifdef __7Z_SET_PROPERTIES + #ifdef Z7_7Z_SET_PROPERTIES public ISetProperties, #endif - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public IOutArchive, #endif - PUBLIC_ISetCompressCodecsInfo + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC public CMyUnknownImp, - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public COutHandler #else public CCommonMethodProps #endif { -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - #ifdef __7Z_SET_PROPERTIES - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - #endif - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - - #ifdef __7Z_SET_PROPERTIES - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif - - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) - #endif - + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_COM_QI_ENTRY(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_IFACE_COM7_IMP(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif DECL_ISetCompressCodecsInfo - CHandler(); - ~CHandler() - { - Close(); - } - private: CMyComPtr _inStream; NArchive::N7z::CDbEx _db; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool _isEncrypted; bool _passwordIsDefined; UString _password; // _Wipe - #endif + #endif - #ifdef EXTRACT_ONLY + #ifdef Z7_EXTRACT_ONLY - #ifdef __7Z_SET_PROPERTIES + #ifdef Z7_7Z_SET_PROPERTIES bool _useMultiThreadMixer; #endif @@ -162,7 +154,7 @@ #endif bool IsFolderEncrypted(CNum folderIndex) const; - #ifndef _SFX + #ifndef Z7_SFX CRecordVector _fileInfoPopIDs; void FillPopIDs(); @@ -172,6 +164,13 @@ #endif DECL_EXTERNAL_CODECS_VARS + +public: + CHandler(); + ~CHandler() + { + Close(); + } }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandlerOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandlerOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHandlerOut.cpp 2022-05-09 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHandlerOut.cpp 2025-07-03 07:00:00.000000000 +0000 @@ -13,13 +13,16 @@ #include "7zOut.h" #include "7zUpdate.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY using namespace NWindows; namespace NArchive { namespace N7z { +static const UInt32 k_decoderCompatibilityVersion = 2301; +// 7-Zip version 2301 supports ARM64 filter + #define k_LZMA_Name "LZMA" #define kDefaultMethodName "LZMA2" #define k_Copy_Name "Copy" @@ -35,7 +38,7 @@ 1 << 20; #endif -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) { *type = NFileTimeType::kWindows; return S_OK; @@ -43,10 +46,11 @@ HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) { + bool isFilter; dest.CodecIndex = FindMethod_Index( EXTERNAL_CODECS_VARS m.MethodName, true, - dest.Id, dest.NumStreams); + dest.Id, dest.NumStreams, isFilter); if (dest.CodecIndex < 0) return E_INVALIDARG; (CProps &)dest = (CProps &)m; @@ -107,8 +111,8 @@ } } - const UInt64 kSolidBytes_Min = (1 << 24); - const UInt64 kSolidBytes_Max = ((UInt64)1 << 32); + const UInt64 kSolidBytes_Min = 1 << 24; + const UInt64 kSolidBytes_Max = (UInt64)1 << 32; // for non-LZMA2 methods bool needSolid = false; @@ -118,22 +122,24 @@ SetGlobalLevelTo(oneMethodInfo); - #ifndef _7ZIP_ST +#ifndef Z7_ST const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0); if (!numThreads_WasSpecifiedInMethod) { // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads); } - #endif + if (methodMode.NumThreadGroups > 1) + CMultiMethodProps::Set_Method_NumThreadGroups_IfNotFinded(oneMethodInfo, methodMode.NumThreadGroups); +#endif CMethodFull &methodFull = methodMode.Methods.AddNew(); - RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)); + RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)) - #ifndef _7ZIP_ST +#ifndef Z7_ST methodFull.Set_NumThreads = true; methodFull.NumThreads = methodMode.NumThreads; - #endif +#endif if (methodFull.Id != k_Copy) needSolid = true; @@ -147,15 +153,55 @@ case k_Deflate: dicSize = (UInt32)1 << 15; break; case k_Deflate64: dicSize = (UInt32)1 << 16; break; case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break; + // case k_ZSTD: dicSize = 1 << 23; break; default: continue; } UInt64 numSolidBytes; - + + /* + if (methodFull.Id == k_ZSTD) + { + // continue; + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps)); + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + UInt64 cs = (UInt64)(zstdProps.jobSize); + UInt32 winSize = (UInt32)(1 << zstdProps.windowLog); + if (cs < winSize) + cs = winSize; + numSolidBytes = cs << 6; + const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34); + if (numSolidBytes > kSolidBytes_Zstd_Max) + numSolidBytes = kSolidBytes_Zstd_Max; + + methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder + + #ifndef Z7_ST + if (!numThreads_WasSpecifiedInMethod + && !methodMode.NumThreads_WasForced + && methodMode.MemoryUsageLimit_WasSet + ) + { + const UInt32 numThreads_Original = methodMode.NumThreads; + const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps, + methodMode.MemoryUsageLimit, + numThreads_Original); + if (numThreads_Original != numThreads_New) + { + CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New); + } + } + #endif + } + else + */ if (methodFull.Id == k_LZMA2) { // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code - /* lzma2 code use dictionary upo to fake 4 GiB to calculate ChunkSize. + /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize. So we do same */ UInt64 cs = (UInt64)dicSize << 2; const UInt32 kMinSize = (UInt32)1 << 20; @@ -167,25 +213,24 @@ cs &= ~(UInt64)(kMinSize - 1); // we want to use at least 64 chunks (threads) per one solid block. - // here we don't use chunckSize property + // here we don't use chunkSize property numSolidBytes = cs << 6; - // here we get real chunckSize + // here we get real chunkSize cs = oneMethodInfo.Get_Xz_BlockSize(); if (dicSize > cs) - dicSize = cs; + dicSize = cs; - const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34); + const UInt64 kSolidBytes_Lzma2_Max = (UInt64)1 << 34; if (numSolidBytes > kSolidBytes_Lzma2_Max) - numSolidBytes = kSolidBytes_Lzma2_Max; + numSolidBytes = kSolidBytes_Lzma2_Max; methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder - #ifndef _7ZIP_ST + #ifndef Z7_ST if (!numThreads_WasSpecifiedInMethod && !methodMode.NumThreads_WasForced - && methodMode.MemoryUsageLimit_WasSet - ) + && methodMode.MemoryUsageLimit_WasSet) { const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads; @@ -229,14 +274,14 @@ { numSolidBytes = (UInt64)dicSize << 7; if (numSolidBytes > kSolidBytes_Max) - numSolidBytes = kSolidBytes_Max; + numSolidBytes = kSolidBytes_Max; } if (_numSolidBytesDefined) continue; if (numSolidBytes < kSolidBytes_Min) - numSolidBytes = kSolidBytes_Min; + numSolidBytes = kSolidBytes_Min; _numSolidBytes = numSolidBytes; _numSolidBytesDefined = true; } @@ -261,7 +306,7 @@ // ft = 0; // ftDefined = false; NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(index, propID, &prop)); + RINOK(updateCallback->GetProperty(index, propID, &prop)) if (prop.vt == VT_FILETIME) { ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); @@ -344,13 +389,13 @@ } */ -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN - const CDbEx *db = 0; - #ifdef _7Z_VOL + const CDbEx *db = NULL; + #ifdef Z7_7Z_VOL if (_volumes.Size() > 1) return E_FAIL; const CVolume *volume = 0; @@ -360,7 +405,7 @@ db = &volume->Database; } #else - if (_inStream != 0) + if (_inStream) db = &_db; #endif @@ -368,8 +413,9 @@ return E_NOTIMPL; /* - CMyComPtr getRawProps; - updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRawProps, + getRawProps, updateCallback) CUniqBlocks secureBlocks; secureBlocks.AddUniq(NULL, 0); @@ -406,7 +452,7 @@ UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) CUpdateItem ui; ui.NewProps = IntToBool(newProps); ui.NewData = IntToBool(newData); @@ -445,7 +491,7 @@ if (need_Attrib) { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)); + RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) ui.AttribDefined = false; else if (prop.vt != VT_UI4) @@ -458,9 +504,9 @@ } // we need MTime to sort files. - if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)); - if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)); - if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)); + if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)) + if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)) + if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)) /* if (getRawProps) @@ -478,7 +524,7 @@ { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + RINOK(updateCallback->GetProperty(i, kpidPath, &prop)) if (prop.vt == VT_EMPTY) { } @@ -492,7 +538,7 @@ } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)) if (prop.vt == VT_EMPTY) folderStatusIsDefined = false; else if (prop.vt != VT_BOOL) @@ -506,7 +552,7 @@ { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)); + RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)) if (prop.vt == VT_EMPTY) ui.IsAnti = false; else if (prop.vt != VT_BOOL) @@ -623,7 +669,7 @@ if (!ui.IsDir) { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(i, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; ui.Size = (UInt64)prop.uhVal.QuadPart; @@ -650,7 +696,7 @@ methodMode.MemoryUsageLimit = _memUsage_Compress; methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet; - #ifndef _7ZIP_ST + #ifndef Z7_ST { UInt32 numThreads = _numThreads; const UInt32 kNumThreads_Max = 1024; @@ -659,18 +705,22 @@ methodMode.NumThreads = numThreads; methodMode.NumThreads_WasForced = _numThreads_WasForced; methodMode.MultiThreadMixer = _useMultiThreadMixer; +#ifdef _WIN32 + methodMode.NumThreadGroups = _numThreadGroups; // _change it +#endif // headerMethod.NumThreads = 1; headerMethod.MultiThreadMixer = _useMultiThreadMixer; } #endif - HRESULT res = SetMainMethod(methodMode); - RINOK(res); + const HRESULT res = SetMainMethod(methodMode); + RINOK(res) - RINOK(SetHeaderMethod(headerMethod)); + RINOK(SetHeaderMethod(headerMethod)) - CMyComPtr getPassword2; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword2, + getPassword2, updateCallback) methodMode.PasswordIsDefined = false; methodMode.Password.Wipe_and_Empty(); @@ -678,7 +728,7 @@ { CMyComBSTR_Wipe password; Int32 passwordIsDefined; - RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)); + RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)) methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); if (methodMode.PasswordIsDefined && password) methodMode.Password = password; @@ -688,7 +738,7 @@ bool encryptHeaders = false; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (!methodMode.PasswordIsDefined && _passwordIsDefined) { // if header is compressed, we use that password for updated archive @@ -701,7 +751,7 @@ { if (_encryptHeadersSpecified) encryptHeaders = _encryptHeaders; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO else encryptHeaders = _passwordIsDefined; #endif @@ -716,13 +766,14 @@ if (numItems < 2) compressMainHeader = false; - int level = GetLevel(); + const int level = GetLevel(); CUpdateOptions options; options.Need_CTime = need_CTime; options.Need_ATime = need_ATime; options.Need_MTime = need_MTime; options.Need_Attrib = need_Attrib; + // options.Need_Crc = (_crcSize != 0); // for debug options.Method = &methodMode; options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL; @@ -730,6 +781,11 @@ options.MaxFilter = (level >= 8); options.AnalysisLevel = GetAnalysisLevel(); + options.SetFilterSupporting_ver_enabled_disabled( + _decoderCompatibilityVersion, + _enabledFilters, + _disabledFilters); + options.HeaderOptions.CompressMainHeader = compressMainHeader; /* options.HeaderOptions.WriteCTime = Write_CTime; @@ -748,12 +804,6 @@ options.MultiThreadMixer = _useMultiThreadMixer; - COutArchive archive; - CArchiveDatabaseOut newDatabase; - - CMyComPtr getPassword; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword); - /* if (secureBlocks.Sorted.Size() > 1) { @@ -766,9 +816,9 @@ } */ - res = Update( + return Update( EXTERNAL_CODECS_VARS - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL volume ? volume->Stream: 0, volume ? db : 0, #else @@ -778,18 +828,7 @@ updateItems, // treeFolders, // secureBlocks, - archive, newDatabase, outStream, updateCallback, options - #ifndef _NO_CRYPTO - , getPassword - #endif - ); - - RINOK(res); - - updateItems.ClearAndFree(); - - return archive.WriteDatabase(EXTERNAL_CODECS_VARS - newDatabase, options.HeaderMethod, options.HeaderOptions); + outStream, updateCallback, options); COM_TRY_END } @@ -798,7 +837,7 @@ { stream = 0; { - unsigned index = ParseStringToUInt32(srcString, coder); + const unsigned index = ParseStringToUInt32(srcString, coder); if (index == 0) return E_INVALIDARG; srcString.DeleteFrontal(index); @@ -806,7 +845,7 @@ if (srcString[0] == 's') { srcString.Delete(0); - unsigned index = ParseStringToUInt32(srcString, stream); + const unsigned index = ParseStringToUInt32(srcString, stream); if (index == 0) return E_INVALIDARG; srcString.DeleteFrontal(index); @@ -831,6 +870,10 @@ InitSolid(); _useTypeSorting = false; + + _decoderCompatibilityVersion = k_decoderCompatibilityVersion; + _enabledFilters.Clear(); + _disabledFilters.Clear(); } void COutHandler::InitProps() @@ -860,7 +903,7 @@ i += (unsigned)(end - start); if (i == s2.Len()) return E_INVALIDARG; - wchar_t c = s2[i++]; + const wchar_t c = s2[i++]; if (c == 'f') { if (v < 1) @@ -912,11 +955,34 @@ static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) { - RINOK(PROPVARIANT_to_bool(prop, dest.Val)); + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) dest.Def = true; return S_OK; } +struct C_Id_Name_pair +{ + UInt32 Id; + const char *Name; +}; + +static const C_Id_Name_pair g_filter_pairs[] = +{ + { k_Delta, "Delta" }, + { k_ARM64, "ARM64" }, + { k_RISCV, "RISCV" }, + { k_SWAP2, "SWAP2" }, + { k_SWAP4, "SWAP4" }, + { k_BCJ, "BCJ" }, + { k_BCJ2 , "BCJ2" }, + { k_PPC, "PPC" }, + { k_IA64, "IA64" }, + { k_ARM, "ARM" }, + { k_ARMT, "ARMT" }, + { k_SPARC, "SPARC" } +}; + + HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) { UString name = nameSpec; @@ -935,7 +1001,7 @@ } UInt32 number; - unsigned index = ParseStringToUInt32(name, number); + const unsigned index = ParseStringToUInt32(name, number); // UString realName = name.Ptr(index); if (index == 0) { @@ -946,20 +1012,20 @@ if (name.IsEqualTo("hcf")) { bool compressHeadersFull = true; - RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)); + RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)) return compressHeadersFull ? S_OK: E_INVALIDARG; } if (name.IsEqualTo("he")) { - RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)); + RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)) _encryptHeadersSpecified = true; return S_OK; } { bool processed; - RINOK(TimeOptions.Parse(name, value, processed)); + RINOK(TimeOptions.Parse(name, value, processed)) if (processed) { if ( TimeOptions.Prec != (UInt32)(Int32)-1 @@ -977,12 +1043,49 @@ if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting); + if (name.IsPrefixedBy_Ascii_NoCase("yv")) + { + name.Delete(0, 2); + UInt32 v = 1 << 16; // if no number is noit specified, we use big value + RINOK(ParsePropToUInt32(name, value, v)) + _decoderCompatibilityVersion = v; + // if (v == 0) _decoderCompatibilityVersion = k_decoderCompatibilityVersion; + return S_OK; + } + + if (name.IsPrefixedBy_Ascii_NoCase("yf")) + { + name.Delete(0, 2); + CUIntVector *vec; + if (name.IsEqualTo_Ascii_NoCase("a")) vec = &_enabledFilters; + else if (name.IsEqualTo_Ascii_NoCase("d")) vec = &_disabledFilters; + else return E_INVALIDARG; + + if (value.vt != VT_BSTR) + return E_INVALIDARG; + for (unsigned k = 0;; k++) + { + if (k == Z7_ARRAY_SIZE(g_filter_pairs)) + { + // maybe we can ignore unsupported filter names here? + return E_INVALIDARG; + } + const C_Id_Name_pair &pair = g_filter_pairs[k]; + if (StringsAreEqualNoCase_Ascii(value.bstrVal, pair.Name)) + { + vec->AddToUniqueSorted(pair.Id); + break; + } + } + return S_OK; + } + // if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode); } return CMultiMethodProps::SetProperty(name, value); } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN _bonds.Clear(); @@ -997,6 +1100,7 @@ const PROPVARIANT &value = values[i]; + if (name.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23 if (name[0] == 'b') { if (value.vt != VT_EMPTY) @@ -1004,12 +1108,12 @@ name.Delete(0); CBond2 bond; - RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)); + RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)) if (name[0] != ':') return E_INVALIDARG; name.Delete(0); UInt32 inStream = 0; - RINOK(ParseBond(name, bond.InCoder, inStream)); + RINOK(ParseBond(name, bond.InCoder, inStream)) if (inStream != 0) return E_INVALIDARG; if (!name.IsEmpty()) @@ -1018,7 +1122,7 @@ continue; } - RINOK(SetProperty(name, value)); + RINOK(SetProperty(name, value)) } unsigned numEmptyMethods = GetNumEmptyMethods(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHeader.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHeader.cpp 2013-11-24 13:19:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.cpp 2023-03-04 09:00:00.000000000 +0000 @@ -8,7 +8,7 @@ namespace N7z { Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zHeader.h 2020-07-04 10:05:04.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zHeader.h 2024-03-03 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7z/7zHeader.h -#ifndef __7Z_HEADER_H -#define __7Z_HEADER_H +#ifndef ZIP7_INC_7Z_HEADER_H +#define ZIP7_INC_7Z_HEADER_H #include "../../../Common/MyTypes.h" @@ -11,13 +11,13 @@ const unsigned kSignatureSize = 6; extern Byte kSignature[kSignatureSize]; -// #define _7Z_VOL +// #define Z7_7Z_VOL // 7z-MultiVolume is not finished yet. // It can work already, but I still do not like some // things of that new multivolume format. // So please keep it commented. -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL extern Byte kFinishSignature[kSignatureSize]; #endif @@ -38,7 +38,7 @@ const UInt32 kStartHeaderSize = 20; -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL struct CFinishHeader: public CStartHeader { UInt64 ArchiveStartOffset; // data offset from end if that struct @@ -99,6 +99,8 @@ const UInt32 k_Copy = 0; const UInt32 k_Delta = 3; +const UInt32 k_ARM64 = 0xa; +const UInt32 k_RISCV = 0xb; const UInt32 k_LZMA2 = 0x21; @@ -122,14 +124,18 @@ const UInt32 k_AES = 0x6F10701; +// const UInt32 k_ZSTD = 0x4015D; // winzip zstd +// 0x4F71101, 7z-zstd -static inline bool IsFilterMethod(UInt64 m) +inline bool IsFilterMethod(UInt64 m) { - if (m > (UInt64)0xFFFFFFFF) + if (m > (UInt32)0xFFFFFFFF) return false; switch ((UInt32)m) { case k_Delta: + case k_ARM64: + case k_RISCV: case k_BCJ: case k_BCJ2: case k_PPC: @@ -140,6 +146,7 @@ case k_SWAP2: case k_SWAP4: return true; + default: break; } return false; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zIn.cpp 2021-04-14 10:28:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.cpp 2024-02-17 09:00:00.000000000 +0000 @@ -11,6 +11,7 @@ #include "../../../../C/7zCrc.h" #include "../../../../C/CpuArch.h" +#include "../../../Common/MyBuffer2.h" // #include "../../../Common/UTFConvert.h" #include "../../Common/StreamObjects.h" @@ -24,51 +25,62 @@ #define Get64(p) GetUi64(p) // define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader -#ifndef _SFX +#ifndef Z7_SFX #define FORMAT_7Z_RECOVERY #endif using namespace NWindows; using namespace NCOM; -namespace NArchive { -namespace N7z { - unsigned BoolVector_CountSum(const CBoolVector &v); +Z7_NO_INLINE unsigned BoolVector_CountSum(const CBoolVector &v) { unsigned sum = 0; const unsigned size = v.Size(); - for (unsigned i = 0; i < size; i++) - if (v[i]) - sum++; + if (size) + { + const bool *p = v.ConstData(); + const bool * const lim = p + size; + do + if (*p) + sum++; + while (++p != lim); + } return sum; } static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i) { - return (i < v.Size() ? v[i] : false); + return i < v.Size() ? v[i] : false; } +Z7_NO_INLINE static void BoolVector_Fill_False(CBoolVector &v, unsigned size) { v.ClearAndSetSize(size); - bool *p = &v[0]; + bool *p = v.NonConstData(); for (unsigned i = 0; i < size; i++) p[i] = false; } +namespace NArchive { +namespace N7z { + +#define k_Scan_NumCoders_MAX 64 +#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + class CInArchiveException {}; class CUnsupportedFeatureException: public CInArchiveException {}; -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void ThrowException() { throw CInArchiveException(); } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static inline void ThrowEndOfData() { ThrowException(); } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static inline void ThrowIncorrect() { ThrowException(); } class CStreamSwitch @@ -113,12 +125,12 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector *dataVector) { Remove(); - Byte external = archive->ReadByte(); + const Byte external = archive->ReadByte(); if (external != 0) { if (!dataVector) ThrowIncorrect(); - CNum dataIndex = archive->ReadNum(); + const CNum dataIndex = archive->ReadNum(); if (dataIndex >= dataVector->Size()) ThrowIncorrect(); Set(archive, (*dataVector)[dataIndex]); @@ -171,7 +183,7 @@ return 0; } - unsigned b = *p++; + const unsigned b = *p++; size--; if ((b & 0x80) == 0) @@ -192,10 +204,10 @@ for (unsigned i = 1; i < 8; i++) { - unsigned mask = (unsigned)0x80 >> i; + const unsigned mask = (unsigned)0x80 >> i; if ((b & mask) == 0) { - UInt64 high = b & (mask - 1); + const UInt64 high = b & (mask - 1); value |= (high << (i * 8)); processed = i + 1; return value; @@ -219,7 +231,7 @@ UInt64 CInByte2::ReadNumber() { size_t processed; - UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); + const UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); if (processed == 0) ThrowEndOfData(); _pos += processed; @@ -239,7 +251,7 @@ } } */ - UInt64 value = ReadNumber(); + const UInt64 value = ReadNumber(); if (value > kNumMax) ThrowUnsupported(); return (CNum)value; @@ -249,7 +261,7 @@ { if (_pos + 4 > _size) ThrowEndOfData(); - UInt32 res = Get32(_buffer + _pos); + const UInt32 res = Get32(_buffer + _pos); _pos += 4; return res; } @@ -258,54 +270,101 @@ { if (_pos + 8 > _size) ThrowEndOfData(); - UInt64 res = Get64(_buffer + _pos); + const UInt64 res = Get64(_buffer + _pos); _pos += 8; return res; } -#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false; +#define Y0 '7' +#define Y1 'z' +#define Y2 0xBC +#define Y3 0xAF +#define Y4 0x27 +#define Y5 0x1C + +#define IS_SIGNATURE(p)( \ + (p)[2] == Y2 && \ + (p)[3] == Y3 && \ + (p)[5] == Y5 && \ + (p)[4] == Y4 && \ + (p)[1] == Y1 && \ + (p)[0] == Y0) + +/* FindSignature_10() is allowed to access data up to and including &limit[9]. + limit[10] access is not allowed. + return: + (return_ptr < limit) : signature was found at (return_ptr) + (return_ptr >= limit) : limit was reached or crossed. So no signature found before limit +*/ +Z7_NO_INLINE +static const Byte *FindSignature_10(const Byte *p, const Byte *limit) +{ + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + const Byte b = p[5]; + p += 6; + if (b == Y0) { break; } + if (b == Y1) { p -= 1; break; } + if (b == Y2) { p -= 2; break; } + if (b == Y3) { p -= 3; break; } + if (b == Y4) { p -= 4; break; } + if (b == Y5) { p -= 5; break; } + } + if (IS_SIGNATURE(p - 1)) + return p - 1; + } +} + -static inline bool TestSignature(const Byte *p) +static inline bool TestStartCrc(const Byte *p) { - CHECK_SIGNATURE return CrcCalc(p + 12, 20) == Get32(p + 8); } -#ifdef FORMAT_7Z_RECOVERY static inline bool TestSignature2(const Byte *p) { - CHECK_SIGNATURE; - if (CrcCalc(p + 12, 20) == Get32(p + 8)) + if (!IS_SIGNATURE(p)) + return false; + #ifdef FORMAT_7Z_RECOVERY + if (TestStartCrc(p)) return true; for (unsigned i = 8; i < kHeaderSize; i++) if (p[i] != 0) return false; return (p[6] != 0 || p[7] != 0); + #else + return TestStartCrc(p); + #endif } -#else -#define TestSignature2(p) TestSignature(p) -#endif + HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)) if (TestSignature2(_header)) return S_OK; if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) return S_FALSE; - const UInt32 kBufSize = 1 << 15; - CByteArr buf(kBufSize); + const UInt32 kBufSize = (1 << 15) + kHeaderSize; // must be > (kHeaderSize * 2) + CAlignedBuffer1 buf(kBufSize); memcpy(buf, _header, kHeaderSize); UInt64 offset = 0; for (;;) { - UInt32 readSize = kBufSize - kHeaderSize; + UInt32 readSize = + (offset == 0) ? + kBufSize - kHeaderSize - kHeaderSize : + kBufSize - kHeaderSize; if (searchHeaderSizeLimit) { - UInt64 rem = *searchHeaderSizeLimit - offset; + const UInt64 rem = *searchHeaderSizeLimit - offset; if (readSize > rem) readSize = (UInt32)rem; if (readSize == 0) @@ -313,29 +372,28 @@ } UInt32 processed = 0; - RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)); + RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)) if (processed == 0) return S_FALSE; + + /* &buf[0] was already tested for signature before. + So first search here will be for &buf[1] */ for (UInt32 pos = 0;;) { const Byte *p = buf + pos + 1; - const Byte *lim = buf + processed; - for (; p <= lim; p += 4) - { - if (p[0] == '7') break; - if (p[1] == '7') { p += 1; break; } - if (p[2] == '7') { p += 2; break; } - if (p[3] == '7') { p += 3; break; } - }; - if (p > lim) + const Byte *lim = buf + processed + 1; + /* we have (kHeaderSize - 1 = 31) filled bytes starting from (lim), + and it's safe to access just 10 bytes in that reserved area */ + p = FindSignature_10(p, lim); + if (p >= lim) break; pos = (UInt32)(p - buf); - if (TestSignature(p)) + if (TestStartCrc(p)) { memcpy(_header, p, kHeaderSize); _arhiveBeginStreamPosition += offset + pos; - return stream->Seek((Int64)(_arhiveBeginStreamPosition + kHeaderSize), STREAM_SEEK_SET, NULL); + return InStream_SeekSet(stream, _arhiveBeginStreamPosition + kHeaderSize); } } @@ -349,10 +407,8 @@ { HeadersSize = 0; Close(); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) - RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition)) - RINOK(stream->Seek((Int64)_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)) - RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + RINOK(InStream_GetPos_GetSize(stream, _arhiveBeginStreamPosition, _fileEndPosition)) + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)) _stream = stream; return S_OK; } @@ -378,9 +434,9 @@ void CInByte2::ParseFolder(CFolder &folder) { - UInt32 numCoders = ReadNum(); + const UInt32 numCoders = ReadNum(); - if (numCoders == 0) + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) ThrowUnsupported(); folder.Coders.SetSize(numCoders); @@ -391,10 +447,10 @@ { CCoderInfo &coder = folder.Coders[i]; { - Byte mainByte = ReadByte(); + const Byte mainByte = ReadByte(); if ((mainByte & 0xC0) != 0) ThrowUnsupported(); - unsigned idSize = (mainByte & 0xF); + const unsigned idSize = (mainByte & 0xF); if (idSize > 8 || idSize > GetRem()) ThrowUnsupported(); const Byte *longID = GetPtr(); @@ -407,7 +463,9 @@ if ((mainByte & 0x10) != 0) { coder.NumStreams = ReadNum(); + // if (coder.NumStreams > k_Scan_NumCodersStreams_in_Folder_MAX) ThrowUnsupported(); /* numOutStreams = */ ReadNum(); + // if (ReadNum() != 1) // numOutStreams ThrowUnsupported(); } else { @@ -416,7 +474,7 @@ if ((mainByte & 0x20) != 0) { - CNum propsSize = ReadNum(); + const CNum propsSize = ReadNum(); coder.Props.Alloc((size_t)propsSize); ReadBytes((Byte *)coder.Props, (size_t)propsSize); } @@ -426,7 +484,7 @@ numInStreams += coder.NumStreams; } - UInt32 numBonds = numCoders - 1; + const UInt32 numBonds = numCoders - 1; folder.Bonds.SetSize(numBonds); for (i = 0; i < numBonds; i++) { @@ -437,7 +495,7 @@ if (numInStreams < numBonds) ThrowUnsupported(); - UInt32 numPackStreams = numInStreams - numBonds; + const UInt32 numPackStreams = numInStreams - numBonds; folder.PackStreams.SetSize(numPackStreams); if (numPackStreams == 1) @@ -458,9 +516,9 @@ void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const { - size_t startPos = FoCodersDataOffset[folderIndex]; + const size_t startPos = FoCodersDataOffset[folderIndex]; CInByte2 inByte; - inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); + inByte.Init(CodersData.ConstData() + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); inByte.ParseFolder(folder); if (inByte.GetRem() != 0) throw 20120424; @@ -473,8 +531,8 @@ if (!NameOffsets || !NamesBuf) return; - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; if (size >= (1 << 28)) return; @@ -507,8 +565,8 @@ if (!NameOffsets || !NamesBuf) return S_OK; - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; if (size >= (1 << 14)) return S_OK; @@ -530,7 +588,7 @@ #else */ - RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)); + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)) wchar_t *s = path->bstrVal; const Byte *p = ((const Byte *)NamesBuf + offset * 2); // Utf16LE__To_WCHARs_Sep(p, size, s); @@ -601,7 +659,7 @@ { for (;;) { - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type == id) return; if (type == NID::kEnd) @@ -613,7 +671,7 @@ void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v) { - unsigned numItems = v.Defs.Size(); + const unsigned numItems = v.Defs.Size(); v.Vals.ClearAndSetSize(numItems); UInt32 *p = &v.Vals[0]; const bool *defs = &v.Defs[0]; @@ -634,12 +692,9 @@ } -#define k_Scan_NumCoders_MAX 64 -#define k_Scan_NumCodersStreams_in_Folder_MAX 64 - void CInArchive::ReadPackInfo(CFolders &f) { - CNum numPackStreams = ReadNum(); + const CNum numPackStreams = ReadNum(); WaitId(NID::kSize); f.PackPositions.Alloc(numPackStreams + 1); @@ -648,7 +703,7 @@ for (CNum i = 0; i < numPackStreams; i++) { f.PackPositions[i] = sum; - UInt64 packSize = ReadNumber(); + const UInt64 packSize = ReadNumber(); sum += packSize; if (sum < packSize) ThrowIncorrect(); @@ -676,7 +731,7 @@ CFolders &folders) { WaitId(NID::kFolder); - CNum numFolders = ReadNum(); + const CNum numFolders = ReadNum(); CNum numCodersOutStreams = 0; { @@ -704,18 +759,18 @@ folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr); CNum numInStreams = 0; - CNum numCoders = inByte->ReadNum(); + const CNum numCoders = inByte->ReadNum(); if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) ThrowUnsupported(); for (CNum ci = 0; ci < numCoders; ci++) { - Byte mainByte = inByte->ReadByte(); + const Byte mainByte = inByte->ReadByte(); if ((mainByte & 0xC0) != 0) ThrowUnsupported(); - unsigned idSize = (mainByte & 0xF); + const unsigned idSize = (mainByte & 0xF); if (idSize > 8) ThrowUnsupported(); if (idSize > inByte->GetRem()) @@ -744,18 +799,18 @@ if ((mainByte & 0x20) != 0) { - CNum propsSize = inByte->ReadNum(); + const CNum propsSize = inByte->ReadNum(); if (propsSize > inByte->GetRem()) ThrowEndOfData(); if (id == k_LZMA2 && propsSize == 1) { - Byte v = *_inByteBack->GetPtr(); + const Byte v = *_inByteBack->GetPtr(); if (folders.ParsedMethods.Lzma2Prop < v) folders.ParsedMethods.Lzma2Prop = v; } else if (id == k_LZMA && propsSize == 5) { - UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); + const UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); if (folders.ParsedMethods.LzmaDic < dicSize) folders.ParsedMethods.LzmaDic = dicSize; } @@ -771,7 +826,7 @@ else { UInt32 i; - CNum numBonds = numCoders - 1; + const CNum numBonds = numCoders - 1; if (numInStreams < numBonds) ThrowUnsupported(); @@ -796,7 +851,7 @@ if (numPackStreams != 1) for (i = 0; i < numPackStreams; i++) { - CNum index = inByte->ReadNum(); // PackStreams + const CNum index = inByte->ReadNum(); // PackStreams if (index >= numInStreams || StreamUsed[index]) ThrowUnsupported(); StreamUsed[index] = true; @@ -838,7 +893,7 @@ for (;;) { - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type == NID::kEnd) return; if (type == NID::kCRC) @@ -882,19 +937,19 @@ { // v3.13 incorrectly worked with empty folders // v4.07: we check that folder is empty - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 0) continue; UInt64 sum = 0; for (CNum j = 1; j < numSubstreams; j++) { - UInt64 size = ReadNumber(); + const UInt64 size = ReadNumber(); unpackSizes.Add(size); sum += size; if (sum < size) ThrowIncorrect(); } - UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); + const UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); if (folderUnpackSize < sum) ThrowIncorrect(); unpackSizes.Add(folderUnpackSize - sum); @@ -907,7 +962,7 @@ { /* v9.26 - v9.29 incorrectly worked: if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ - CNum val = folders.NumUnpackStreamsVector[i]; + const CNum val = folders.NumUnpackStreamsVector[i]; if (val > 1) ThrowIncorrect(); if (val == 1) @@ -918,7 +973,7 @@ unsigned numDigests = 0; for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) numDigests += numSubstreams; } @@ -941,7 +996,7 @@ for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { digests.Defs[k] = true; @@ -973,7 +1028,7 @@ unsigned k = 0; for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { digests.Defs[k] = true; @@ -1069,7 +1124,7 @@ void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) { - Byte allAreDefined = ReadByte(); + const Byte allAreDefined = ReadByte(); if (allAreDefined == 0) { ReadBoolVector(numItems, v); @@ -1106,7 +1161,7 @@ DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { CFolders folders; @@ -1130,8 +1185,7 @@ ThrowUnsupported(); data.Alloc(unpackSize); - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream = outStreamSpec; + CMyComPtr2_Create outStreamSpec; outStreamSpec->Init(data, unpackSize); bool dataAfterEnd_Error = false; @@ -1142,21 +1196,21 @@ folders, i, NULL, // &unpackSize64 - outStream, + outStreamSpec, NULL, // *compressProgress NULL // **inStreamMainRes , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) , false // mtMode , 1 // numThreads , 0 // memUsage #endif ); - RINOK(result); + RINOK(result) if (dataAfterEnd_Error) ThereIsHeaderError = true; @@ -1178,7 +1232,7 @@ HRESULT CInArchive::ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { UInt64 type = ReadID(); @@ -1193,14 +1247,14 @@ if (type == NID::kAdditionalStreamsInfo) { - HRESULT result = ReadAndDecodePackedStreams( + const HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS db.ArcInfo.StartPositionAfterHeader, db.ArcInfo.DataStartPosition2, dataVector - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); - RINOK(result); + RINOK(result) db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; type = ReadID(); } @@ -1233,14 +1287,14 @@ CBoolVector emptyStreamVector; CBoolVector emptyFileVector; CBoolVector antiFileVector; - CNum numEmptyStreams = 0; + unsigned numEmptyStreams = 0; for (;;) { const UInt64 type2 = ReadID(); if (type2 == NID::kEnd) break; - UInt64 size = ReadNumber(); + const UInt64 size = ReadNumber(); if (size > _inByteBack->GetRem()) ThrowIncorrect(); CStreamSwitch switchProp; @@ -1255,7 +1309,7 @@ { CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - size_t rem = _inByteBack->GetRem(); + const size_t rem = _inByteBack->GetRem(); db.NamesBuf.Alloc(rem); ReadBytes(db.NamesBuf, rem); db.NameOffsets.Alloc(numFiles + 1); @@ -1264,7 +1318,7 @@ for (i = 0; i < numFiles; i++) { const size_t curRem = (rem - pos) / 2; - const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf + pos); + const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf.ConstData() + pos); size_t j; for (j = 0; j < curRem && buf[j] != 0; j++); if (j == curRem) @@ -1410,7 +1464,7 @@ CNum emptyFileIndex = 0; CNum sizeIndex = 0; - const CNum numAntiItems = BoolVector_CountSum(antiFileVector); + const unsigned numAntiItems = BoolVector_CountSum(antiFileVector); if (numAntiItems != 0) db.IsAnti.ClearAndSetSize(numFiles); @@ -1471,7 +1525,7 @@ for (i = 0; i < Files.Size(); i++) { - bool emptyStream = !Files[i].HasStream; + const bool emptyStream = !Files[i].HasStream; if (indexInFolder == 0) { if (emptyStream) @@ -1528,7 +1582,7 @@ HRESULT CInArchive::ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { db.Clear(); @@ -1548,22 +1602,22 @@ UInt32 nextHeaderCRC = Get32(_header + 28); #ifdef FORMAT_7Z_RECOVERY - UInt32 crcFromArc = Get32(_header + 8); + const UInt32 crcFromArc = Get32(_header + 8); if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) { UInt64 cur, fileSize; - RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); + RINOK(InStream_GetPos(_stream, cur)) const unsigned kCheckSize = 512; Byte buf[kCheckSize]; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize)) const UInt64 rem = fileSize - cur; unsigned checkSize = kCheckSize; if (rem < kCheckSize) checkSize = (unsigned)(rem); if (checkSize < 3) return S_FALSE; - RINOK(_stream->Seek((Int64)(fileSize - checkSize), STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); + RINOK(InStream_SeekSet(_stream, fileSize - checkSize)) + RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)) if (buf[checkSize - 1] != 0) return S_FALSE; @@ -1580,7 +1634,7 @@ nextHeaderSize = checkSize - i; nextHeaderOffset = rem - nextHeaderSize; nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); - RINOK(_stream->Seek((Int64)cur, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, cur)) db.StartHeaderWasRecovered = true; } else @@ -1602,7 +1656,7 @@ if (nextHeaderSize == 0) { - if (nextHeaderOffset != 0) + if (nextHeaderOffset != 0 || nextHeaderCRC != 0) return S_FALSE; db.IsArc = true; db.HeadersSize = HeadersSize; @@ -1622,14 +1676,14 @@ db.UnexpectedEnd = true; return S_FALSE; } - RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL)); + RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL)) - size_t nextHeaderSize_t = (size_t)nextHeaderSize; + const size_t nextHeaderSize_t = (size_t)nextHeaderSize; if (nextHeaderSize_t != nextHeaderSize) return E_OUTOFMEMORY; CByteBuffer buffer2(nextHeaderSize_t); - RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)); + RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)) if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) ThrowIncorrect(); @@ -1642,19 +1696,19 @@ CObjectVector dataVector; - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type != NID::kHeader) { if (type != NID::kEncodedHeader) ThrowIncorrect(); - HRESULT result = ReadAndDecodePackedStreams( + const HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS db.ArcInfo.StartPositionAfterHeader, db.ArcInfo.DataStartPosition2, dataVector - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); - RINOK(result); + RINOK(result) if (dataVector.Size() == 0) return S_OK; if (dataVector.Size() > 1) @@ -1672,7 +1726,7 @@ return ReadHeader( EXTERNAL_CODECS_LOC_VARS db - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); } @@ -1680,14 +1734,14 @@ HRESULT CInArchive::ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { try { - HRESULT res = ReadDatabase2( + const HRESULT res = ReadDatabase2( EXTERNAL_CODECS_LOC_VARS db - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); if (ThereIsHeaderError) db.ThereIsHeaderError = true; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zIn.h 2019-07-01 11:38:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zIn.h 2024-02-17 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zIn.h -#ifndef __7Z_IN_H -#define __7Z_IN_H +#ifndef ZIP7_INC_7Z_IN_H +#define ZIP7_INC_7Z_IN_H #include "../../../Common/MyCom.h" @@ -22,12 +22,12 @@ We don't need to init isEncrypted and passwordIsDefined We must upgrade them only */ -#ifdef _NO_CRYPTO -#define _7Z_DECODER_CRYPRO_VARS_DECL -#define _7Z_DECODER_CRYPRO_VARS +#ifdef Z7_NO_CRYPTO +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL +#define Z7_7Z_DECODER_CRYPRO_VARS #else -#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password -#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password +#define Z7_7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password #endif struct CParsedMethods @@ -273,33 +273,36 @@ void FillLinks(); - UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const + UInt64 GetFolderStreamPos(size_t folderIndex, size_t indexInFolder) const { - return ArcInfo.DataStartPosition + - PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; + return ArcInfo.DataStartPosition + PackPositions.ConstData() + [FoStartPackStreamIndex.ConstData()[folderIndex] + indexInFolder]; } - UInt64 GetFolderFullPackSize(CNum folderIndex) const + UInt64 GetFolderFullPackSize(size_t folderIndex) const { return - PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - - PackPositions[FoStartPackStreamIndex[folderIndex]]; + PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex + 1]] - + PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex]]; } - UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const + UInt64 GetFolderPackStreamSize(size_t folderIndex, size_t streamIndex) const { - size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex; - return PackPositions[i + 1] - PackPositions[i]; + const size_t i = FoStartPackStreamIndex.ConstData()[folderIndex] + streamIndex; + return PackPositions.ConstData()[i + 1] - + PackPositions.ConstData()[i]; } - UInt64 GetFilePackSize(CNum fileIndex) const + /* + UInt64 GetFilePackSize(size_t fileIndex) const { - CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; + const CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; if (folderIndex != kNumNoIndex) if (FolderStartFileIndex[folderIndex] == fileIndex) return GetFolderFullPackSize(folderIndex); return 0; } + */ }; const unsigned kNumBufLevelsMax = 4; @@ -418,17 +421,17 @@ DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); public: CInArchive(bool useMixerMT): @@ -442,7 +445,7 @@ HRESULT ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zItem.h 2021-01-25 09:26:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zItem.h 2023-09-12 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zItem.h -#ifndef __7Z_ITEM_H -#define __7Z_ITEM_H +#ifndef ZIP7_INC_7Z_ITEM_H +#define ZIP7_INC_7Z_ITEM_H #include "../../../Common/MyBuffer.h" #include "../../../Common/MyString.h" @@ -36,7 +36,7 @@ struct CFolder { - CLASS_NO_COPY(CFolder) + Z7_CLASS_NO_COPY(CFolder) public: CObjArray2 Coders; CObjArray2 Bonds; @@ -129,6 +129,11 @@ bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } void SetItem(unsigned index, bool defined, UInt32 value); + void if_NonEmpty_FillResidue_with_false(unsigned numItems) + { + if (Defs.Size() != 0 && Defs.Size() < numItems) + SetItem(numItems - 1, false, 0); + } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zOut.cpp 2021-04-02 16:46:07.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -3,27 +3,45 @@ #include "StdAfx.h" #include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" #include "../../../Common/AutoPtr.h" // #include "../../../Common/UTFConvert.h" #include "../../Common/StreamObjects.h" +#include "../Common/OutStreamWithCRC.h" #include "7zOut.h" +unsigned BoolVector_CountSum(const CBoolVector &v); + +static UInt64 UInt64Vector_CountSum(const CRecordVector &v) +{ + UInt64 sum = 0; + const unsigned size = v.Size(); + if (size) + { + const UInt64 *p = v.ConstData(); + const UInt64 * const lim = p + size; + do + sum += *p++; + while (p != lim); + } + return sum; +} + + namespace NArchive { namespace N7z { -HRESULT COutArchive::WriteSignature() +static void FillSignature(Byte *buf) { - Byte buf[8]; memcpy(buf, kSignature, kSignatureSize); buf[kSignatureSize] = kMajorVersion; buf[kSignatureSize + 1] = 4; - return WriteDirect(buf, 8); } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL HRESULT COutArchive::WriteFinishSignature() { RINOK(WriteDirect(kFinishSignature, kSignatureSize)); @@ -49,15 +67,16 @@ HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) { - Byte buf[24]; - SetUInt64(buf + 4, h.NextHeaderOffset); - SetUInt64(buf + 12, h.NextHeaderSize); - SetUInt32(buf + 20, h.NextHeaderCRC); - SetUInt32(buf, CrcCalc(buf + 4, 20)); - return WriteDirect(buf, 24); + Byte buf[32]; + FillSignature(buf); + SetUInt64(buf + 8 + 4, h.NextHeaderOffset); + SetUInt64(buf + 8 + 12, h.NextHeaderSize); + SetUInt32(buf + 8 + 20, h.NextHeaderCRC); + SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20)); + return WriteDirect(buf, sizeof(buf)); } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) { CCRC crc; @@ -75,15 +94,15 @@ } #endif -HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) +HRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */) { Close(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL // endMarker = false; _endMarker = endMarker; #endif SeqStream = stream; - if (!endMarker) + // if (!endMarker) { SeqStream.QueryInterface(IID_IOutStream, &Stream); if (!Stream) @@ -91,8 +110,13 @@ return E_NOTIMPL; // endMarker = true; } + RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos)) + Byte buf[32]; + FillSignature(buf); + memset(&buf[8], 0, 32 - 8); + return WriteDirect(buf, sizeof(buf)); } - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (endMarker) { /* @@ -101,17 +125,10 @@ sh.NextHeaderSize = (UInt32)(Int32)-1; sh.NextHeaderCRC = 0; WriteStartHeader(sh); + return S_OK; */ } - else #endif - { - if (!Stream) - return E_FAIL; - RINOK(WriteSignature()); - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); - } - return S_OK; } void COutArchive::Close() @@ -120,17 +137,6 @@ Stream.Release(); } -HRESULT COutArchive::SkipPrefixArchiveHeader() -{ - #ifdef _7Z_VOL - if (_endMarker) - return S_OK; - #endif - Byte buf[24]; - memset(buf, 0, 24); - return WriteDirect(buf, 24); -} - UInt64 COutArchive::GetPos() const { if (_countMode) @@ -147,7 +153,7 @@ else if (_writeToStream) { _outByte.WriteBytes(data, size); - _crc = CrcUpdate(_crc, data, size); + // _crc = CrcUpdate(_crc, data, size); } else _outByte2.WriteBytes(data, size); @@ -158,14 +164,12 @@ if (_countMode) _countSize++; else if (_writeToStream) - { - _outByte.WriteByte(b); - _crc = CRC_UPDATE_BYTE(_crc, b); - } + WriteByte_ToStream(b); else _outByte2.WriteByte(b); } +/* void COutArchive::WriteUInt32(UInt32 value) { for (int i = 0; i < 4; i++) @@ -183,6 +187,7 @@ value >>= 8; } } +*/ void COutArchive::WriteNumber(UInt64 value) { @@ -216,7 +221,7 @@ return i; } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) { UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; @@ -302,7 +307,7 @@ WriteNumber(folder.PackStreams[i]); } -void COutArchive::WriteBoolVector(const CBoolVector &boolVector) +void COutArchive::Write_BoolVector(const CBoolVector &boolVector) { Byte b = 0; Byte mask = 0x80; @@ -328,31 +333,32 @@ { WriteByte(id); WriteNumber(Bv_GetSizeInBytes(boolVector)); - WriteBoolVector(boolVector); + Write_BoolVector(boolVector); +} + +void COutArchive::Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined) +{ + if (numDefined == boolVector.Size()) + WriteByte(1); + else + { + WriteByte(0); + Write_BoolVector(boolVector); + } } -unsigned BoolVector_CountSum(const CBoolVector &v); void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) { const unsigned numDefined = BoolVector_CountSum(digests.Defs); if (numDefined == 0) return; - WriteByte(NID::kCRC); - if (numDefined == digests.Defs.Size()) - WriteByte(1); - else - { - WriteByte(0); - WriteBoolVector(digests.Defs); - } - - for (unsigned i = 0; i < digests.Defs.Size(); i++) - if (digests.Defs[i]) - WriteUInt32(digests.Vals[i]); + Write_BoolVector_numDefined(digests.Defs, numDefined); + Write_UInt32DefVector_numDefined(digests, numDefined); } + void COutArchive::WritePackInfo( UInt64 dataOffset, const CRecordVector &packSizes, @@ -481,17 +487,42 @@ WriteByte(type); WriteNumber(dataSize); - if (numDefined == v.Size()) - WriteByte(1); - else + Write_BoolVector_numDefined(v, numDefined); + WriteByte(0); // 0 means no switching to external stream +} + + +void COutArchive::Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined) +{ + if (_countMode) { - WriteByte(0); - WriteBoolVector(v); + _countSize += (size_t)numDefined * 4; + return; } - WriteByte(0); // 0 means no switching to external stream + + const bool * const defs = v.Defs.ConstData(); + const UInt32 * const vals = v.Vals.ConstData(); + const size_t num = v.Defs.Size(); + + for (size_t i = 0; i < num; i++) + if (defs[i]) + { + UInt32 value = vals[i]; + for (int k = 0; k < 4; k++) + { + if (_writeToStream) + WriteByte_ToStream((Byte)value); + else + _outByte2.WriteByte((Byte)value); + // WriteByte((Byte)value); + value >>= 8; + } + // WriteUInt32(v.Vals[i]); + } } -void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) + +void COutArchive::Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type) { const unsigned numDefined = BoolVector_CountSum(v.Defs); if (numDefined == 0) @@ -499,30 +530,58 @@ WriteAlignedBools(v.Defs, numDefined, type, 3); - for (unsigned i = 0; i < v.Defs.Size(); i++) - if (v.Defs[i]) - WriteUInt64(v.Vals[i]); + if (_countMode) + { + _countSize += (size_t)numDefined * 8; + return; + } + + const bool * const defs = v.Defs.ConstData(); + const UInt64 * const vals = v.Vals.ConstData(); + const size_t num = v.Defs.Size(); + + for (size_t i = 0; i < num; i++) + if (defs[i]) + { + UInt64 value = vals[i]; + for (int k = 0; k < 8; k++) + { + if (_writeToStream) + WriteByte_ToStream((Byte)value); + else + _outByte2.WriteByte((Byte)value); + // WriteByte((Byte)value); + value >>= 8; + } + // WriteUInt64(v.Vals[i]); + } } + HRESULT COutArchive::EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS CEncoder &encoder, const CByteBuffer &data, CRecordVector &packSizes, CObjectVector &folders, COutFolders &outFolders) { - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr stream = streamSpec; + CMyComPtr2_Create streamSpec; streamSpec->Init(data, data.Size()); outFolders.FolderUnpackCRCs.Defs.Add(true); outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); // outFolders.NumUnpackStreamsVector.Add(1); - UInt64 dataSize64 = data.Size(); - UInt64 unpackSize = data.Size(); - RINOK(encoder.Encode( + const UInt64 dataSize64 = data.Size(); + const UInt64 expectSize = data.Size(); + RINOK(encoder.Encode1( EXTERNAL_CODECS_LOC_VARS - stream, + streamSpec, // NULL, - &dataSize64, - folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL)) + &dataSize64, // inSizeForReduce + expectSize, + folders.AddNew(), + // outFolders.CoderUnpackSizes, unpackSize, + SeqStream, packSizes, NULL)) + if (!streamSpec->WasFinished()) + return E_FAIL; + encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes); return S_OK; } @@ -536,13 +595,7 @@ */ _useAlign = true; - { - UInt64 packSize = 0; - FOR_VECTOR (i, db.PackSizes) - packSize += db.PackSizes[i]; - headerOffset = packSize; - } - + headerOffset = UInt64Vector_CountSum(db.PackSizes); WriteByte(NID::kHeader); @@ -663,81 +716,97 @@ { /* ---------- Names ---------- */ - unsigned numDefined = 0; size_t namesDataSize = 0; - FOR_VECTOR (i, db.Files) { - const UString &name = db.Names[i]; - if (!name.IsEmpty()) - numDefined++; - const size_t numUtfChars = - /* - #if WCHAR_MAX > 0xffff + FOR_VECTOR (i, db.Files) + { + const UString &name = db.Names[i]; + const size_t numUtfChars = + /* + #if WCHAR_MAX > 0xffff Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); - #else - */ + #else + */ name.Len(); - // #endif - namesDataSize += (numUtfChars + 1) * 2; + // #endif + namesDataSize += numUtfChars; + } } - - if (numDefined > 0) + if (namesDataSize) { - namesDataSize++; + namesDataSize += db.Files.Size(); // we will write tail zero wchar for each name + namesDataSize *= 2; // 2 bytes per wchar for UTF16 encoding + namesDataSize++; // for additional switch byte (zero value) SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); - WriteByte(NID::kName); WriteNumber(namesDataSize); - WriteByte(0); - FOR_VECTOR (i, db.Files) + + if (_countMode) + _countSize += namesDataSize; + else { - const UString &name = db.Names[i]; - for (unsigned t = 0; t <= name.Len(); t++) + WriteByte(0); + FOR_VECTOR (i, db.Files) { - wchar_t c = name[t]; - - /* - #if WCHAR_MAX > 0xffff - if (c >= 0x10000) + const UString &name = db.Names[i]; + const wchar_t *p = name.Ptr(); + const size_t len = (size_t)name.Len() + 1; + const wchar_t * const lim = p + len; + if (_writeToStream) { - c -= 0x10000; - if (c < (1 << 20)) + do { - unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); - WriteByte((Byte)c0); - WriteByte((Byte)(c0 >> 8)); - c = 0xdc00 + (c & 0x3FF); + const wchar_t c = *p++; + WriteByte_ToStream((Byte)c); + WriteByte_ToStream((Byte)(c >> 8)); } - else - c = '_'; // we change character unsupported by UTF16 + while (p != lim); + } + else + { + Byte *dest = _outByte2.GetDest_and_Update(len * 2); + do + { + /* + #if WCHAR_MAX > 0xffff + if (c >= 0x10000) + { + c -= 0x10000; + if (c < (1 << 20)) + { + unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); + WriteByte((Byte)c0); + WriteByte((Byte)(c0 >> 8)); + c = 0xdc00 + (c & 0x3FF); + } + else + c = '_'; // we change character unsupported by UTF16 + } + #endif + */ + const wchar_t c = *p++; + SetUi16(dest, (UInt16)c) + dest += 2; + } + while (p != lim); } - #endif - */ - - WriteByte((Byte)c); - WriteByte((Byte)(c >> 8)); } } } } - /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime); - /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime); - /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime); - WriteUInt64DefVector(db.StartPos, NID::kStartPos); + /* if (headerOptions.WriteCTime) */ Write_UInt64DefVector_type(db.CTime, NID::kCTime); + /* if (headerOptions.WriteATime) */ Write_UInt64DefVector_type(db.ATime, NID::kATime); + /* if (headerOptions.WriteMTime) */ Write_UInt64DefVector_type(db.MTime, NID::kMTime); + Write_UInt64DefVector_type(db.StartPos, NID::kStartPos); { /* ---------- Write Attrib ---------- */ const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); - if (numDefined != 0) { WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); - FOR_VECTOR (i, db.Attrib.Defs) - { - if (db.Attrib.Defs[i]) - WriteUInt32(db.Attrib.Vals[i]); - } + Write_UInt32DefVector_numDefined(db.Attrib, numDefined); } } @@ -773,13 +842,7 @@ WriteByte(NID::kParent); WriteNumber(dataSize); - if (numIsDir == boolVector.Size()) - WriteByte(1); - else - { - WriteByte(0); - WriteBoolVector(boolVector); - } + Write_BoolVector_numDefined(boolVector, numIsDir); for (i = 0; i < db.Files.Size(); i++) { const CFileItem &file = db.Files[i]; @@ -826,32 +889,34 @@ if (!db.CheckNumFiles()) return E_FAIL; - UInt64 headerOffset; - UInt32 headerCRC; - UInt64 headerSize; - if (db.IsEmpty()) - { - headerSize = 0; - headerOffset = 0; - headerCRC = CrcCalc(0, 0); - } - else - { + CStartHeader sh; + sh.NextHeaderOffset = 0; + sh.NextHeaderSize = 0; + sh.NextHeaderCRC = 0; // CrcCalc(NULL, 0); + + if (!db.IsEmpty()) + { + CMyComPtr2_Create crcStream; + crcStream->SetStream(SeqStream); + crcStream->Init(); + bool encodeHeaders = false; - if (options != 0) + if (options) if (options->IsEmpty()) - options = 0; - if (options != 0) + options = NULL; + if (options) if (options->PasswordIsDefined || headerOptions.CompressMainHeader) encodeHeaders = true; - _outByte.SetStream(SeqStream); + if (!_outByte.Create(1 << 16)) + return E_OUTOFMEMORY; + _outByte.SetStream(crcStream.Interface()); _outByte.Init(); - _crc = CRC_INIT_VAL; + // _crc = CRC_INIT_VAL; _countMode = encodeHeaders; _writeToStream = true; _countSize = 0; - WriteHeader(db, /* headerOptions, */ headerOffset); + WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); if (encodeHeaders) { @@ -860,7 +925,7 @@ _countMode = false; _writeToStream = false; - WriteHeader(db, /* headerOptions, */ headerOffset); + WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); if (_countSize != _outByte2.GetPos()) return E_FAIL; @@ -876,7 +941,7 @@ RINOK(EncodeStream( EXTERNAL_CODECS_LOC_VARS encoder, buf, - packSizes, folders, outFolders)); + packSizes, folders, outFolders)) _writeToStream = true; @@ -884,17 +949,19 @@ throw 1; WriteID(NID::kEncodedHeader); - WritePackInfo(headerOffset, packSizes, CUInt32DefVector()); + WritePackInfo(sh.NextHeaderOffset, packSizes, CUInt32DefVector()); WriteUnpackInfo(folders, outFolders); WriteByte(NID::kEnd); - FOR_VECTOR (i, packSizes) - headerOffset += packSizes[i]; + + sh.NextHeaderOffset += UInt64Vector_CountSum(packSizes); } - RINOK(_outByte.Flush()); - headerCRC = CRC_GET_DIGEST(_crc); - headerSize = _outByte.GetProcessedSize(); + RINOK(_outByte.Flush()) + sh.NextHeaderCRC = crcStream->GetCRC(); + // sh.NextHeaderCRC = CRC_GET_DIGEST(_crc); + // if (CRC_GET_DIGEST(_crc) != sh.NextHeaderCRC) throw 1; + sh.NextHeaderSize = _outByte.GetProcessedSize(); } - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (_endMarker) { CFinishHeader h; @@ -910,14 +977,12 @@ } else #endif + if (Stream) { - CStartHeader h; - h.NextHeaderSize = headerSize; - h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = headerOffset; - RINOK(Stream->Seek((Int64)_prefixHeaderPos, STREAM_SEEK_SET, NULL)); - return WriteStartHeader(h); + RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) + return WriteStartHeader(sh); } + return S_OK; } void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zOut.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zOut.h 2016-12-18 09:41:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zOut.h 2023-11-25 15:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zOut.h -#ifndef __7Z_OUT_H -#define __7Z_OUT_H +#ifndef ZIP7_INC_7Z_OUT_H +#define ZIP7_INC_7Z_OUT_H #include "7zCompressionMode.h" #include "7zEncode.h" @@ -14,35 +14,46 @@ namespace NArchive { namespace N7z { +const unsigned k_StartHeadersRewriteSize = 32; + class CWriteBufferLoc { Byte *_data; - size_t _size; - size_t _pos; + Byte *_dataLim; + Byte *_dataBase; public: - CWriteBufferLoc(): _size(0), _pos(0) {} + // CWriteBufferLoc(): _data(NULL), _dataLim(NULL), _dataBase(NULL) {} void Init(Byte *data, size_t size) { _data = data; - _size = size; - _pos = 0; + _dataBase = data; + _dataLim = data + size; + } + + Byte *GetDest_and_Update(size_t size) + { + Byte *dest = _data; + if (size > (size_t)(_dataLim - dest)) + throw 1; + _data = dest + size; + return dest; } void WriteBytes(const void *data, size_t size) { if (size == 0) return; - if (size > _size - _pos) - throw 1; - memcpy(_data + _pos, data, size); - _pos += size; + Byte *dest = GetDest_and_Update(size); + memcpy(dest, data, size); } void WriteByte(Byte b) { - if (_size == _pos) + Byte *dest = _data; + if (dest == _dataLim) throw 1; - _data[_pos++] = b; + *dest++ = b; + _data = dest; } - size_t GetPos() const { return _pos; } + size_t GetPos() const { return (size_t)(_data - _dataBase); } }; @@ -240,22 +251,26 @@ class COutArchive { - UInt64 _prefixHeaderPos; - HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } UInt64 GetPos() const; void WriteBytes(const void *data, size_t size); void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } void WriteByte(Byte b); - void WriteUInt32(UInt32 value); - void WriteUInt64(UInt64 value); + void WriteByte_ToStream(Byte b) + { + _outByte.WriteByte(b); + // _crc = CRC_UPDATE_BYTE(_crc, b); + } + // void WriteUInt32(UInt32 value); + // void WriteUInt64(UInt64 value); void WriteNumber(UInt64 value); void WriteID(UInt64 value) { WriteNumber(value); } void WriteFolder(const CFolder &folder); HRESULT WriteFileHeader(const CFileItem &itemInfo); - void WriteBoolVector(const CBoolVector &boolVector); + void Write_BoolVector(const CBoolVector &boolVector); + void Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined); void WritePropBoolVector(Byte id, const CBoolVector &boolVector); void WriteHashDigests(const CUInt32DefVector &digests); @@ -277,7 +292,8 @@ void SkipToAligned(unsigned pos, unsigned alignShifts); void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts); - void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); + void Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined); + void Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type); HRESULT EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS @@ -290,44 +306,39 @@ bool _countMode; bool _writeToStream; - size_t _countSize; - UInt32 _crc; - COutBuffer _outByte; - CWriteBufferLoc _outByte2; - - #ifdef _7Z_VOL + bool _useAlign; + #ifdef Z7_7Z_VOL bool _endMarker; #endif + // UInt32 _crc; + size_t _countSize; + CWriteBufferLoc _outByte2; + COutBuffer _outByte; + UInt64 _signatureHeaderPos; + CMyComPtr Stream; - bool _useAlign; - - HRESULT WriteSignature(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL HRESULT WriteFinishSignature(); - #endif - HRESULT WriteStartHeader(const CStartHeader &h); - #ifdef _7Z_VOL HRESULT WriteFinishHeader(const CFinishHeader &h); #endif - CMyComPtr Stream; -public: + HRESULT WriteStartHeader(const CStartHeader &h); - COutArchive() { _outByte.Create(1 << 16); } +public: CMyComPtr SeqStream; - HRESULT Create(ISequentialOutStream *stream, bool endMarker); + + // COutArchive(); + HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */); void Close(); - HRESULT SkipPrefixArchiveHeader(); HRESULT WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS const CArchiveDatabaseOut &db, const CCompressionMethodMode *options, const CHeaderOptions &headerOptions); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); #endif - }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zProperties.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zProperties.cpp 2015-09-28 13:09:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.cpp 2023-03-29 09:00:00.000000000 +0000 @@ -2,56 +2,63 @@ #include "StdAfx.h" -#include "7zProperties.h" -#include "7zHeader.h" #include "7zHandler.h" - -// #define _MULTI_PACK +#include "7zProperties.h" namespace NArchive { namespace N7z { struct CPropMap { - UInt32 FilePropID; - CStatProp StatProp; + Byte FilePropID; + // CStatProp StatProp; + VARTYPE vt; + UInt32 StatPropID; }; -static const CPropMap kPropMap[] = -{ - { NID::kName, { NULL, kpidPath, VT_BSTR } }, - { NID::kSize, { NULL, kpidSize, VT_UI8 } }, - { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, - - #ifdef _MULTI_PACK - { 100, { "Pack0", kpidPackedSize0, VT_UI8 } }, - { 101, { "Pack1", kpidPackedSize1, VT_UI8 } }, - { 102, { "Pack2", kpidPackedSize2, VT_UI8 } }, - { 103, { "Pack3", kpidPackedSize3, VT_UI8 } }, - { 104, { "Pack4", kpidPackedSize4, VT_UI8 } }, - #endif +// #define STAT_PROP(name, id, vt) { name, id, vt } +#define STAT_PROP(name, id, vt) vt, id - { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, - { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } }, - { NID::kATime, { NULL, kpidATime, VT_FILETIME } }, - { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } }, - { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } }, +#define STAT_PROP2(id, vt) STAT_PROP(NULL, id, vt) - { NID::kCRC, { NULL, kpidCRC, VT_UI4 } }, - -// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } }, - { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } } +#define k_7z_id_Encrypted 97 +#define k_7z_id_Method 98 +#define k_7z_id_Block 99 - #ifndef _SFX - , - { 97, { NULL, kpidEncrypted, VT_BOOL } }, - { 98, { NULL, kpidMethod, VT_BSTR } }, - { 99, { NULL, kpidBlock, VT_UI4 } } +static const CPropMap kPropMap[] = +{ + { NID::kName, STAT_PROP2(kpidPath, VT_BSTR) }, + { NID::kSize, STAT_PROP2(kpidSize, VT_UI8) }, + { NID::kPackInfo, STAT_PROP2(kpidPackSize, VT_UI8) }, + + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES +#define k_7z_id_PackedSize0 100 + { k_7z_id_PackedSize0 + 0, STAT_PROP("Pack0", kpidPackedSize0, VT_UI8) }, + { k_7z_id_PackedSize0 + 1, STAT_PROP("Pack1", kpidPackedSize1, VT_UI8) }, + { k_7z_id_PackedSize0 + 2, STAT_PROP("Pack2", kpidPackedSize2, VT_UI8) }, + { k_7z_id_PackedSize0 + 3, STAT_PROP("Pack3", kpidPackedSize3, VT_UI8) }, + { k_7z_id_PackedSize0 + 4, STAT_PROP("Pack4", kpidPackedSize4, VT_UI8) }, + #endif + + { NID::kCTime, STAT_PROP2(kpidCTime, VT_FILETIME) }, + { NID::kMTime, STAT_PROP2(kpidMTime, VT_FILETIME) }, + { NID::kATime, STAT_PROP2(kpidATime, VT_FILETIME) }, + { NID::kWinAttrib, STAT_PROP2(kpidAttrib, VT_UI4) }, + { NID::kStartPos, STAT_PROP2(kpidPosition, VT_UI8) }, + + { NID::kCRC, STAT_PROP2(kpidCRC, VT_UI4) }, + // { NID::kIsAux, STAT_PROP2(kpidIsAux, VT_BOOL) }, + { NID::kAnti, STAT_PROP2(kpidIsAnti, VT_BOOL) } + + #ifndef Z7_SFX + , { k_7z_id_Encrypted, STAT_PROP2(kpidEncrypted, VT_BOOL) } + , { k_7z_id_Method, STAT_PROP2(kpidMethod, VT_BSTR) } + , { k_7z_id_Block, STAT_PROP2(kpidBlock, VT_UI4) } #endif }; static void CopyOneItem(CRecordVector &src, - CRecordVector &dest, UInt32 item) + CRecordVector &dest, const UInt32 item) { FOR_VECTOR (i, src) if (src[i] == item) @@ -62,7 +69,7 @@ } } -static void RemoveOneItem(CRecordVector &src, UInt32 item) +static void RemoveOneItem(CRecordVector &src, const UInt32 item) { FOR_VECTOR (i, src) if (src[i] == item) @@ -72,7 +79,7 @@ } } -static void InsertToHead(CRecordVector &dest, UInt32 item) +static void InsertToHead(CRecordVector &dest, const UInt32 item) { FOR_VECTOR (i, dest) if (dest[i] == item) @@ -89,7 +96,7 @@ { _fileInfoPopIDs.Clear(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (_volumes.Size() < 1) return; const CVolume &volume = _volumes.Front(); @@ -105,34 +112,31 @@ RemoveOneItem(fileInfoPopIDs, NID::kNtSecure); */ - COPY_ONE_ITEM(kName); - COPY_ONE_ITEM(kAnti); - COPY_ONE_ITEM(kSize); - COPY_ONE_ITEM(kPackInfo); - COPY_ONE_ITEM(kCTime); - COPY_ONE_ITEM(kMTime); - COPY_ONE_ITEM(kATime); - COPY_ONE_ITEM(kWinAttrib); - COPY_ONE_ITEM(kCRC); - COPY_ONE_ITEM(kComment); + COPY_ONE_ITEM(kName) + COPY_ONE_ITEM(kAnti) + COPY_ONE_ITEM(kSize) + COPY_ONE_ITEM(kPackInfo) + COPY_ONE_ITEM(kCTime) + COPY_ONE_ITEM(kMTime) + COPY_ONE_ITEM(kATime) + COPY_ONE_ITEM(kWinAttrib) + COPY_ONE_ITEM(kCRC) + COPY_ONE_ITEM(kComment) _fileInfoPopIDs += fileInfoPopIDs; - #ifndef _SFX - _fileInfoPopIDs.Add(97); - _fileInfoPopIDs.Add(98); - _fileInfoPopIDs.Add(99); + #ifndef Z7_SFX + _fileInfoPopIDs.Add(k_7z_id_Encrypted); + _fileInfoPopIDs.Add(k_7z_id_Method); + _fileInfoPopIDs.Add(k_7z_id_Block); #endif - #ifdef _MULTI_PACK - _fileInfoPopIDs.Add(100); - _fileInfoPopIDs.Add(101); - _fileInfoPopIDs.Add(102); - _fileInfoPopIDs.Add(103); - _fileInfoPopIDs.Add(104); + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES + for (unsigned i = 0; i < 5; i++) + _fileInfoPopIDs.Add(k_7z_id_PackedSize0 + i); #endif - #ifndef _SFX + #ifndef Z7_SFX InsertToHead(_fileInfoPopIDs, NID::kMTime); InsertToHead(_fileInfoPopIDs, NID::kPackInfo); InsertToHead(_fileInfoPopIDs, NID::kSize); @@ -140,25 +144,29 @@ #endif } -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) { *numProps = _fileInfoPopIDs.Size(); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) { if (index >= _fileInfoPopIDs.Size()) return E_INVALIDARG; - UInt64 id = _fileInfoPopIDs[index]; - for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++) + const UInt64 id = _fileInfoPopIDs[index]; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPropMap); i++) { const CPropMap &pr = kPropMap[i]; if (pr.FilePropID == id) { + *propID = pr.StatPropID; + *varType = pr.vt; + /* const CStatProp &st = pr.StatProp; *propID = st.PropID; *varType = st.vt; + */ /* if (st.lpwstrName) *name = ::SysAllocString(st.lpwstrName); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zProperties.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zProperties.h 2008-08-06 08:30:47.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zProperties.h 2023-03-29 09:00:00.000000000 +0000 @@ -1,13 +1,16 @@ // 7zProperties.h -#ifndef __7Z_PROPERTIES_H -#define __7Z_PROPERTIES_H +#ifndef ZIP7_INC_7Z_PROPERTIES_H +#define ZIP7_INC_7Z_PROPERTIES_H #include "../../PropID.h" namespace NArchive { namespace N7z { +// #define Z7_7Z_SHOW_PACK_STREAMS_SIZES // for debug + +#ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES enum { kpidPackedSize0 = kpidUserDefined, @@ -16,6 +19,7 @@ kpidPackedSize3, kpidPackedSize4 }; +#endif }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zRegister.cpp 2022-05-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zRegister.cpp 2022-08-17 05:00:00.000000000 +0000 @@ -22,6 +22,6 @@ | NArcInfoFlags::kMTime_Default , TIME_PREC_TO_ARC_FLAGS_MASK(NFileTimeType::kWindows) | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(NFileTimeType::kWindows) - , NULL); + , NULL) }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.cpp 2012-11-17 06:57:34.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.cpp 2023-03-29 06:00:00.000000000 +0000 @@ -4,19 +4,28 @@ #include "7zSpecStream.h" -STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) +/* +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); + const HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; return result; } -STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { if (!_getSubStreamSize) return E_NOTIMPL; return _getSubStreamSize->GetSubStreamSize(subStream, value); } + +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +{ + if (!_compressGetSubStreamSize) + return E_NOTIMPL; + return _compressGetSubStreamSize->GetNextInSubStream(streamIndexRes, stream); +} +*/ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.h 2014-12-21 15:31:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zSpecStream.h 2023-03-29 06:00:00.000000000 +0000 @@ -1,35 +1,49 @@ // 7zSpecStream.h -#ifndef __7Z_SPEC_STREAM_H -#define __7Z_SPEC_STREAM_H +#ifndef ZIP7_INC_7Z_SPEC_STREAM_H +#define ZIP7_INC_7Z_SPEC_STREAM_H #include "../../../Common/MyCom.h" #include "../../ICoder.h" -class CSequentialInStreamSizeCount2: +/* +#define Z7_COM_QI_ENTRY_AG_2(i, sub0, sub) else if (iid == IID_ ## i) \ + { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ + { i *ti = this; *outObject = ti; } } + +class CSequentialInStreamSizeCount2 Z7_final: public ISequentialInStream, public ICompressGetSubStreamSize, + public ICompressInSubStreams, public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressGetSubStreamSize) + Z7_COM_QI_ENTRY_AG_2(ISequentialInStream, _stream, _compressGetSubStreamSize) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressGetSubStreamSize) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + CMyComPtr _stream; CMyComPtr _getSubStreamSize; + CMyComPtr _compressGetSubStreamSize; UInt64 _size; public: void Init(ISequentialInStream *stream) { _size = 0; _getSubStreamSize.Release(); + _compressGetSubStreamSize.Release(); _stream = stream; _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); + _stream.QueryInterface(IID_ICompressInSubStreams, &_compressGetSubStreamSize); } UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); }; +*/ #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.cpp 2022-05-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.cpp 2024-06-19 05:00:00.000000000 +0000 @@ -4,6 +4,8 @@ #include "../../../../C/CpuArch.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringToInt.h" #include "../../../Common/Wildcard.h" #include "../../Common/CreateCoder.h" @@ -24,24 +26,43 @@ namespace NArchive { namespace N7z { - #define k_X86 k_BCJ struct CFilterMode { UInt32 Id; - UInt32 Delta; - - CFilterMode(): Id(0), Delta(0) {} + UInt32 Delta; // required File Size alignment, if Id is not k_Delta. + // (Delta == 0) means unknown alignment + UInt32 Offset; // for k_ARM64 / k_RISCV + // UInt32 AlignSizeOpt; // for k_ARM64 + + CFilterMode(): + Id(0), + Delta(0), + Offset(0) + // , AlignSizeOpt(0) + {} + + void ClearFilterMode() + { + Id = 0; + Delta = 0; + Offset = 0; + // AlignSizeOpt = 0; + } + // it sets Delta as Align value, if Id is exe filter + // in another cases it sets Delta = 0, that void SetDelta() { if (Id == k_IA64) Delta = 16; - else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC) + else if (Id == k_ARM64 || Id == k_ARM || Id == k_PPC || Id == k_SPARC) Delta = 4; - else if (Id == k_ARMT) + else if (Id == k_ARMT || Id == k_RISCV) Delta = 2; + else if (Id == k_BCJ || Id == k_BCJ2) + Delta = 1; // do we need it? else Delta = 0; } @@ -74,10 +95,13 @@ return 0; p += 4; - switch (GetUi16(p)) + const unsigned machine = GetUi16(p); + + switch (machine) { case 0x014C: case 0x8664: filterId = k_X86; break; + case 0xAA64: filterId = k_ARM64; break; /* IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE @@ -90,10 +114,16 @@ case 0x01C2: filterId = k_ARM; break; // WinCE new case 0x01C4: filterId = k_ARMT; break; // WinRT + case 0x5032: // RISCV32 + case 0x5064: // RISCV64 + // case 0x5128: // RISCV128 + filterId = k_RISCV; break; + case 0x0200: filterId = k_IA64; break; default: return 0; } + const UInt32 numSections = GetUi16(p + 2); optHeaderSize = GetUi16(p + 16); if (optHeaderSize > (1 << 10)) return 0; @@ -109,11 +139,94 @@ return 0; } + // Windows exe file sizes are not aligned for 4 KiB. + // So we can't use (CFilterMode::Offset != 0) in solid archives. + // So we just don't set Offset here. +#define NUM_SCAN_SECTIONS_MAX (1 << 6) +// #define EXE_SECTION_OFFSET_MAX (1 << 27) +// #define EXE_SECTION_SIZE_MIN (1 << 8) +// #define EXE_SECTION_SIZE_MAX (1 << 27) +#define PE_SectHeaderSize 40 +// #define PE_SECT_EXECUTE 0x20000000 + +/* + if (numSections > NUM_SCAN_SECTIONS_MAX) + return 0; +*/ + + if ((size_t)(p - buf) + optHeaderSize <= size) + { + p += optHeaderSize; +/* + // UInt32 numExeSections = 0; + // bool execute_finded = false; + // UInt32 sect_va = 0; + // UInt32 sect_size = 0; + // UInt32 sect_offset = 0; +*/ + if (numSections <= NUM_SCAN_SECTIONS_MAX) + if (machine == 0x8664) + for (UInt32 i = 0; i < numSections + ; i++, p += PE_SectHeaderSize) + { + // UInt32 characts, rawSize, offset; + if ((UInt32)(p - buf) + PE_SectHeaderSize > size) + { + // return 0; + break; + } + if (memcmp(p, ".a64xrm", 8) == 0) + { + // ARM64EC + filterId = k_ARM64; + break; + } +/* + rawSize = GetUi32(p + 16); + offset = GetUi32(p + 20); + characts = GetUi32(p + 36); + if (rawSize >= EXE_SECTION_SIZE_MIN && + rawSize <= EXE_SECTION_SIZE_MAX && + offset <= EXE_SECTION_OFFSET_MAX && + // offset < limit && + offset > 0) + { + if ((characts & PE_SECT_EXECUTE) != 0) + { + // execute_finded = true; + // sect_va = GetUi32(p + 12); + // sect_size = rawSize; + // sect_offset = offset; + break; + } + } +*/ + } + } + + /* + filterMode->Offset = 0; + if (filterId == k_ARM64) + { + // filterMode->AlignSizeOpt = (1 << 12); + // const UInt32 offs = (sect_va - sect_offset) & 0xFFF; + // if (offs != 0) + // filterMode->Offset = offs; // change it + } + */ filterMode->Id = filterId; return 1; } +/* + Filters don't improve the compression ratio for relocatable object files (".o"). + But we can get compression ratio gain, if we compress object + files and executables in same solid block. + So we use filters for relocatable object files (".o"): +*/ +// #define Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ + /* ---------- ELF ---------- */ #define ELF_SIG 0x464C457F @@ -153,6 +266,12 @@ default: return 0; } +#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ +#define ELF_ET_REL 1 + if (Get16(buf + 0x10, be) == ELF_ET_REL) + return 0; +#endif + switch (Get16(buf + 0x12, be)) { case 3: @@ -163,9 +282,11 @@ case 43: filterId = k_SPARC; break; case 20: case 21: if (!be) return 0; filterId = k_PPC; break; - case 40: if ( be) return 0; filterId = k_ARM; break; - - /* Some IA-64 ELF exacutable have size that is not aligned for 16 bytes. + case 40: if (be) return 0; filterId = k_ARM; break; + case 183: if (be) return 0; filterId = k_ARM64; break; + case 243: if (be) return 0; filterId = k_RISCV; break; + + /* Some IA-64 ELF executables have size that is not aligned for 16 bytes. So we don't use IA-64 filter for IA-64 ELF */ // case 50: if ( be) return 0; filterId = k_IA64; break; @@ -192,6 +313,7 @@ #define MACH_MACHINE_PPC 18 #define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) #define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) +#define MACH_MACHINE_ARM64 (MACH_ARCH_ABI64 | MACH_MACHINE_ARM) static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode) { @@ -210,6 +332,12 @@ default: return 0; } +#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ +#define MACH_TYPE_OBJECT 1 + if (Get32(buf + 0xC, be) == MACH_TYPE_OBJECT) + return 0; +#endif + switch (Get32(buf + 4, be)) { case MACH_MACHINE_386: @@ -218,6 +346,7 @@ case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break; case MACH_MACHINE_PPC: case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break; + case MACH_MACHINE_ARM64: if ( be) return 0; filterId = k_ARM64; break; default: return 0; } @@ -284,10 +413,15 @@ return False; } + +/* + filterMode->Delta will be set as: + = delta value : [1, 256] : for k_Delta + = 0 for another filters (branch filters) +*/ static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) { - filterMode->Id = 0; - filterMode->Delta = 0; + filterMode->ClearFilterMode(); if (Parse_EXE(buf, size, filterMode)) return True; if (Parse_ELF(buf, size, filterMode)) return True; @@ -315,18 +449,44 @@ else if (!m.Encrypted) return 1; - if (Id < m.Id) return -1; - if (Id > m.Id) return 1; + const UInt32 id1 = Id; + const UInt32 id2 = m.Id; + /* + // we can change the order to place k_ARM64 files close to another exe files + if (id1 <= k_SPARC && + id2 <= k_SPARC) + { + #define k_ARM64_FOR_SORT 0x3030901 + if (id1 == k_ARM64) id1 = k_ARM64_FOR_SORT; + if (id2 == k_ARM64) id2 = k_ARM64_FOR_SORT; + } + */ + if (id1 < id2) return -1; + if (id1 > id2) return 1; if (Delta < m.Delta) return -1; if (Delta > m.Delta) return 1; + if (Offset < m.Offset) return -1; + if (Offset > m.Offset) return 1; + + /* we don't go here, because GetGroup() + and operator ==(const CFilterMode2 &m) + add only unique CFilterMode2:: { Id, Delta, Offset, Encrypted } items. + */ + /* + if (GroupIndex < m.GroupIndex) return -1; + if (GroupIndex > m.GroupIndex) return 1; + */ return 0; } bool operator ==(const CFilterMode2 &m) const { - return Id == m.Id && Delta == m.Delta && Encrypted == m.Encrypted; + return Id == m.Id + && Delta == m.Delta + && Offset == m.Offset + && Encrypted == m.Encrypted; } }; @@ -367,6 +527,8 @@ { switch (m) { + case k_ARM64: + case k_RISCV: case k_BCJ: case k_BCJ2: case k_ARM: @@ -375,6 +537,7 @@ case k_SPARC: case k_IA64: return true; + default: break; } return false; } @@ -383,8 +546,9 @@ CRecordVector &filters, const CFolderEx &f, bool extractFilter) { CFilterMode2 m; - m.Id = 0; - m.Delta = 0; + // m.Id = 0; + // m.Delta = 0; + // m.Offset = 0; m.Encrypted = f.IsEncrypted(); if (extractFilter) @@ -405,6 +569,10 @@ if (m.Id == k_BCJ2) m.Id = k_BCJ; m.SetDelta(); + if (m.Id == k_ARM64 || + m.Id == k_RISCV) + if (coder.Props.Size() == 4) + m.Offset = GetUi32(coder.Props); } } @@ -417,16 +585,13 @@ static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, UInt64 position, UInt64 size, ICompressProgressInfo *progress) { - RINOK(inStream->Seek((Int64)position, STREAM_SEEK_SET, 0)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLimited(streamSpec); + RINOK(InStream_SeekSet(inStream, position)) + CMyComPtr2_Create streamSpec; streamSpec->SetStream(inStream); streamSpec->Init(size); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL); + CMyComPtr2_Create copyCoder; + RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, progress)) + return (copyCoder->TotalSize == size ? S_OK : E_FAIL); } /* @@ -445,7 +610,7 @@ } */ -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; } #define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b)) @@ -630,7 +795,7 @@ unsigned NamePos; unsigned ExtensionIndex; - CRefItem() {}; + CRefItem() {} CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): UpdateItem(&ui), Index(index), @@ -640,9 +805,9 @@ { if (sortByType) { - int slashPos = ui.Name.ReverseFind_PathSepar(); + const int slashPos = ui.Name.ReverseFind_PathSepar(); NamePos = (unsigned)(slashPos + 1); - int dotPos = ui.Name.ReverseFind_Dot(); + const int dotPos = ui.Name.ReverseFind_Dot(); if (dotPos <= slashPos) ExtensionPos = ui.Name.Len(); else @@ -653,7 +818,7 @@ AString s; for (unsigned pos = ExtensionPos;; pos++) { - wchar_t c = ui.Name[pos]; + const wchar_t c = ui.Name[pos]; if (c >= 0x80) break; if (c == 0) @@ -661,7 +826,7 @@ ExtensionIndex = GetExtIndex(s); break; } - s += (char)MyCharLower_Ascii((char)c); + s.Add_Char((char)MyCharLower_Ascii((char)c)); } } } @@ -710,16 +875,16 @@ // bool sortByType = *(bool *)param; const CSortParam *sortParam = (const CSortParam *)param; - bool sortByType = sortParam->SortByType; + const bool sortByType = sortParam->SortByType; if (sortByType) { - RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))); + RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))) if (!u1.MTimeDefined && u2.MTimeDefined) return 1; if (u1.MTimeDefined && !u2.MTimeDefined) return -1; - if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime); - RINOZ_COMP(u1.Size, u2.Size); + if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime) + RINOZ_COMP(u1.Size, u2.Size) } /* int par1 = a1.UpdateItem->ParentFolderIndex; @@ -765,9 +930,9 @@ } */ // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex); - RINOK(CompareFileNames(u1.Name, u2.Name)); - RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient); - RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive); + RINOK(CompareFileNames(u1.Name, u2.Name)) + RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient) + RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive) return 0; } @@ -778,7 +943,7 @@ CRecordVector folderRefs; }; -static const char * const g_ExeExts[] = +static const char * const g_Exe_Exts[] = { "dll" , "exe" @@ -787,13 +952,64 @@ , "sys" }; -static bool IsExeExt(const wchar_t *ext) +static const char * const g_ExeUnix_Exts[] = +{ + "so" + , "dylib" +}; + +static bool IsExt_Exe(const wchar_t *ext) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exe_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_Exe_Exts[i])) + return true; + return false; +} + +/* +static bool IsExt_ExeUnix(const wchar_t *ext) { - for (unsigned i = 0; i < ARRAY_SIZE(g_ExeExts); i++) - if (StringsAreEqualNoCase_Ascii(ext, g_ExeExts[i])) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_ExeUnix_Exts[i])) return true; return false; } +*/ + +// we try to find "so" extension in such name: libstdc++.so.6.0.29 +static bool IsExt_ExeUnix_NumericAllowed(const UString &path) +{ + unsigned pos = path.Len(); + unsigned dotPos = pos; + for (;;) + { + if (pos == 0) + return false; + const wchar_t c = path[--pos]; + if (IS_PATH_SEPAR(c)) + return false; + if (c == '.') + { + const unsigned num = (dotPos - pos) - 1; + if (num < 1) + return false; + const wchar_t *cur = path.Ptr(pos + 1); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + { + const char *ext = g_ExeUnix_Exts[i]; + if (num == MyStringLen(ext)) + if (IsString1PrefixedByString2_NoCase_Ascii(cur, ext)) + return true; + } + const wchar_t *end; + ConvertStringToUInt32(cur, &end); + if ((size_t)(end - cur) != num) + return false; + dotPos = pos; + } + } +} + struct CAnalysis { @@ -802,6 +1018,8 @@ bool ParseWav; bool ParseExe; + bool ParseExeUnix; + bool ParseNoExt; bool ParseAll; /* @@ -811,8 +1029,10 @@ */ CAnalysis(): - ParseWav(true), + ParseWav(false), ParseExe(false), + ParseExeUnix(false), + ParseNoExt(false), ParseAll(false) /* , Need_ATime(false) @@ -829,32 +1049,46 @@ { filterMode.Id = 0; filterMode.Delta = 0; + filterMode.Offset = 0; CFilterMode filterModeTemp = filterMode; - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); // if (dotPos > slashPos) { bool needReadFile = ParseAll; - + /* if (Callback) is not supported by client, + we still try to use file name extension to detect executable file */ bool probablyIsSameIsa = false; if (!needReadFile || !Callback) { - const wchar_t *ext; + const wchar_t *ext = NULL; if (dotPos > slashPos) ext = ui.Name.Ptr((unsigned)(dotPos + 1)); - else - ext = ui.Name.RightPtr(0); - - // p7zip uses the trick to store posix attributes in high 16 bits + // 7-zip stores posix attributes in high 16 bits and sets (0x8000) flag if (ui.Attrib & 0x8000) { - unsigned st_mode = ui.Attrib >> 16; - // st_mode = 00111; - if ((st_mode & 00111) && (ui.Size >= 2048)) + const unsigned st_mode = ui.Attrib >> 16; + /* note: executable ".so" can be without execute permission, + and symbolic link to such ".so" file is possible */ + // st_mode = 00111; // for debug + /* in Linux we expect such permissions: + 0755 : for most executables + 0644 : for some ".so" files + 0777 : in WSL for all files. + We can try to exclude some such 0777 cases from analysis, + if there is non-executable extension. + */ + + if ((st_mode & ( + MY_LIN_S_IXUSR | + MY_LIN_S_IXGRP | + MY_LIN_S_IXOTH)) != 0 + && MY_LIN_S_ISREG(st_mode) + && (ui.Size >= (1u << 11))) { #ifndef _WIN32 probablyIsSameIsa = true; @@ -863,36 +1097,45 @@ } } - if (IsExeExt(ext)) - { - needReadFile = true; - #ifdef _WIN32 - probablyIsSameIsa = true; - needReadFile = ParseExe; - #endif - } - else if (StringsAreEqualNoCase_Ascii(ext, "wav")) + if (!needReadFile) { - needReadFile = ParseWav; - } - /* - else if (!needReadFile && ParseUnixExt) - { - if (StringsAreEqualNoCase_Ascii(ext, "so") - || StringsAreEqualNoCase_Ascii(ext, "")) - - needReadFile = true; + if (!ext) + needReadFile = ParseNoExt; + else + { + bool isUnixExt = false; + if (ParseExeUnix) + isUnixExt = IsExt_ExeUnix_NumericAllowed(ui.Name); + if (isUnixExt) + { + needReadFile = true; + #ifndef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (IsExt_Exe(ext)) + { + needReadFile = ParseExe; + #ifdef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (StringsAreEqualNoCase_Ascii(ext, "wav")) + { + if (!needReadFile) + needReadFile = ParseWav; + } + } } - */ } - if (needReadFile && Callback) + if (needReadFile) { - if (Buffer.Size() != kAnalysisBufSize) - { - Buffer.Alloc(kAnalysisBufSize); - } + BoolInt parseRes = false; + if (Callback) { + if (Buffer.Size() != kAnalysisBufSize) + Buffer.Alloc(kAnalysisBufSize); CMyComPtr stream; HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze); if (result == S_OK && stream) @@ -908,40 +1151,66 @@ ATime_Defined = true; } */ - size_t size = kAnalysisBufSize; result = ReadStream(stream, Buffer, &size); stream.Release(); // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK)); if (result == S_OK) { - BoolInt parseRes = ParseFile(Buffer, size, &filterModeTemp); - if (parseRes && filterModeTemp.Delta == 0) - { - filterModeTemp.SetDelta(); - if (filterModeTemp.Delta != 0 && filterModeTemp.Id != k_Delta) - { - if (ui.Size % filterModeTemp.Delta != 0) - { - parseRes = false; - } - } - } - if (!parseRes) + parseRes = ParseFile(Buffer, size, &filterModeTemp); + } + } + } // Callback + else if (probablyIsSameIsa) + { + #ifdef MY_CPU_X86_OR_AMD64 + filterModeTemp.Id = k_X86; + #endif + #ifdef MY_CPU_ARM64 + filterModeTemp.Id = k_ARM64; + #endif + #ifdef MY_CPU_RISCV + filterModeTemp.Id = k_RISCV; + #endif + #ifdef MY_CPU_SPARC + filterModeTemp.Id = k_SPARC; + #endif + parseRes = true; + } + + if (parseRes + && filterModeTemp.Id != k_Delta + && filterModeTemp.Delta == 0) + { + /* ParseFile() sets (filterModeTemp.Delta == 0) for all + methods except of k_Delta. */ + // it's not k_Delta + // So we call SetDelta() to set Delta + filterModeTemp.SetDelta(); + if (filterModeTemp.Delta > 1) + { + /* If file Size is not aligned, then branch filter + will not work for next file in solid block. + Maybe we should allow filter for non-aligned-size file in non-solid archives ? + */ + if (ui.Size % filterModeTemp.Delta != 0) + parseRes = false; + // windows exe files are not aligned for 4 KiB. + /* + else if (filterModeTemp.Id == k_ARM64 && filterModeTemp.Offset != 0) + { + if (ui.Size % (1 << 12) != 0) { - filterModeTemp.Id = 0; - filterModeTemp.Delta = 0; + // If Size is not aligned for 4 KiB, then Offset will not work for next file in solid block. + // so we place such file in group with (Offset==0). + filterModeTemp.Offset = 0; } } + */ } } - } - else if ((needReadFile && !Callback) || probablyIsSameIsa) - { - #ifdef MY_CPU_X86_OR_AMD64 - if (probablyIsSameIsa) - filterModeTemp.Id = k_X86; - #endif + if (!parseRes) + filterModeTemp.ClearFilterMode(); } } @@ -955,6 +1224,8 @@ m.NumStreams = numStreams; } + +// we add bond for mode.Methods[0] that is filter static HRESULT AddBondForFilter(CCompressionMethodMode &mode) { for (unsigned c = 1; c < mode.Methods.Size(); c++) @@ -972,16 +1243,19 @@ return E_INVALIDARG; } -static HRESULT AddFilterBond(CCompressionMethodMode &mode) +/* +static HRESULT AddBondForFilter_if_ThereAreBonds(CCompressionMethodMode &mode) { if (!mode.Bonds.IsEmpty()) return AddBondForFilter(mode); return S_OK; } +*/ static HRESULT AddBcj2Methods(CCompressionMethodMode &mode) { // mode.Methods[0] must be k_BCJ2 method ! + // mode.Methods[1] : we expect that there is at least one method after BCJ2 CMethodFull m; GetMethodFull(k_LZMA, 1, m); @@ -993,7 +1267,7 @@ m.AddProp32(NCoderPropID::kLitContextBits, 0); // m.AddProp_Ascii(NCoderPropID::kMatchFinder, "BT2"); - unsigned methodIndex = mode.Methods.Size(); + const unsigned methodIndex = mode.Methods.Size(); if (mode.Bonds.IsEmpty()) { @@ -1010,102 +1284,142 @@ mode.Methods.Add(m); mode.Methods.Add(m); - RINOK(AddBondForFilter(mode)); + RINOK(AddBondForFilter(mode)) CBond2 bond; - bond.OutCoder = 0; + bond.OutCoder = 0; // index of BCJ2 coder bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond); bond.InCoder = methodIndex + 1; bond.OutStream = 2; mode.Bonds.Add(bond); return S_OK; } + static HRESULT MakeExeMethod(CCompressionMethodMode &mode, - const CFilterMode &filterMode, /* bool addFilter, */ bool bcj2Filter) + const CFilterMode &filterMode, + const bool bcj2_IsAllowed, + const CUIntVector &disabledFilterIDs) { if (mode.Filter_was_Inserted) { + // filter was inserted, but bond for that filter was not added still. const CMethodFull &m = mode.Methods[0]; - CMethodId id = m.Id; - if (id == k_BCJ2) + if (m.Id == k_BCJ2) return AddBcj2Methods(mode); if (!m.IsSimpleCoder()) return E_NOTIMPL; - // if (Bonds.IsEmpty()) we can create bonds later - return AddFilterBond(mode); + if (mode.Bonds.IsEmpty()) + return S_OK; + return AddBondForFilter(mode); } if (filterMode.Id == 0) return S_OK; - CMethodFull &m = mode.Methods.InsertNew(0); + unsigned nextCoder; - { - FOR_VECTOR(k, mode.Bonds) - { - CBond2 &bond = mode.Bonds[k]; - bond.InCoder++; - bond.OutCoder++; - } - } - - HRESULT res; - - if (bcj2Filter && Is86Filter(filterMode.Id)) - { - GetMethodFull(k_BCJ2, 4, m); - res = AddBcj2Methods(mode); + const bool useBcj2 = bcj2_IsAllowed + && Is86Filter(filterMode.Id) + && disabledFilterIDs.FindInSorted(k_BCJ2) < 0; + + if (!useBcj2 && disabledFilterIDs.FindInSorted(filterMode.Id) >= 0) + { + // required filter is disabled, + // but we still can use information about data alignment. +#if 0 // 1 for debug + // we can return here, if we want default lzma properties + return S_OK; +#else + // we will try to change lzma/lzma2 properties + nextCoder = 0; + if (!mode.Bonds.IsEmpty()) + for (unsigned c = 0;; c++) + { + if (c == mode.Methods.Size()) + return S_OK; + if (!mode.IsThereBond_to_Coder(c)) + { + nextCoder = c; + break; + } + } +#endif } else { + // we insert new filter method: + CMethodFull &m = mode.Methods.InsertNew(0); // 0 == index of new inserted item + { + // we move all coder indexes in bonds up for 1 position: + FOR_VECTOR (k, mode.Bonds) + { + CBond2 &bond = mode.Bonds[k]; + bond.InCoder++; + bond.OutCoder++; + } + } + if (useBcj2) + { + GetMethodFull(k_BCJ2, 4, m); + return AddBcj2Methods(mode); + } + GetMethodFull(filterMode.Id, 1, m); + if (filterMode.Id == k_Delta) m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta); - res = AddFilterBond(mode); - - int alignBits = -1; - if (filterMode.Id == k_Delta || filterMode.Delta != 0) + else if (filterMode.Id == k_ARM64 + || filterMode.Id == k_RISCV) { - if (filterMode.Delta == 1) alignBits = 0; - else if (filterMode.Delta == 2) alignBits = 1; - else if (filterMode.Delta == 4) alignBits = 2; - else if (filterMode.Delta == 8) alignBits = 3; - else if (filterMode.Delta == 16) alignBits = 4; - } - else - { - // alignBits = GetAlignForFilterMethod(filterMode.Id); + // if (filterMode.Offset != 0) + m.AddProp32( + NCoderPropID::kDefaultProp, + // NCoderPropID::kBranchOffset, + filterMode.Offset); } - if (res == S_OK && alignBits >= 0) + nextCoder = 1; + if (!mode.Bonds.IsEmpty()) { - unsigned nextCoder = 1; - if (!mode.Bonds.IsEmpty()) - { - nextCoder = mode.Bonds.Back().InCoder; - } - if (nextCoder < mode.Methods.Size()) - { - CMethodFull &nextMethod = mode.Methods[nextCoder]; - if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2) - { - if (!nextMethod.Are_Lzma_Model_Props_Defined()) - { - if (alignBits != 0) - { - if (alignBits > 2 || filterMode.Id == k_Delta) - nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits); - unsigned lc = 0; - if (alignBits < 3) - lc = (unsigned)(3 - alignBits); - nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc); - nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits); - } - } - } - } + RINOK(AddBondForFilter(mode)) + nextCoder = mode.Bonds.Back().InCoder; } } - return res; + if (nextCoder >= mode.Methods.Size()) + { + // we don't expect that case, if there was non-filter method. + // but we return S_OK to support filter-only case. + return S_OK; + } + + int alignBits = -1; + { + const UInt32 delta = filterMode.Delta; + if (delta == 0 || delta > 16) + { + // if (delta == 0) alignBits = GetAlignForFilterMethod(filterMode.Id); + } + else if ((delta & ((1 << 4) - 1)) == 0) alignBits = 4; + else if ((delta & ((1 << 3) - 1)) == 0) alignBits = 3; + else if ((delta & ((1 << 2) - 1)) == 0) alignBits = 2; + else if ((delta & ((1 << 1) - 1)) == 0) alignBits = 1; + // else alignBits = 0; + /* alignBits=0 is default mode for lzma/lzma2. + So we don't set alignBits=0 here. */ + } + if (alignBits <= 0) + return S_OK; + // (alignBits > 0) + CMethodFull &nextMethod = mode.Methods[nextCoder]; + if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2) + if (!nextMethod.Are_Lzma_Model_Props_Defined()) + { + if (alignBits > 2 || filterMode.Id == k_Delta) + nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits); + const unsigned lc = (alignBits < 3) ? (unsigned)(3 - alignBits) : 0u; + nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc); + nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits); + } + return S_OK; } @@ -1135,13 +1449,13 @@ -class CRepackInStreamWithSizes: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + CRepackInStreamWithSizes + , ISequentialInStream + , ICompressGetSubStreamSize +) CMyComPtr _stream; - // UInt64 _size; + UInt64 _size; const CBoolVector *_extractStatuses; UInt32 _startIndex; public: @@ -1151,37 +1465,28 @@ { _startIndex = startIndex; _extractStatuses = extractStatuses; - // _size = 0; + _size = 0; _stream = stream; } - // UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); + UInt64 GetSize() const { return _size; } }; -STDMETHODIMP CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize)) { - return _stream->Read(data, size, processedSize); - /* UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); + const HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; return result; - */ } -STDMETHODIMP CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { *value = 0; if (subStream >= _extractStatuses->Size()) return S_FALSE; // E_FAIL; - unsigned index = (unsigned)subStream; + const unsigned index = (unsigned)subStream; if ((*_extractStatuses)[index]) { const CFileItem &fi = _db->Files[_startIndex + index]; @@ -1212,7 +1517,7 @@ public: const CDbEx *_db; CMyComPtr _opCallback; - CMyComPtr _extractCallback; + CMyComPtr _extractCallback; HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses); HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; } @@ -1241,7 +1546,7 @@ NEventIndexType::kInArcIndex, arcIndex, _needWrite ? NUpdateNotifyOp::kRepack : - NUpdateNotifyOp::kSkip)); + NUpdateNotifyOp::kSkip)) } _crc = CRC_INIT_VAL; @@ -1267,7 +1572,7 @@ { RINOK(_extractCallback->ReportExtractResult( NEventIndexType::kInArcIndex, arcIndex, - NExtract::NOperationResult::kCRCError)); + NExtract::NOperationResult::kCRCError)) } // return S_FALSE; return k_My_HRESULT_CRC_ERROR; @@ -1277,30 +1582,28 @@ { while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0) { - RINOK(OpenFile()); - RINOK(CloseFile()); + RINOK(OpenFile()) + RINOK(CloseFile()) } return S_OK; } -#ifndef _7ZIP_ST +#ifndef Z7_ST -class CFolderOutStream2: +class CFolderOutStream2 Z7_final: public CRepackStreamBase, public ISequentialOutStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) public: CMyComPtr _stream; - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -1322,22 +1625,22 @@ _rem -= cur; if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) break; continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_currentIndex == _extractStatuses->Size()) { // we don't support write cut here return E_FAIL; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; @@ -1349,18 +1652,19 @@ static const UInt32 kTempBufSize = 1 << 16; -class CFolderInStream2: +class CFolderInStream2 Z7_final: public CRepackStreamBase, public ISequentialInStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialInStream) + Byte *_buf; public: CMyComPtr _inStream; HRESULT Result; - MY_UNKNOWN_IMP - CFolderInStream2(): Result(S_OK) { @@ -1373,10 +1677,9 @@ } void Init() { Result = S_OK; } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -1397,7 +1700,7 @@ cur = kTempBufSize; } - HRESULT result = _inStream->Read(buf, cur, &cur); + const HRESULT result = _inStream->Read(buf, cur, &cur); _crc = CrcUpdate(_crc, buf, cur); _rem -= cur; @@ -1414,11 +1717,11 @@ if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) return E_FAIL; @@ -1426,20 +1729,20 @@ continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_currentIndex == _extractStatuses->Size()) { return S_OK; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; } -class CThreadDecoder - #ifndef _7ZIP_ST +class CThreadDecoder Z7_final + #ifndef Z7_ST : public CVirtThread #endif { @@ -1449,7 +1752,7 @@ CThreadDecoder(bool multiThreadMixer): Decoder(multiThreadMixer) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (multiThreadMixer) { MtMode = false; @@ -1463,7 +1766,7 @@ // send_UnpackSize = false; } - #ifndef _7ZIP_ST + #ifndef Z7_ST bool dataAfterEnd_Error; HRESULT Result; @@ -1479,31 +1782,39 @@ // bool send_UnpackSize; // UInt64 UnpackSize; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr getTextPassword; #endif - DECL_EXTERNAL_CODECS_LOC_VARS2; + DECL_EXTERNAL_CODECS_LOC_VARS_DECL - #ifndef _7ZIP_ST + #ifndef Z7_ST bool MtMode; UInt32 NumThreads; #endif - ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); } - virtual void Execute(); + ~CThreadDecoder() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before + destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } +private: + virtual void Execute() Z7_override; #endif }; -#ifndef _7ZIP_ST +#ifndef Z7_ST void CThreadDecoder::Execute() { try { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; UString password; @@ -1526,8 +1837,8 @@ NULL // *inStreamMainRes , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST , MtMode, NumThreads, 0 // MemUsage #endif @@ -1548,20 +1859,17 @@ #endif -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO -class CCryptoGetTextPassword: - public ICryptoGetTextPassword, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CCryptoGetTextPassword + , ICryptoGetTextPassword +) public: UString Password; - - MY_UNKNOWN_IMP - STDMETHOD(CryptoGetTextPassword)(BSTR *password); }; -STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)) { return StringToBstr(Password, password); } @@ -1585,58 +1893,71 @@ DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const CDbEx *db, - const CObjectVector &updateItems, + CObjectVector &updateItems, // const CObjectVector &treeFolders, // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ) + const CUpdateOptions &options) { UInt64 numSolidFiles = options.NumSolidFiles; if (numSolidFiles == 0) numSolidFiles = 1; - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - - CMyComPtr extractCallback; - updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveExtractCallbackMessage2, + extractCallback, updateCallback) /* - CMyComPtr reportArcProp; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackArcProp, + reportArcProp, updateCallback) */ // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); - /* - CMyComPtr outStream; - RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); - if (!outStream) - return E_NOTIMPL; - */ - - UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0; - if (startBlockSize > 0 && !options.RemoveSfxBlock) + CMyComPtr v_StreamSetRestriction; { - RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); + Z7_DECL_CMyComPtr_QI_FROM( + IOutStream, + outStream, seqOutStream) + if (!outStream) + return E_NOTIMPL; + const UInt64 sfxBlockSize = (db && !options.RemoveSfxBlock) ? + db->ArcInfo.StartPosition: 0; + seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&v_StreamSetRestriction); + if (v_StreamSetRestriction) + { + UInt64 offset = 0; + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &offset)) + RINOK(v_StreamSetRestriction->SetRestriction( + outStream ? offset + sfxBlockSize : 0, + outStream ? offset + sfxBlockSize + k_StartHeadersRewriteSize : 0)) + } + outStream.Release(); + if (sfxBlockSize != 0) + { + RINOK(WriteRange(inStream, seqOutStream, 0, sfxBlockSize, NULL)) + } } CIntArr fileIndexToUpdateIndexMap; UInt64 complexity = 0; + bool isThere_UnknownSize = false; UInt64 inSizeForReduce2 = 0; + + #ifndef Z7_NO_CRYPTO bool needEncryptedRepack = false; + #endif CRecordVector filters; CObjectVector groups; - #ifndef _7ZIP_ST + #ifndef Z7_ST bool thereAreRepacks = false; #endif @@ -1646,11 +1967,15 @@ const CCompressionMethodMode &method = *options.Method; FOR_VECTOR (i, method.Methods) + { + /* IsFilterMethod() knows only built-in codecs + FIXME: we should check IsFilter status for external filters too */ if (IsFilterMethod(method.Methods[i].Id)) { useFilters = false; break; } + } } if (db) @@ -1672,7 +1997,7 @@ { CNum indexInFolder = 0; CNum numCopyItems = 0; - CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; + const CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; UInt64 repackSize = 0; for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++) @@ -1684,7 +2009,7 @@ if (file.HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) { numCopyItems++; @@ -1702,11 +2027,13 @@ CFolderEx f; db->ParseFolderEx(i, f); + #ifndef Z7_NO_CRYPTO const bool isEncrypted = f.IsEncrypted(); + #endif const bool needCopy = (numCopyItems == numUnpackStreams); const bool extractFilter = (useFilters || needCopy); - unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); + const unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); while (groupIndex >= groups.Size()) groups.AddNew(); @@ -1717,45 +2044,55 @@ complexity += db->GetFolderFullPackSize(i); else { - #ifndef _7ZIP_ST + #ifndef Z7_ST thereAreRepacks = true; #endif complexity += repackSize; if (inSizeForReduce2 < repackSize) inSizeForReduce2 = repackSize; + #ifndef Z7_NO_CRYPTO if (isEncrypted) needEncryptedRepack = true; + #endif } } } UInt64 inSizeForReduce = 0; { - bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0); + const bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0); FOR_VECTOR (i, updateItems) { const CUpdateItem &ui = updateItems[i]; if (ui.NewData) { - complexity += ui.Size; - if (isSolid) - inSizeForReduce += ui.Size; - else if (inSizeForReduce < ui.Size) - inSizeForReduce = ui.Size; + if (ui.Size == (UInt64)(Int64)-1) + isThere_UnknownSize = true; + else + { + complexity += ui.Size; + if (isSolid) + inSizeForReduce += ui.Size; + else if (inSizeForReduce < ui.Size) + inSizeForReduce = ui.Size; + } } } } + if (isThere_UnknownSize) + inSizeForReduce = (UInt64)(Int64)-1; + else + RINOK(updateCallback->SetTotal(complexity)) + if (inSizeForReduce < inSizeForReduce2) - inSizeForReduce = inSizeForReduce2; + inSizeForReduce = inSizeForReduce2; - RINOK(updateCallback->SetTotal(complexity)); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - #ifndef _7ZIP_ST + #ifndef Z7_ST CStreamBinder sb; /* @@ -1769,13 +2106,13 @@ CThreadDecoder threadDecoder(options.MultiThreadMixer); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer && thereAreRepacks) { - #ifdef EXTERNAL_CODECS - threadDecoder.__externalCodecs = __externalCodecs; + #ifdef Z7_EXTERNAL_CODECS + threadDecoder._externalCodecs = _externalCodecs; #endif - WRes wres = threadDecoder.Create(); + const WRes wres = threadDecoder.Create(); if (wres != 0) return HRESULT_FROM_WIN32(wres); } @@ -1784,22 +2121,23 @@ { CAnalysis analysis; // analysis.Need_ATime = options.Need_ATime; - if (options.AnalysisLevel == 0) - { - analysis.ParseWav = false; - analysis.ParseExe = false; - analysis.ParseAll = false; - } - else + int analysisLevel = options.AnalysisLevel; + // (analysisLevel < 0) means default level (5) + if (analysisLevel < 0) + analysisLevel = 5; + if (analysisLevel != 0) { analysis.Callback = opCallback; - if (options.AnalysisLevel > 0) + analysis.ParseWav = true; + if (analysisLevel >= 5) { - analysis.ParseWav = true; - if (options.AnalysisLevel >= 7) + analysis.ParseExe = true; + analysis.ParseExeUnix = true; + // analysis.ParseNoExt = true; + if (analysisLevel >= 7) { - analysis.ParseExe = true; - if (options.AnalysisLevel >= 9) + analysis.ParseNoExt = true; + if (analysisLevel >= 9) analysis.ParseAll = true; } } @@ -1819,7 +2157,7 @@ if (useFilters) { // analysis.ATime_Defined = false; - RINOK(analysis.GetFilterGroup(i, ui, fm)); + RINOK(analysis.GetFilterGroup(i, ui, fm)) /* if (analysis.ATime_Defined) { @@ -1830,7 +2168,7 @@ } fm.Encrypted = method.PasswordIsDefined; - unsigned groupIndex = GetGroup(filters, fm); + const unsigned groupIndex = GetGroup(filters, fm); while (groupIndex >= groups.Size()) groups.AddNew(); groups[groupIndex].Indices.Add(i); @@ -1838,7 +2176,7 @@ } - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CCryptoGetTextPassword *getPasswordSpec = NULL; CMyComPtr getTextPassword; @@ -1847,7 +2185,7 @@ getPasswordSpec = new CCryptoGetTextPassword; getTextPassword = getPasswordSpec; - #ifndef _7ZIP_ST + #ifndef Z7_ST threadDecoder.getTextPassword = getPasswordSpec; #endif @@ -1855,10 +2193,13 @@ getPasswordSpec->Password = options.Method->Password; else { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getDecoderPassword, updateCallback) if (!getDecoderPassword) return E_NOTIMPL; CMyComBSTR password; - RINOK(getDecoderPassword->CryptoGetTextPassword(&password)); + RINOK(getDecoderPassword->CryptoGetTextPassword(&password)) if (password) getPasswordSpec->Password = password; } @@ -1866,11 +2207,12 @@ #endif - // ---------- Compress ---------- - RINOK(archive.Create(seqOutStream, false)); - RINOK(archive.SkipPrefixArchiveHeader()); + COutArchive archive; + CArchiveDatabaseOut newDatabase; + + RINOK(archive.Create_and_WriteStartPrefix(seqOutStream)) /* CIntVector treeFolderToArcIndex; @@ -1973,7 +2315,6 @@ { // ---------- Sort Filters ---------- - FOR_VECTOR (i, filters) { filters[i].GroupIndex = i; @@ -1987,22 +2328,23 @@ CCompressionMethodMode method = *options.Method; { - HRESULT res = MakeExeMethod(method, filterMode, - #ifdef _7ZIP_ST + const HRESULT res = MakeExeMethod(method, filterMode, + // bcj2_IsAllowed: + #ifdef Z7_ST false #else options.MaxFilter && options.MultiThreadMixer #endif - ); + , options.DisabledFilterIDs); - RINOK(res); + RINOK(res) } if (filterMode.Encrypted) { if (!method.PasswordIsDefined) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (getPasswordSpec) method.Password = getPasswordSpec->Password; #endif @@ -2021,13 +2363,13 @@ const CSolidGroup &group = groups[filterMode.GroupIndex]; - FOR_VECTOR(folderRefIndex, group.folderRefs) + FOR_VECTOR (folderRefIndex, group.folderRefs) { const CFolderRepack &rep = group.folderRefs[folderRefIndex]; - unsigned folderIndex = rep.FolderIndex; + const unsigned folderIndex = rep.FolderIndex; - CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; + const CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; if (rep.NumCopyFiles == numUnpackStreams) { @@ -2035,7 +2377,7 @@ { RINOK(opCallback->ReportOperation( NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NUpdateNotifyOp::kReplicate)); + NUpdateNotifyOp::kReplicate)) // ---------- Copy old solid block ---------- { @@ -2047,21 +2389,27 @@ indexInFolder++; RINOK(opCallback->ReportOperation( NEventIndexType::kInArcIndex, (UInt32)fi, - NUpdateNotifyOp::kReplicate)); + NUpdateNotifyOp::kReplicate)) } } } } - UInt64 packSize = db->GetFolderFullPackSize(folderIndex); + const UInt64 packSize = db->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, - db->GetFolderStreamPos(folderIndex, 0), packSize, progress)); + db->GetFolderStreamPos(folderIndex, 0), packSize, lps)) lps->ProgressOffset += packSize; - + + const unsigned folderIndex_New = newDatabase.Folders.Size(); CFolder &folder = newDatabase.Folders.AddNew(); + // v23.01: we copy FolderCrc, if FolderCrc was used + if (db->FolderCRCs.ValidAndDefined(folderIndex)) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, db->FolderCRCs.Vals[folderIndex]); + db->ParseFolderInfo(folderIndex, folder); - CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; - FOR_VECTOR(j, folder.PackStreams) + const CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; + FOR_VECTOR (j, folder.PackStreams) { newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j)); // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); @@ -2069,9 +2417,9 @@ } size_t indexStart = db->FoToCoderUnpackSizes[folderIndex]; - size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; + const size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; for (; indexStart < indexEnd; indexStart++) - newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]); + newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes.ConstData()[indexStart]); } else { @@ -2108,7 +2456,7 @@ if (file.HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) needExtract = true; // decodeSize += file.Size; @@ -2130,7 +2478,6 @@ unsigned startPackIndex = newDatabase.PackSizes.Size(); UInt64 curUnpackSize; { - CMyComPtr sbInStream; CRepackStreamBase *repackBase; CFolderInStream2 *FosSpec2 = NULL; @@ -2138,13 +2485,13 @@ CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes; CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer) { repackBase = threadDecoder.FosSpec; CMyComPtr sbOutStream; sb.CreateStreams2(sbInStream, sbOutStream); - RINOK(sb.Create_ReInit()); + RINOK(sb.Create_ReInit()) threadDecoder.FosSpec->_stream = sbOutStream; @@ -2164,7 +2511,7 @@ sbInStream = FosSpec2; repackBase = FosSpec2; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; UString password; @@ -2173,7 +2520,7 @@ CMyComPtr decodedStream; bool dataAfterEnd_Error = false; - HRESULT res = threadDecoder.Decoder.Decode( + const HRESULT res = threadDecoder.Decoder.Decode( EXTERNAL_CODECS_LOC_VARS inStream, db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);, @@ -2187,15 +2534,15 @@ &decodedStream , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST , false // mtMode , 1 // numThreads , 0 // memUsage #endif ); - RINOK(res); + RINOK(res) if (!decodedStream) return E_FAIL; @@ -2207,12 +2554,12 @@ repackBase->_extractCallback = extractCallback; UInt32 startIndex = db->FolderStartFileIndex[folderIndex]; - RINOK(repackBase->Init(startIndex, &extractStatuses)); + RINOK(repackBase->Init(startIndex, &extractStatuses)) inStreamSizeCountSpec->_db = db; inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer) { WRes wres = threadDecoder.Start(); @@ -2222,20 +2569,29 @@ #endif } - curUnpackSize = sizeToEncode; + // curUnpackSize = sizeToEncode; - HRESULT encodeRes = encoder.Encode( + HRESULT encodeRes = encoder.Encode1( EXTERNAL_CODECS_LOC_VARS inStreamSizeCount, // NULL, &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize, - archive.SeqStream, newDatabase.PackSizes, progress); + sizeToEncode, // expectedDataSize + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curUnpackSize, + archive.SeqStream, newDatabase.PackSizes, lps); if (encodeRes == k_My_HRESULT_CRC_ERROR) return E_FAIL; - #ifndef _7ZIP_ST + curUnpackSize = inStreamSizeCountSpec->GetSize(); + + if (encodeRes == S_OK) + { + encoder.Encode_Post(curUnpackSize, newDatabase.CoderUnpackSizes); + } + + #ifndef Z7_ST if (options.MultiThreadMixer) { // 16.00: hang was fixed : for case if decoding was not finished. @@ -2244,12 +2600,12 @@ sbInStream.Release(); { - WRes wres = threadDecoder.WaitExecuteFinish(); + const WRes wres = threadDecoder.WaitExecuteFinish(); if (wres != 0) return HRESULT_FROM_WIN32(wres); } - HRESULT decodeRes = threadDecoder.Result; + const HRESULT decodeRes = threadDecoder.Result; // if (res == k_My_HRESULT_CRC_ERROR) if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error) { @@ -2260,12 +2616,12 @@ // NEventIndexType::kBlockIndex, (UInt32)folderIndex, (decodeRes != S_OK ? NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kDataAfterEnd))); + NExtract::NOperationResult::kDataAfterEnd))) } if (decodeRes != S_OK) return E_FAIL; } - RINOK(decodeRes); + RINOK(decodeRes) if (encodeRes == S_OK) if (sb.ProcessedSize != sizeToEncode) encodeRes = E_FAIL; @@ -2279,15 +2635,15 @@ { RINOK(extractCallback->ReportExtractResult( NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return E_FAIL; } - RINOK(FosSpec2->Result); + RINOK(FosSpec2->Result) } - RINOK(encodeRes); - RINOK(repackBase->CheckFinishedState()); + RINOK(encodeRes) + RINOK(repackBase->CheckFinishedState()) if (curUnpackSize != sizeToEncode) return E_FAIL; @@ -2306,7 +2662,7 @@ if (db->Files[fi].HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0) { const CUpdateItem &ui = updateItems[(unsigned)updateIndex]; @@ -2343,13 +2699,13 @@ // ---------- Compress files to new solid blocks ---------- - unsigned numFiles = group.Indices.Size(); + const unsigned numFiles = group.Indices.Size(); if (numFiles == 0) continue; CRecordVector refItems; refItems.ClearAndSetSize(numFiles); // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1 - bool sortByType = options.UseTypeSorting; + const bool sortByType = options.UseTypeSorting; unsigned i; @@ -2365,7 +2721,7 @@ for (i = 0; i < numFiles; i++) { - UInt32 index = refItems[i].Index; + const UInt32 index = refItems[i].Index; indices[i] = index; /* const CUpdateItem &ui = updateItems[index]; @@ -2395,8 +2751,8 @@ break; if (options.SolidExtension) { - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1)); if (numSubFiles == 0) prevExtension = ext; @@ -2408,7 +2764,7 @@ if (numSubFiles < 1) numSubFiles = 1; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) /* const unsigned folderIndex = newDatabase.NumUnpackStreamsVector.Size(); @@ -2422,8 +2778,7 @@ */ - CFolderInStream *inStreamSpec = new CFolderInStream; - CMyComPtr solidInStream(inStreamSpec); + CMyComPtr2_Create inStreamSpec; // solidInStream; // inStreamSpec->_reportArcProp = reportArcProp; @@ -2431,31 +2786,45 @@ inStreamSpec->Need_ATime = options.Need_ATime; inStreamSpec->Need_MTime = options.Need_MTime; inStreamSpec->Need_Attrib = options.Need_Attrib; + // inStreamSpec->Need_Crc = options.Need_Crc; inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); unsigned startPackIndex = newDatabase.PackSizes.Size(); - UInt64 curFolderUnpackSize = totalSize; + // UInt64 curFolderUnpackSize = totalSize; // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug + const UInt64 expectedDataSize = totalSize; + + // const unsigned folderIndex_New = newDatabase.Folders.Size(); - RINOK(encoder.Encode( + RINOK(encoder.Encode1( EXTERNAL_CODECS_LOC_VARS - solidInStream, + inStreamSpec, // NULL, &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize, - archive.SeqStream, newDatabase.PackSizes, progress)); + expectedDataSize, // expected size + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curFolderUnpackSize, + archive.SeqStream, newDatabase.PackSizes, lps)) if (!inStreamSpec->WasFinished()) return E_FAIL; + /* + if (inStreamSpec->Need_FolderCrc) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, inStreamSpec->GetFolderCrc()); + */ + + const UInt64 curFolderUnpackSize = inStreamSpec->Get_TotalSize_for_Coder(); + encoder.Encode_Post(curFolderUnpackSize, newDatabase.CoderUnpackSizes); + UInt64 packSize = 0; // const UInt32 numStreams = newDatabase.PackSizes.Size() - startPackIndex; for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) packSize += newDatabase.PackSizes[startPackIndex]; lps->OutSize += packSize; - lps->InSize += curFolderUnpackSize; // for () // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); @@ -2496,14 +2865,15 @@ // name += ".locked"; // for debug } + // if (inStreamSpec->Need_Crc) file.Crc = inStreamSpec->CRCs[subIndex]; file.Size = inStreamSpec->Sizes[subIndex]; procSize += file.Size; - // if (file.Size >= 0) // test purposes + // if (file.Size >= 0) // for debug: test purposes if (file.Size != 0) { - file.CrcDefined = true; + file.CrcDefined = true; // inStreamSpec->Need_Crc; file.HasStream = true; numUnpackStreams++; } @@ -2549,9 +2919,66 @@ newDatabase.AddFile(file, file2, name); } + /* + // for debug: + // we can write crc to folders area, if folder contains only one file + if (numUnpackStreams == 1 && numSubFiles == 1) + { + const CFileItem &file = newDatabase.Files.Back(); + if (file.CrcDefined) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, true, file.Crc); + } + */ + + /* // it's optional check to ensure that sizes are correct - if (procSize != curFolderUnpackSize) + if (inStreamSpec->TotalSize_for_Coder != curFolderUnpackSize) return E_FAIL; + */ + // if (inStreamSpec->AlignLog == 0) + { + if (procSize != curFolderUnpackSize) + return E_FAIL; + } + // else + { + /* + { + const CFolder &old = newDatabase.Folders.Back(); + CFolder &folder = newDatabase.Folders.AddNew(); + { + const unsigned numBonds = old.Bonds.Size(); + folder.Bonds.SetSize(numBonds + 1); + for (unsigned k = 0; k < numBonds; k++) + folder.Bonds[k] = old.Bonds[k]; + CBond &bond = folder.Bonds[numBonds]; + bond.PackIndex = 0; + bond.UnpackIndex = 0; + } + { + const unsigned numCoders = old.Coders.Size(); + folder.Coders.SetSize(numCoders + 1); + for (unsigned k = 0; k < numCoders; k++) + folder.Coders[k] = old.Coders[k]; + CCoderInfo &cod = folder.Coders[numCoders]; + cod.Props.Alloc(1); + cod.Props[0] = (Byte)inStreamSpec->AlignLog; + cod.NumStreams = 1; + } + { + const unsigned numPackStreams = old.Coders.Size(); + folder.Coders.SetSize(numPackStreams); + for (unsigned k = 0; k < numPackStreams; k++) + folder.PackStreams[k] = old.PackStreams[k]; + } + } + newDatabase.Folders.Delete(newDatabase.Folders.Size() - 2); + */ + } + + + lps->InSize += procSize; + // lps->InSize += curFolderUnpackSize; // numUnpackStreams = 0 is very bad case for locked files // v3.13 doesn't understand it. @@ -2561,7 +2988,7 @@ if (skippedSize != 0 && complexity >= skippedSize) { complexity -= skippedSize; - RINOK(updateCallback->SetTotal(complexity)); + RINOK(updateCallback->SetTotal(complexity)) } /* @@ -2604,7 +3031,7 @@ } } - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) /* fileIndexToUpdateIndexMap.ClearAndFree(); @@ -2634,10 +3061,26 @@ } } */ + + { + const unsigned numFolders = newDatabase.Folders.Size(); + if (newDatabase.NumUnpackStreamsVector.Size() != numFolders + || newDatabase.FolderUnpackCRCs.Defs.Size() > numFolders) + return E_FAIL; + newDatabase.FolderUnpackCRCs.if_NonEmpty_FillResidue_with_false(numFolders); + } + + updateItems.ClearAndFree(); newDatabase.ReserveDown(); if (opCallback) - RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)); + RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)) + + RINOK(archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS + newDatabase, options.HeaderMethod, options.HeaderOptions)) + + if (v_StreamSetRestriction) + RINOK(v_StreamSetRestriction->SetRestriction(0, 0)) return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.h 2022-02-06 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/7zUpdate.h 2024-05-12 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zUpdate.h -#ifndef __7Z_UPDATE_H -#define __7Z_UPDATE_H +#ifndef ZIP7_INC_7Z_UPDATE_H +#define ZIP7_INC_7Z_UPDATE_H #include "../IArchive.h" @@ -9,7 +9,6 @@ #include "7zCompressionMode.h" #include "7zIn.h" -#include "7zOut.h" namespace NArchive { namespace N7z { @@ -95,8 +94,6 @@ bool MaxFilter; // use BCJ2 filter instead of BCJ int AnalysisLevel; - CHeaderOptions HeaderOptions; - UInt64 NumSolidFiles; UInt64 NumSolidBytes; bool SolidExtension; @@ -110,6 +107,28 @@ bool Need_ATime; bool Need_MTime; bool Need_Attrib; + // bool Need_Crc; + + CHeaderOptions HeaderOptions; + + CUIntVector DisabledFilterIDs; + + void Add_DisabledFilter_for_id(UInt32 id, + const CUIntVector &enabledFilters) + { + if (enabledFilters.FindInSorted(id) < 0) + DisabledFilterIDs.AddToUniqueSorted(id); + } + + void SetFilterSupporting_ver_enabled_disabled( + UInt32 compatVer, + const CUIntVector &enabledFilters, + const CUIntVector &disabledFilters) + { + DisabledFilterIDs = disabledFilters; + if (compatVer < 2300) Add_DisabledFilter_for_id(k_ARM64, enabledFilters); + if (compatVer < 2402) Add_DisabledFilter_for_id(k_RISCV, enabledFilters); + } CUpdateOptions(): Method(NULL), @@ -127,25 +146,22 @@ Need_ATime(false), Need_MTime(false), Need_Attrib(false) - {} + // , Need_Crc(true) + { + DisabledFilterIDs.Add(k_RISCV); + } }; HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const CDbEx *db, - const CObjectVector &updateItems, + CObjectVector &updateItems, // const CObjectVector &treeFolders, // treeFolders[0] is root // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ); + const CUpdateOptions &options); }} #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/StdAfx.h 2013-11-24 12:59:55.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/7z/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/makefile --- 7zip-22.01+dfsg/CPP/7zip/Archive/7z/makefile 2015-10-18 10:02:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/7z/makefile 2023-04-04 20:00:00.000000000 +0000 @@ -1,11 +1,11 @@ PROG = 7z.dll DEF_FILE = ../Archive.def CFLAGS = $(CFLAGS) \ - -DEXTERNAL_CODECS \ + -DZ7_EXTERNAL_CODECS \ AR_OBJS = \ $O\ArchiveExports.obj \ - $O\DllExports.obj \ + $O\DllExports2.obj \ 7Z_OBJS = \ $O\7zCompressionMode.obj \ @@ -34,7 +34,6 @@ $O\Wildcard.obj \ WIN_OBJS = \ - $O\DLL.obj \ $O\FileDir.obj \ $O\FileFind.obj \ $O\FileIO.obj \ @@ -61,6 +60,7 @@ COMPRESS_OBJS = \ $O\CopyCoder.obj \ + $O\CodecExports.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ApfsHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApfsHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ApfsHandler.cpp 2022-07-11 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApfsHandler.cpp 2023-12-11 16:00:00.000000000 +0000 @@ -12,9 +12,11 @@ #endif #include "../../../C/CpuArch.h" +#include "../../../C/Sha256.h" #include "../../Common/ComTry.h" #include "../../Common/IntToString.h" +#include "../../Common/MyBuffer2.h" #include "../../Common/MyLinux.h" #include "../../Common/UTFConvert.h" @@ -52,31 +54,18 @@ namespace NArchive { namespace NApfs { -#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10)))) - -static void ConvertByteToHex(unsigned val, char *s) -{ - unsigned t; - t = val >> 4; - s[0] = ValToHex(t); - t = val & 0xF; - s[1] = ValToHex(t); -} - struct CUuid { Byte Data[16]; void SetHex_To_str(char *s) const { - for (unsigned i = 0; i < 16; i++) - ConvertByteToHex(Data[i], s + i * 2); - s[32] = 0; + ConvertDataToHex_Lower(s, Data, sizeof(Data)); } void AddHexToString(UString &dest) const { - char temp[32 + 4]; + char temp[sizeof(Data) * 2 + 4]; SetHex_To_str(temp); dest += temp; } @@ -87,7 +76,8 @@ typedef UInt64 oid_t; typedef UInt64 xid_t; -typedef Int64 paddr_t; +// typedef Int64 paddr_t; +typedef UInt64 paddr_t_unsigned; #define G64o G64 #define G64x G64 @@ -140,8 +130,10 @@ #define OBJECT_TYPE_GBITMAP_BLOCK 0x1b #define OBJECT_TYPE_ER_RECOVERY_BLOCK 0x1c #define OBJECT_TYPE_SNAP_META_EXT 0x1d +*/ #define OBJECT_TYPE_INTEGRITY_META 0x1e #define OBJECT_TYPE_FEXT_TREE 0x1f +/* #define OBJECT_TYPE_RESERVED_20 0x20 #define OBJECT_TYPE_INVALID 0x0 @@ -152,8 +144,9 @@ #define OBJ_VIRTUAL 0x0 #define OBJ_EPHEMERAL 0x80000000 +*/ #define OBJ_PHYSICAL 0x40000000 - +/* #define OBJ_NOHEADER 0x20000000 #define OBJ_ENCRYPTED 0x10000000 #define OBJ_NONPERSISTENT 0x08000000 @@ -167,6 +160,8 @@ // #define MAX_CKSUM_SIZE 8 +static const unsigned k_obj_phys_Size = 0x20; + // obj_phys_t struct CPhys { @@ -183,10 +178,10 @@ void CPhys::Parse(const Byte *p) { // memcpy(cksum, p, MAX_CKSUM_SIZE); - G64o (8, oid); - G64x (0x10, xid); - G32 (0x18, type); - G32 (0x1C, subtype); + G64o (8, oid) + G64x (0x10, xid) + G32 (0x18, type) + G32 (0x1C, subtype) } #define NX_MAX_FILE_SYSTEMS 100 @@ -216,7 +211,9 @@ #define APFS_INCOMPAT_NORMALIZATION_INSENSITIVE (1 << 3) /* #define APFS_INCOMPAT_INCOMPLETE_RESTORE (1 << 4) +*/ #define APFS_INCOMPAT_SEALED_VOLUME (1 << 5) +/* #define APFS_INCOMPAT_RESERVED_40 (1 << 6) */ @@ -301,7 +298,7 @@ { for (unsigned i = 0; i < NX_MAX_FILE_SYSTEMS; i++) { - G64o (0xb8 + i * 8, fs_oid[i]); + G64o (0xb8 + i * 8, fs_oid[i]) } } }; @@ -369,17 +366,18 @@ if (!CheckFletcher64(p, kApfsHeaderSize)) return false; - G32 (0x24, block_size); + G32 (0x24, block_size) { - unsigned logSize = GetLogSize(block_size); + const unsigned logSize = GetLogSize(block_size); + // don't change it. Some code requires (block_size <= 16) if (logSize < 12 || logSize > 16) return false; block_size_Log = logSize; } - G64 (0x28, block_count); + G64 (0x28, block_count) - static const UInt64 kArcSize_MAX = (UInt64)1 << 62; + const UInt64 kArcSize_MAX = (UInt64)1 << 62; if (block_count > (kArcSize_MAX >> block_size_Log)) return false; @@ -402,10 +400,10 @@ G32 (0x94, xp_data_len); G64o (0x98, spaceman_oid); */ - G64o (0xa0, omap_oid); + G64o (0xa0, omap_oid) // G64o (0xa8, reaper_oid); // G32 (0xb0, test_type); - G32 (0xb4, max_file_systems); + G32 (0xb4, max_file_systems) if (max_file_systems > NX_MAX_FILE_SYSTEMS) return false; /* @@ -448,6 +446,87 @@ } +enum apfs_hash_type_t +{ + APFS_HASH_INVALID = 0, + APFS_HASH_SHA256 = 1, + APFS_HASH_SHA512_256 = 2, + APFS_HASH_SHA384 = 3, + APFS_HASH_SHA512 = 4, + + APFS_HASH_MIN = APFS_HASH_SHA256, + APFS_HASH_MAX = APFS_HASH_SHA512, + + APFS_HASH_DEFAULT = APFS_HASH_SHA256 +}; + +static unsigned GetHashSize(unsigned hashType) +{ + if (hashType > APFS_HASH_MAX) return 0; + if (hashType < APFS_HASH_MIN) return 0; + if (hashType == APFS_HASH_SHA256) return 32; + return hashType * 16; +} + +#define APFS_HASH_MAX_SIZE 64 + +static const char * const g_hash_types[] = +{ + NULL + , "SHA256" + , "SHA512_256" + , "SHA384" + , "SHA512" +}; + + +struct C_integrity_meta_phys +{ + // CPhys im_o; + // UInt32 im_version; + UInt32 im_flags; + // apfs_hash_type_t + UInt32 im_hash_type; + // UInt32 im_root_hash_offset; + // xid_t im_broken_xid; + // UInt64 im_reserved[9]; + + unsigned HashSize; + Byte Hash[APFS_HASH_MAX_SIZE]; + + bool Is_SHA256() const { return im_hash_type == APFS_HASH_SHA256; } + + C_integrity_meta_phys() + { + memset(this, 0, sizeof(*this)); + } + bool Parse(const Byte *p, size_t size, oid_t oid); +}; + +bool C_integrity_meta_phys::Parse(const Byte *p, size_t size, oid_t oid) +{ + CPhys o; + if (!CheckFletcher64(p, size)) + return false; + o.Parse(p); + if (o.GetType() != OBJECT_TYPE_INTEGRITY_META) + return false; + if (o.oid != oid) + return false; + // G32 (0x20, im_version); + G32 (0x24, im_flags) + G32 (0x28, im_hash_type) + UInt32 im_root_hash_offset; + G32 (0x2C, im_root_hash_offset) + // G64x (0x30, im_broken_xid); + const unsigned hashSize = GetHashSize(im_hash_type); + HashSize = hashSize; + if (im_root_hash_offset >= size || size - im_root_hash_offset < hashSize) + return false; + memcpy(Hash, p + im_root_hash_offset, hashSize); + return true; +} + struct C_omap_phys { @@ -485,7 +564,7 @@ G32 (0x28, tree_type); G32 (0x2C, snapshot_tree_type); */ - G64o (0x30, tree_oid); + G64o (0x30, tree_oid) /* G64o (0x38, snapshot_tree_oid); G64x (0x40, most_recent_snap); @@ -509,8 +588,8 @@ void Parse(const Byte *p) { - G16 (0, off); - G16 (2, len); + G16 (0, off) + G16 (2, len) } UInt32 GetEnd() const { return (UInt32)off + len; } bool CheckOverLimit(UInt32 limit) @@ -542,8 +621,8 @@ void Parse(const Byte *p) { - G16 (0, k); - G16 (2, v); + G16 (0, k) + G16 (2, v) } }; @@ -551,9 +630,9 @@ #define BTNODE_ROOT (1 << 0) #define BTNODE_LEAF (1 << 1) #define BTNODE_FIXED_KV_SIZE (1 << 2) -/* #define BTNODE_HASHED (1 << 3) #define BTNODE_NOHEADER (1 << 4) +/* #define BTNODE_CHECK_KOFF_INVAL (1 << 15) */ @@ -563,7 +642,7 @@ struct CBTreeNodePhys { // btn_ prefix - CPhys o; + CPhys ophys; UInt16 flags; UInt16 level; // the number of child levels below this node. 0 - for a leaf node, 1 for the immediate parent of a leaf node UInt32 nkeys; // The number of keys stored in this node. @@ -575,21 +654,35 @@ */ bool Is_FIXED_KV_SIZE() const { return (flags & BTNODE_FIXED_KV_SIZE) != 0; } + bool Is_NOHEADER() const { return (flags & BTNODE_NOHEADER) != 0; } + bool Is_HASHED() const { return (flags & BTNODE_HASHED) != 0; } - bool Parse(const Byte *p, size_t size) + bool Parse(const Byte *p, size_t size, bool noHeader = false) { - if (!CheckFletcher64(p, size)) - return false; - o.Parse(p); - G16 (0x20, flags); - G16 (0x22, level); - G32 (0x24, nkeys); + G16 (0x20, flags) + G16 (0x22, level) + G32 (0x24, nkeys) table_space.Parse(p + 0x28); /* free_space.Parse(p + 0x2C); key_free_list.Parse(p + 0x30); val_free_list.Parse(p + 0x34); */ + memset(&ophys, 0, sizeof(ophys)); + if (noHeader) + { + for (unsigned i = 0; i < k_obj_phys_Size; i++) + if (p[i] != 0) + return false; + } + else + { + if (!CheckFletcher64(p, size)) + return false; + ophys.Parse(p); + } + if (Is_NOHEADER() != noHeader) + return false; return true; } }; @@ -606,6 +699,7 @@ #define BTREE_KV_NONALIGNED (1 << 6) #define BTREE_HASHED (1 << 7) */ +#define BTREE_NOHEADER (1 << 8) /* BTREE_EPHEMERAL: The nodes in the B-tree use ephemeral object identifiers to link to child nodes @@ -624,10 +718,10 @@ void Parse(const Byte *p) { - G32 (0, flags); - G32 (4, node_size); - G32 (8, key_size); - G32 (12, val_size); + G32 (0, flags) + G32 (4, node_size) + G32 (8, key_size) + G32 (12, val_size) } }; @@ -643,14 +737,15 @@ bool Is_EPHEMERAL() const { return (fixed.flags & BTREE_EPHEMERAL) != 0; } bool Is_PHYSICAL() const { return (fixed.flags & BTREE_PHYSICAL) != 0; } + bool Is_NOHEADER() const { return (fixed.flags & BTREE_NOHEADER) != 0; } void Parse(const Byte *p) { fixed.Parse(p); - G32 (0x10, longest_key); - G32 (0x14, longest_val); - G64 (0x18, key_count); - G64 (0x20, node_count); + G32 (0x10, longest_key) + G32 (0x14, longest_val) + G64 (0x18, key_count) + G64 (0x20, node_count) } }; @@ -685,7 +780,7 @@ #define APFS_MODIFIED_NAMELEN 32 -#define sizeof__apfs_modified_by_t (APFS_MODIFIED_NAMELEN + 16); +#define sizeof_apfs_modified_by_t (APFS_MODIFIED_NAMELEN + 16) struct apfs_modified_by_t { @@ -697,8 +792,8 @@ { memcpy(id, p, APFS_MODIFIED_NAMELEN); p += APFS_MODIFIED_NAMELEN; - G64 (0, timestamp); - G64x (8, last_xid); + G64 (0, timestamp) + G64x (8, last_xid) } }; @@ -711,7 +806,7 @@ // apfs_ CPhys o; // UInt32 magic; - UInt32 fs_index; // e index of the object identifier for this volume's file system in the container's array of file systems. + UInt32 fs_index; // index of the object identifier for this volume's file system in the container's array of file systems. // UInt64 features; // UInt64 readonly_compatible_features; UInt64 incompatible_features; @@ -759,9 +854,11 @@ UInt64 cloneinfo_xid; oid_t snap_meta_ext_oid; CUuid volume_group_id; - oid_t integrity_meta_oid; - oid_t fext_tree_oid; - UInt32 fext_tree_type; + */ + oid_t integrity_meta_oid; // virtual object identifier of the integrity metadata object + oid_t fext_tree_oid; // virtual object identifier of the file extent tree. + UInt32 fext_tree_type; // The type of the file extent tree. + /* UInt32 reserved_type; oid_t reserved_oid; */ @@ -793,21 +890,21 @@ return false; // if (o.GetType() != OBJECT_TYPE_NX_SUPERBLOCK) return false; - G32 (0x24, fs_index); + G32 (0x24, fs_index) // G64 (0x28, features); // G64 (0x30, readonly_compatible_features); - G64 (0x38, incompatible_features); - G64 (0x40, unmount_time); + G64 (0x38, incompatible_features) + G64 (0x40, unmount_time) // G64 (0x48, fs_reserve_block_count); // G64 (0x50, fs_quota_block_count); - G64 (0x58, fs_alloc_count); + G64 (0x58, fs_alloc_count) // meta_crypto.Parse(p + 0x60); // G32 (0x74, root_tree_type); // G32 (0x78, extentref_tree_type); // G32 (0x7C, snap_meta_tree_type); - G64o (0x80, omap_oid); - G64o (0x88, root_tree_oid); + G64o (0x80, omap_oid) + G64o (0x88, root_tree_oid) /* G64o (0x90, extentref_tree_oid); G64o (0x98, snap_meta_tree_oid); @@ -815,23 +912,23 @@ G64o (0xa8, revert_to_sblock_oid); G64 (0xb0, next_obj_id); */ - G64 (0xb8, num_files); - G64 (0xc0, num_directories); - G64 (0xc8, num_symlinks); - G64 (0xd0, num_other_fsobjects); - G64 (0xd8, num_snapshots); - G64 (0xe0, total_blocks_alloced); - G64 (0xe8, total_blocks_freed); + G64 (0xb8, num_files) + G64 (0xc0, num_directories) + G64 (0xc8, num_symlinks) + G64 (0xd0, num_other_fsobjects) + G64 (0xd8, num_snapshots) + G64 (0xe0, total_blocks_alloced) + G64 (0xe8, total_blocks_freed) vol_uuid.SetFrom(p + 0xf0); - G64 (0x100, last_mod_time); - G64 (0x108, fs_flags); + G64 (0x100, last_mod_time) + G64 (0x108, fs_flags) p += 0x110; formatted_by.Parse(p); - p += sizeof__apfs_modified_by_t; + p += sizeof_apfs_modified_by_t; for (unsigned i = 0; i < APFS_MAX_HIST; i++) { modified_by[i].Parse(p); - p += sizeof__apfs_modified_by_t; + p += sizeof_apfs_modified_by_t; } memcpy(volname, p, APFS_VOLNAME_LEN); p += APFS_VOLNAME_LEN; @@ -845,9 +942,11 @@ G64 (0x20, cloneinfo_xid); G64o (0x28, snap_meta_ext_oid); volume_group_id.SetFrom(p + 0x30); - G64o (0x40, integrity_meta_oid); - G64o (0x48, fext_tree_oid); - G32 (0x50, fext_tree_type); + */ + G64o (0x40, integrity_meta_oid) + G64o (0x48, fext_tree_oid) + G32 (0x50, fext_tree_type) + /* G32 (0x54, reserved_type); G64o (0x58, reserved_oid); */ @@ -888,7 +987,7 @@ { UInt64 obj_id_and_type; - void Parse(const Byte *p) { G64(0, obj_id_and_type); } + void Parse(const Byte *p) { G64(0, obj_id_and_type) } unsigned GetType() const { return (unsigned)(obj_id_and_type >> OBJ_TYPE_SHIFT); } UInt64 GetID() const { return obj_id_and_type & OBJ_ID_MASK; } }; @@ -918,9 +1017,9 @@ // uint8_t xfields[]; void Parse(const Byte *p) { - G64 (0, file_id); - G64 (8, date_added); - G16 (0x10, flags); + G64 (0, file_id) + G64 (8, date_added) + G16 (0x10, flags) } }; @@ -959,8 +1058,8 @@ #define UNIFIED_ID_SPACE_MARK 0x0800000000000000 */ -typedef enum -{ +//typedef enum +// { /* INODE_IS_APFS_PRIVATE = 0x00000001, INODE_MAINTAIN_DIR_STATS = 0x00000002, @@ -977,13 +1076,13 @@ INODE_PINNED_TO_MAIN = 0x00001000, INODE_PINNED_TO_TIER2 = 0x00002000, */ -INODE_HAS_RSRC_FORK = 0x00004000, +// INODE_HAS_RSRC_FORK = 0x00004000, /* INODE_NO_RSRC_FORK = 0x00008000, INODE_ALLOCATION_SPILLEDOVER = 0x00010000, INODE_FAST_PROMOTE = 0x00020000, */ -INODE_HAS_UNCOMPRESSED_SIZE = 0x00040000, +#define INODE_HAS_UNCOMPRESSED_SIZE 0x00040000 /* INODE_IS_PURGEABLE = 0x00080000, INODE_WANTS_TO_BE_PURGEABLE = 0x00100000, @@ -1001,8 +1100,8 @@ | INODE_HAS_FINDER_INFO \ | INODE_SNAPSHOT_COW_EXEMPTION), */ -} -j_inode_flags; +// } +// j_inode_flags; /* @@ -1063,24 +1162,24 @@ // bsd stat.h /* -#define MY__UF_SETTABLE 0x0000ffff // mask of owner changeable flags -#define MY__UF_NODUMP 0x00000001 // do not dump file -#define MY__UF_IMMUTABLE 0x00000002 // file may not be changed -#define MY__UF_APPEND 0x00000004 // writes to file may only append -#define MY__UF_OPAQUE 0x00000008 // directory is opaque wrt. union -#define MY__UF_NOUNLINK 0x00000010 // file entry may not be removed or renamed Not implement in MacOS -#define MY__UF_COMPRESSED 0x00000020 // file entry is compressed -#define MY__UF_TRACKED 0x00000040 // notify about file entry changes -#define MY__UF_DATAVAULT 0x00000080 // entitlement required for reading and writing -#define MY__UF_HIDDEN 0x00008000 // file entry is hidden - -#define MY__SF_SETTABLE 0xffff0000 // mask of superuser changeable flags -#define MY__SF_ARCHIVED 0x00010000 // file is archived -#define MY__SF_IMMUTABLE 0x00020000 // file may not be changed -#define MY__SF_APPEND 0x00040000 // writes to file may only append -#define MY__SF_RESTRICTED 0x00080000 // entitlement required for writing -#define MY__SF_NOUNLINK 0x00100000 // file entry may not be removed, renamed or used as mount point -#define MY__SF_SNAPSHOT 0x00200000 // snapshot inode +#define MY_UF_SETTABLE 0x0000ffff // mask of owner changeable flags +#define MY_UF_NODUMP 0x00000001 // do not dump file +#define MY_UF_IMMUTABLE 0x00000002 // file may not be changed +#define MY_UF_APPEND 0x00000004 // writes to file may only append +#define MY_UF_OPAQUE 0x00000008 // directory is opaque wrt. union +#define MY_UF_NOUNLINK 0x00000010 // file entry may not be removed or renamed Not implement in MacOS +#define MY_UF_COMPRESSED 0x00000020 // file entry is compressed +#define MY_UF_TRACKED 0x00000040 // notify about file entry changes +#define MY_UF_DATAVAULT 0x00000080 // entitlement required for reading and writing +#define MY_UF_HIDDEN 0x00008000 // file entry is hidden + +#define MY_SF_SETTABLE 0xffff0000 // mask of superuser changeable flags +#define MY_SF_ARCHIVED 0x00010000 // file is archived +#define MY_SF_IMMUTABLE 0x00020000 // file may not be changed +#define MY_SF_APPEND 0x00040000 // writes to file may only append +#define MY_SF_RESTRICTED 0x00080000 // entitlement required for writing +#define MY_SF_NOUNLINK 0x00100000 // file entry may not be removed, renamed or used as mount point +#define MY_SF_SNAPSHOT 0x00200000 // snapshot inode Not implement in MacOS */ @@ -1142,11 +1241,11 @@ void Parse(const Byte *p) { - G64 (0, size); - G64 (0x8, alloced_size); - G64 (0x10, default_crypto_id); - G64 (0x18, total_bytes_written); - G64 (0x20, total_bytes_read); + G64 (0, size) + G64 (0x8, alloced_size) + G64 (0x10, default_crypto_id) + G64 (0x18, total_bytes_written) + G64 (0x20, total_bytes_read) } }; @@ -1167,8 +1266,8 @@ void Parse(const Byte *p) { - G64 (0, len_and_flags); - G64 (0x8, phys_block_num); + G64 (0, len_and_flags) + G64 (0x8, phys_block_num) // G64 (0x10, crypto_id); } }; @@ -1180,12 +1279,14 @@ UInt64 len_and_flags; // The length must be a multiple of the block size defined by the nx_block_size field of nx_superblock_t. // There are currently no flags defined UInt64 phys_block_num; // The physical block address that the extent starts at + + UInt64 GetEndOffset() const { return logical_offset + EXTENT_GET_LEN(len_and_flags); } }; -typedef UInt32 MY__uid_t; -typedef UInt32 MY__gid_t; -typedef UInt16 MY__mode_t; +typedef UInt32 MY_uid_t; +typedef UInt32 MY_gid_t; +typedef UInt16 MY_mode_t; typedef enum @@ -1262,9 +1363,9 @@ // cp_key_class_t default_protection_class; UInt32 write_generation_counter; UInt32 bsd_flags; - MY__uid_t owner; - MY__gid_t group; - MY__mode_t mode; + MY_uid_t owner; + MY_gid_t group; + MY_mode_t mode; UInt16 pad1; UInt64 uncompressed_size; @@ -1376,32 +1477,32 @@ { CRecordVector Extents; // UInt32 NumLinks; - // CSmallNode(): NumLinks(0) {}; + // CSmallNode(): NumLinks(0) {} }; static const unsigned k_SizeOf_j_inode_val = 0x5c; void CNode::Parse(const Byte *p) { - G64 (0, parent_id); - G64 (0x8, private_id); - G64 (0x10, create_time); - G64 (0x18, mod_time); - G64 (0x20, change_time); - G64 (0x28, access_time); - G64 (0x30, internal_flags); + G64 (0, parent_id) + G64 (0x8, private_id) + G64 (0x10, create_time) + G64 (0x18, mod_time) + G64 (0x20, change_time) + G64 (0x28, access_time) + G64 (0x30, internal_flags) { - G32 (0x38, nchildren); + G32 (0x38, nchildren) // G32 (0x38, nlink); } // G32 (0x3c, default_protection_class); - G32 (0x40, write_generation_counter); - G32 (0x44, bsd_flags); - G32 (0x48, owner); - G32 (0x4c, group); - G16 (0x50, mode); + G32 (0x40, write_generation_counter) + G32 (0x44, bsd_flags) + G32 (0x48, owner) + G32 (0x4c, group) + G16 (0x50, mode) // G16 (0x52, pad1); - G64 (0x54, uncompressed_size); + G64 (0x54, uncompressed_size) } @@ -1414,10 +1515,10 @@ #ifdef APFS_SHOW_ALT_STREAMS unsigned AttrIndex; bool IsAltStream() const { return IsViDef(AttrIndex); } - unsigned GetAttrIndex() const { return AttrIndex; }; + unsigned GetAttrIndex() const { return AttrIndex; } #else // bool IsAltStream() const { return false; } - unsigned GetAttrIndex() const { return VI_MINUS1; }; + unsigned GetAttrIndex() const { return VI_MINUS1; } #endif }; @@ -1429,6 +1530,128 @@ }; +struct CHashChunk +{ + UInt64 lba; + UInt32 hashed_len; // the value is UInt16 + Byte hash[APFS_HASH_MAX_SIZE]; +}; + +typedef CRecordVector CStreamHashes; + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _hashError; + CAlignedBuffer1 _sha; + CMyComPtr _stream; + const CStreamHashes *_hashes; + unsigned _blockSizeLog; + unsigned _chunkIndex; + UInt32 _offsetInChunk; + // UInt64 _size; + + CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } +public: + COutStreamWithHash(): _sha(sizeof(CSha256)) {} + + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + // void ReleaseStream() { _stream.Release(); } + void Init(const CStreamHashes *hashes, unsigned blockSizeLog) + { + _hashes = hashes; + _blockSizeLog = blockSizeLog; + _chunkIndex = 0; + _offsetInChunk = 0; + _hashError = false; + // _size = 0; + } + // UInt64 GetSize() const { return _size; } + bool FinalCheck(); +}; + + +static bool Sha256_Final_and_CheckDigest(CSha256 *sha256, const Byte *digest) +{ + MY_ALIGN (16) + UInt32 temp[SHA256_NUM_DIGEST_WORDS]; + Sha256_Final(sha256, (Byte *)temp); + return memcmp(temp, digest, SHA256_DIGEST_SIZE) == 0; +} + + +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (processedSize) + *processedSize = size; + while (size != 0) + { + if (_hashError) + break; + if (_chunkIndex >= _hashes->Size()) + { + _hashError = true; + break; + } + if (_offsetInChunk == 0) + Sha256_Init(Sha()); + const CHashChunk &chunk = (*_hashes)[_chunkIndex]; + /* (_blockSizeLog <= 16) && chunk.hashed_len is 16-bit. + so we can use 32-bit chunkSize here */ + const UInt32 chunkSize = ((UInt32)chunk.hashed_len << _blockSizeLog); + const UInt32 rem = chunkSize - _offsetInChunk; + UInt32 cur = size; + if (cur > rem) + cur = (UInt32)rem; + Sha256_Update(Sha(), (const Byte *)data, cur); + data = (const void *)((const Byte *)data + cur); + size -= cur; + // _size += cur; + _offsetInChunk += cur; + if (chunkSize == _offsetInChunk) + { + if (!Sha256_Final_and_CheckDigest(Sha(), chunk.hash)) + _hashError = true; + _offsetInChunk = 0; + _chunkIndex++; + } + } + return result; +} + + +bool COutStreamWithHash::FinalCheck() +{ + if (_hashError) + return false; + + if (_offsetInChunk != 0) + { + const CHashChunk &chunk = (*_hashes)[_chunkIndex]; + { + const UInt32 chunkSize = ((UInt32)chunk.hashed_len << _blockSizeLog); + const UInt32 rem = chunkSize - _offsetInChunk; + Byte b = 0; + for (UInt32 i = 0; i < rem; i++) + Sha256_Update(Sha(), &b, 1); + } + if (!Sha256_Final_and_CheckDigest(Sha(), chunk.hash)) + _hashError = true; + _offsetInChunk = 0; + _chunkIndex++; + } + if (_chunkIndex != _hashes->Size()) + _hashError = true; + return !_hashError; +} + + + struct CVol { CObjectVector Nodes; @@ -1439,13 +1662,22 @@ CObjectVector SmallNodes; CRecordVector SmallNodeIDs; + CObjectVector FEXT_Nodes; + CRecordVector FEXT_NodeIDs; + + CObjectVector Hash_Vectors; + CRecordVector Hash_IDs; + unsigned StartRef2Index; // ref2_Index for Refs[0] item unsigned RootRef2Index; // ref2_Index of virtual root folder (Volume1) CApfs apfs; + C_integrity_meta_phys integrity; + bool NodeNotFound; bool ThereAreUnlinkedNodes; bool WrongInodeLink; bool UnsupportedFeature; + bool UnsupportedMethod; unsigned NumItems_In_PrivateDir; unsigned NumAltStreams; @@ -1468,6 +1700,7 @@ ThereAreUnlinkedNodes(false), WrongInodeLink(false), UnsupportedFeature(false), + UnsupportedMethod(false), NumItems_In_PrivateDir(0), NumAltStreams(0) {} @@ -1479,7 +1712,7 @@ const UInt64 s = apfsTime / 1000000000; const UInt32 ns = (UInt32)(apfsTime % 1000000000); ns100 = (ns % 100); - const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(s) + ns / 100; + const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64((Int64)s) + ns / 100; ft.dwLowDateTime = (DWORD)v; ft.dwHighDateTime = (DWORD)(v >> 32); } @@ -1561,10 +1794,33 @@ AddComment_Name(s, "incompatible_features"); s += FlagsToString(g_APFS_INCOMPAT_Flags, - ARRAY_SIZE(g_APFS_INCOMPAT_Flags), + Z7_ARRAY_SIZE(g_APFS_INCOMPAT_Flags), (UInt32)apfs.incompatible_features); s.Add_LF(); + + if (apfs.integrity_meta_oid != 0) + { + /* + AddComment_Name(s, "im_version"); + s.Add_UInt32(integrity.im_version); + s.Add_LF(); + */ + AddComment_Name(s, "im_flags"); + s.Add_UInt32(integrity.im_flags); + s.Add_LF(); + AddComment_Name(s, "im_hash_type"); + const char *p = NULL; + if (integrity.im_hash_type < Z7_ARRAY_SIZE(g_hash_types)) + p = g_hash_types[integrity.im_hash_type]; + if (p) + s += p; + else + s.Add_UInt32(integrity.im_hash_type); + s.Add_LF(); + } + + // AddComment_UInt64(s, "reserve_block_count", apfs.fs_reserve_block_count, false); // AddComment_UInt64(s, "quota_block_count", apfs.fs_quota_block_count); AddComment_UInt64(s, "fs_alloc_count", apfs.fs_alloc_count); @@ -1583,7 +1839,7 @@ AddComment_Time(s, "unmounted", apfs.unmount_time); AddComment_Time(s, "last_modified", apfs.last_mod_time); AddComment_modified_by_t(s, "formatted_by", apfs.formatted_by); - for (unsigned i = 0; i < ARRAY_SIZE(apfs.modified_by); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(apfs.modified_by); i++) { const apfs_modified_by_t &v = apfs.modified_by[i]; if (v.last_xid == 0 && v.timestamp == 0 && v.id[0] == 0) @@ -1611,8 +1867,8 @@ xid_t xid; // The transaction identifier void Parse(const Byte *p) { - G64o (0, oid); - G64x (8, xid); + G64o (0, oid) + G64x (8, xid) } }; @@ -1620,7 +1876,9 @@ #define OMAP_VAL_DELETED (1 << 0) #define OMAP_VAL_SAVED (1 << 1) #define OMAP_VAL_ENCRYPTED (1 << 2) +*/ #define OMAP_VAL_NOHEADER (1 << 3) +/* #define OMAP_VAL_CRYPTO_GENERATION (1 << 4) */ @@ -1628,13 +1886,16 @@ { UInt32 flags; UInt32 size; - paddr_t paddr; + // paddr_t paddr; + paddr_t_unsigned paddr; + + bool IsFlag_NoHeader() const { return (flags & OMAP_VAL_NOHEADER) != 0; } void Parse(const Byte *p) { - G32 (0, flags); - G32 (4, size); - G64 (8, paddr); + G32 (0, flags) + G32 (4, size) + G64 (8, paddr) } }; @@ -1710,6 +1971,7 @@ bool HeadersError; bool ThereAreAltStreams; bool UnsupportedFeature; + bool UnsupportedMethod; CSuperBlock sb; @@ -1726,8 +1988,9 @@ void Clear() { HeadersError = false; - UnsupportedFeature = false; ThereAreAltStreams = false; + UnsupportedFeature = false; + UnsupportedMethod = false; ProgressVal_Cur = 0; ProgressVal_Prev = 0; @@ -1742,8 +2005,9 @@ HRESULT SeekReadBlock_FALSE(UInt64 oid, void *data); void GetItemPath(unsigned index, const CNode *inode, NWindows::NCOM::CPropVariant &path) const; - HRESULT ReadMap(UInt64 oid, CMap &map, unsigned recurseLevel); - HRESULT ReadObjectMap(UInt64 oid, CObjectMap &map); + HRESULT ReadMap(UInt64 oid, bool noHeader, CVol *vol, const Byte *hash, + CMap &map, unsigned recurseLevel); + HRESULT ReadObjectMap(UInt64 oid, CVol *vol, CObjectMap &map); HRESULT OpenVolume(const CObjectMap &omap, const oid_t fs_oid); HRESULT Open2(); @@ -1766,14 +2030,14 @@ { if (ProgressVal_Cur - ProgressVal_Prev >= (1 << 22)) { - RINOK(OpenCallback->SetCompleted(NULL, &ProgressVal_Cur)); + RINOK(OpenCallback->SetCompleted(NULL, &ProgressVal_Cur)) ProgressVal_Prev = ProgressVal_Cur; } ProgressVal_Cur += sb.block_size; } if (oid == 0 || oid >= sb.block_count) return S_FALSE; - RINOK(OpenInStream->Seek(oid << sb.block_size_Log, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(OpenInStream, oid << sb.block_size_Log)) return ReadStream_FALSE(OpenInStream, data, sb.block_size); } @@ -1791,8 +2055,23 @@ } +static bool CheckHash(unsigned hashAlgo, const Byte *data, size_t size, const Byte *digest) +{ + if (hashAlgo == APFS_HASH_SHA256) + { + MY_ALIGN (16) + CSha256 sha; + Sha256_Init(&sha); + Sha256_Update(&sha, data, size); + return Sha256_Final_and_CheckDigest(&sha, digest); + } + return true; +} + -HRESULT CDatabase::ReadMap(UInt64 oid, CMap &map, unsigned recurseLevel) +HRESULT CDatabase::ReadMap(UInt64 oid, bool noHeader, + CVol *vol, const Byte *hash, + CMap &map, unsigned recurseLevel) { // is it allowed to use big number of levels ? if (recurseLevel > (1 << 10)) @@ -1809,12 +2088,16 @@ const Byte *buf; { CByteBuffer &buf2 = Buffers[recurseLevel]; - RINOK(SeekReadBlock_FALSE(oid, buf2)); + RINOK(SeekReadBlock_FALSE(oid, buf2)) buf = buf2; } + if (hash && vol) + if (!CheckHash(vol->integrity.im_hash_type, buf, blockSize, hash)) + return S_FALSE; + CBTreeNodePhys bt; - if (!bt.Parse(buf, blockSize)) + if (!bt.Parse(buf, blockSize, noHeader)) return S_FALSE; map.NumNodes++; @@ -1829,14 +2112,16 @@ - File-system records are sorted according to the rules listed in File-System Objects. */ - if (bt.o.subtype != map.Subtype) + if (!noHeader) + if (bt.ophys.subtype != map.Subtype) return S_FALSE; unsigned endLimit = blockSize; if (recurseLevel == 0) { - if (bt.o.GetType() != OBJECT_TYPE_BTREE) + if (!noHeader) + if (bt.ophys.GetType() != OBJECT_TYPE_BTREE) return S_FALSE; if ((bt.flags & BTNODE_ROOT) == 0) return S_FALSE; @@ -1850,8 +2135,10 @@ return S_FALSE; if (bti.Is_PHYSICAL() != map.IsPhysical) return S_FALSE; + if (bti.Is_NOHEADER() != noHeader) + return S_FALSE; // we don't allow volumes with big number of Keys - const UInt32 kNumItemsMax = k_VectorSizeMax; + const unsigned kNumItemsMax = k_VectorSizeMax; if (map.bti.node_count > kNumItemsMax) return S_FALSE; if (map.bti.key_count > kNumItemsMax) @@ -1859,7 +2146,8 @@ } else { - if (bt.o.GetType() != OBJECT_TYPE_BTREE_NODE) + if (!noHeader) + if (bt.ophys.GetType() != OBJECT_TYPE_BTREE_NODE) return S_FALSE; if ((bt.flags & BTNODE_ROOT) != 0) return S_FALSE; @@ -1925,7 +2213,9 @@ const oid_t oidNext = Get64(p2); if (map.bti.Is_PHYSICAL()) { - RINOK(ReadMap(oidNext, map, recurseLevel + 1)); + RINOK(ReadMap(oidNext, noHeader, vol, + NULL, /* hash */ + map, recurseLevel + 1)) continue; } else @@ -1960,10 +2250,38 @@ continue; } { - if (a.v.off < 8 || a.v.len != 8) + if (a.v.len < 8) return S_FALSE; + + const Byte *hashNew = NULL; + oid_t oidNext = Get64(p2); + + if (bt.Is_HASHED()) + { + if (!vol) + return S_FALSE; + /* + struct btn_index_node_val { + oid_t binv_child_oid; + uint8_t binv_child_hash[BTREE_NODE_HASH_SIZE_MAX]; + }; + */ + /* (a.v.len == 40) is possible if Is_HASHED() + so there is hash (for example, 256-bit) after 64-bit id) */ + if (a.v.len != 8 + vol->integrity.HashSize) + return S_FALSE; + hashNew = p2 + 8; + /* we need to add root_tree_oid here, + but where it's defined in apfs specification ? */ + oidNext += vol->apfs.root_tree_oid; + } + else + { + if (a.v.len != 8) + return S_FALSE; + } + // value is only 64-bit for non leaf. - const oid_t oidNext = Get64(p2); if (map.bti.Is_PHYSICAL()) { @@ -1972,15 +2290,25 @@ // RINOK(ReadMap(oidNext, map, recurseLevel + 1)); // continue; } + /* + else if (map.bti.Is_EPHEMERAL()) + { + // Ephemeral objects are stored in memory while the container is mounted and in a checkpoint when the container isn't mounted + // the code was not tested: + return S_FALSE; + } + */ else { + /* nodes in the B-tree use virtual object identifiers to link to their child nodes. */ const int index = map.Omap.FindKey(oidNext); if (index == -1) return S_FALSE; const omap_val &ov = map.Omap.Vals[(unsigned)index]; if (ov.size != blockSize) // change it : it must be multiple of return S_FALSE; - RINOK(ReadMap(ov.paddr, map, recurseLevel + 1)); + RINOK(ReadMap(ov.paddr, ov.IsFlag_NoHeader(), vol, hashNew, + map, recurseLevel + 1)) continue; } } @@ -1996,19 +2324,23 @@ -HRESULT CDatabase::ReadObjectMap(UInt64 oid, CObjectMap &omap) +HRESULT CDatabase::ReadObjectMap(UInt64 oid, CVol *vol, CObjectMap &omap) { CByteBuffer buf; const size_t blockSize = sb.block_size; buf.Alloc(blockSize); - RINOK(SeekReadBlock_FALSE(oid, buf)); + RINOK(SeekReadBlock_FALSE(oid, buf)) C_omap_phys op; if (!op.Parse(buf, blockSize, oid)) return S_FALSE; CMap map; map.Subtype = OBJECT_TYPE_OMAP; map.IsPhysical = true; - RINOK(ReadMap(op.tree_oid, map, 0)); + RINOK(ReadMap(op.tree_oid, + false /* noHeader */, + vol, + NULL, /* hash */ + map, 0)) if (!omap.Parse(map.Pairs)) return S_FALSE; return S_OK; @@ -2022,7 +2354,7 @@ CSuperBlock2 sb2; { Byte buf[kApfsHeaderSize]; - RINOK(ReadStream_FALSE(OpenInStream, buf, kApfsHeaderSize)); + RINOK(ReadStream_FALSE(OpenInStream, buf, kApfsHeaderSize)) if (!sb.Parse(buf)) return S_FALSE; sb2.Parse(buf); @@ -2030,7 +2362,9 @@ { CObjectMap omap; - RINOK(ReadObjectMap(sb.omap_oid, omap)); + RINOK(ReadObjectMap(sb.omap_oid, + NULL, /* CVol */ + omap)) unsigned numRefs = 0; for (unsigned i = 0; i < sb.max_file_systems; i++) { @@ -2038,7 +2372,7 @@ if (oid == 0) continue; // for (unsigned k = 0; k < 1; k++) // for debug - RINOK(OpenVolume(omap, oid)); + RINOK(OpenVolume(omap, oid)) const unsigned a = Vols.Back().Refs.Size(); numRefs += a; if (numRefs < a) @@ -2104,7 +2438,7 @@ if (ov.size != blockSize) // change it : it must be multiple of return S_FALSE; buf.Alloc(blockSize); - RINOK(SeekReadBlock_FALSE(ov.paddr, buf)); + RINOK(SeekReadBlock_FALSE(ov.paddr, buf)) } CVol &vol = Vols.AddNew(); @@ -2113,14 +2447,107 @@ if (!apfs.Parse(buf, blockSize)) return S_FALSE; + if (apfs.fext_tree_oid != 0) + { + if ((apfs.incompatible_features & APFS_INCOMPAT_SEALED_VOLUME) == 0) + return S_FALSE; + if ((apfs.fext_tree_type & OBJ_PHYSICAL) == 0) + return S_FALSE; + if ((apfs.fext_tree_type & OBJECT_TYPE_MASK) != OBJECT_TYPE_BTREE) + return S_FALSE; + + CMap map2; + map2.Subtype = OBJECT_TYPE_FEXT_TREE; + map2.IsPhysical = true; + + RINOK(ReadMap(apfs.fext_tree_oid, + false /* noHeader */, + &vol, + NULL, /* hash */ + map2, 0)) + + UInt64 prevId = 1; + + FOR_VECTOR (i, map2.Pairs) + { + if (OpenCallback && (i & 0xffff) == 1) + { + const UInt64 numFiles = ProgressVal_NumFilesTotal + + (vol.Items.Size() + vol.Nodes.Size()) / 2; + RINOK(OpenCallback->SetCompleted(&numFiles, &ProgressVal_Cur)) + } + // The key half of a record from a file extent tree. + // struct fext_tree_key + const CKeyValPair &pair = map2.Pairs[i]; + if (pair.Key.Size() != 16) + return S_FALSE; + const Byte *p = pair.Key; + const UInt64 id = GetUi64(p); + if (id < prevId) + return S_FALSE; // IDs must be sorted + prevId = id; + + CExtent ext; + ext.logical_offset = GetUi64(p + 8); + { + if (pair.Val.Size() != 16) + return S_FALSE; + const Byte *p2 = pair.Val; + ext.len_and_flags = GetUi64(p2); + ext.phys_block_num = GetUi64(p2 + 8); + } + + PRF(printf("\n%6d: id=%6d logical_addr = %2d len_and_flags=%5x phys_block_num = %5d", + i, (unsigned)id, + (unsigned)ext.logical_offset, + (unsigned)ext.len_and_flags, + (unsigned)ext.phys_block_num)); + + if (vol.FEXT_NodeIDs.IsEmpty() || + vol.FEXT_NodeIDs.Back() != id) + { + vol.FEXT_NodeIDs.Add(id); + vol.FEXT_Nodes.AddNew(); + } + CRecordVector &extents = vol.FEXT_Nodes.Back().Extents; + if (!extents.IsEmpty()) + if (ext.logical_offset != extents.Back().GetEndOffset()) + return S_FALSE; + extents.Add(ext); + continue; + } + + PRF(printf("\n\n")); + } + /* For each volume, read the root file system tree's virtual object identifier from the apfs_root_tree_oid field, and then look it up in the volume object map indicated by the omap_oid field. */ CMap map; + ReadObjectMap(apfs.omap_oid, &vol, map.Omap); + + const Byte *hash_for_root = NULL; + + if (apfs.integrity_meta_oid != 0) + { + if ((apfs.incompatible_features & APFS_INCOMPAT_SEALED_VOLUME) == 0) + return S_FALSE; + const int index = map.Omap.FindKey(apfs.integrity_meta_oid); + if (index == -1) + return S_FALSE; + const omap_val &ov = map.Omap.Vals[(unsigned)index]; + if (ov.size != blockSize) + return S_FALSE; + RINOK(SeekReadBlock_FALSE(ov.paddr, buf)) + if (!vol.integrity.Parse(buf, blockSize, apfs.integrity_meta_oid)) + return S_FALSE; + if (vol.integrity.im_hash_type != 0) + hash_for_root = vol.integrity.Hash; + } + { - ReadObjectMap(apfs.omap_oid, map.Omap); const int index = map.Omap.FindKey(apfs.root_tree_oid); if (index == -1) return S_FALSE; @@ -2129,7 +2556,9 @@ return S_FALSE; map.Subtype = OBJECT_TYPE_FSTREE; map.IsPhysical = false; - RINOK(ReadMap(ov.paddr, map, 0)); + RINOK(ReadMap(ov.paddr, ov.IsFlag_NoHeader(), + &vol, hash_for_root, + map, 0)) } bool needParseAttr = false; @@ -2152,7 +2581,7 @@ if (OpenCallback) { const UInt64 numFiles = ProgressVal_NumFilesTotal + numApfsItems; - RINOK(OpenCallback->SetTotal(&numFiles, NULL)); + RINOK(OpenCallback->SetTotal(&numFiles, NULL)) } } @@ -2165,7 +2594,7 @@ { const UInt64 numFiles = ProgressVal_NumFilesTotal + (vol.Items.Size() + vol.Nodes.Size()) / 2; - RINOK(OpenCallback->SetCompleted(&numFiles, &ProgressVal_Cur)); + RINOK(OpenCallback->SetCompleted(&numFiles, &ProgressVal_Cur)) } const CKeyValPair &pair = map.Pairs[i]; @@ -2180,11 +2609,11 @@ return S_FALSE; // IDs must be sorted prevId = id; - PRF(printf("\n%6d: id=%6d type = %2d", i, (unsigned)id, type)); + PRF(printf("\n%6d: id=%6d type = %2d ", i, (unsigned)id, type)); if (type == APFS_TYPE_INODE) { - PRF(printf (" INODE")); + PRF(printf("INODE")); if (pair.Key.Size() != 8 || pair.Val.Size() < k_SizeOf_j_inode_val) return S_FALSE; @@ -2224,6 +2653,9 @@ UInt32 offset = 4 + (UInt32)xf_num_exts * 4; if (offset + xf_used_data != extraSize) return S_FALSE; + + PRF(printf(" parent_id = %d", (unsigned)inode.parent_id)); + for (unsigned k = 0; k < xf_num_exts; k++) { // struct x_field @@ -2336,7 +2768,7 @@ attr.Id = Get64(p4); attr.dstream.Parse(p4 + 8); attr.dstream_defined = true; - PRF(printf(" streamID=%d", (unsigned)attr.Id)); + PRF(printf(" streamID=%d streamSize=%d", (unsigned)attr.Id, (unsigned)attr.dstream.size)); } else { @@ -2386,7 +2818,7 @@ const UInt32 refcnt = Get32(pair.Val); // The data stream record can be deleted when its reference count reaches zero. - PRF(printf(" refcnt = %8d", (unsigned)refcnt)); + PRF(printf(" refcnt = %d", (unsigned)refcnt)); if (vol.NodeIDs.IsEmpty()) return S_FALSE; @@ -2407,6 +2839,7 @@ inode.refcnt_defined = true; if (inode.refcnt != (UInt32)inode.nlink) { + PRF(printf(" refcnt != nlink")); // is it possible ? // return S_FALSE; } @@ -2536,13 +2969,138 @@ if (id == PRIV_DIR_INO_NUM) vol.NumItems_In_PrivateDir++; - PRF(printf(" next=%6d flags=%2x %s", + PRF(printf(" DIR_REC next=%6d flags=%2x %s", (unsigned)item.Val.file_id, (unsigned)item.Val.flags, item.Name.Ptr())); continue; } - + + if (type == APFS_TYPE_FILE_INFO) + { + if (pair.Key.Size() != 16) + return S_FALSE; + // j_file_info_key + const UInt64 info_and_lba = Get64(p + 8); + + #define J_FILE_INFO_LBA_MASK 0x00ffffffffffffffUL + // #define J_FILE_INFO_TYPE_MASK 0xff00000000000000UL + #define J_FILE_INFO_TYPE_SHIFT 56 + #define APFS_FILE_INFO_DATA_HASH 1 + + const unsigned infoType = (unsigned)(info_and_lba >> J_FILE_INFO_TYPE_SHIFT); + // address is a paddr_t + const UInt64 lba = info_and_lba & J_FILE_INFO_LBA_MASK; + // j_file_data_hash_val_t + /* Use this field of the union if the type stored in the info_and_lba field of j_file_info_val_t is + APFS_FILE_INFO_DATA_HASH */ + if (infoType != APFS_FILE_INFO_DATA_HASH) + return S_FALSE; + if (pair.Val.Size() != 3 + vol.integrity.HashSize) + return S_FALSE; + /* + struct j_file_data_hash_val + { + UInt16 hashed_len; // The length, in blocks, of the data segment that was hashed. + UInt8 hash_size; // must be consistent with integrity_meta_phys_t::im_hash_type + UInt8 hash[0]; + } + */ + + const unsigned hash_size = pair.Val[2]; + if (hash_size != vol.integrity.HashSize) + return S_FALSE; + + CHashChunk hr; + hr.hashed_len = GetUi16(pair.Val); + if (hr.hashed_len == 0) + return S_FALSE; + memcpy(hr.hash, (const Byte *)pair.Val + 3, vol.integrity.HashSize); + // (hashed_len <= 4) : we have seen + hr.lba = lba; + + PRF(printf(" FILE_INFO lba = %6x, hashed_len=%6d", + (unsigned)lba, + (unsigned)hr.hashed_len)); + + if (vol.Hash_IDs.IsEmpty() || vol.Hash_IDs.Back() != id) + { + vol.Hash_Vectors.AddNew(); + vol.Hash_IDs.Add(id); + } + CStreamHashes &hashes = vol.Hash_Vectors.Back(); + if (hashes.Size() != 0) + { + const CHashChunk &hr_Back = hashes.Back(); + if (lba != hr_Back.lba + ((UInt64)hr_Back.hashed_len << sb.block_size_Log)) + return S_FALSE; + } + hashes.Add(hr); + continue; + } + + if (type == APFS_TYPE_SNAP_METADATA) + { + if (pair.Key.Size() != 8) + return S_FALSE; + PRF(printf(" SNAP_METADATA")); + // continue; + } + + /* SIBLING items are used, if there are more than one hard link to some inode + key : value + parent_id_1 DIR_REC : inode_id, name_1 + parent_id_2 DIR_REC : inode_id, name_2 + inode_id INODE : parent_id_1, name_1 + inode_id SIBLING_LINK sibling_id_1 : parent_id_1, name_1 + inode_id SIBLING_LINK sibling_id_2 : parent_id_2, name_2 + sibling_id_1 SIBLING_MAP : inode_id + sibling_id_2 SIBLING_MAP : inode_id + */ + + if (type == APFS_TYPE_SIBLING_LINK) + { + if (pair.Key.Size() != 16) + return S_FALSE; + if (pair.Val.Size() < 10 + 1) + return S_FALSE; + /* + // struct j_sibling_key + // The sibling's unique identifier. + // This value matches the object identifier for the sibling map record + const UInt64 sibling_id = Get64(p + 8); + // struct j_sibling_val + const Byte *v = pair.Val; + const UInt64 parent_id = Get64(v); // The object identifier for the inode that's the parent directory. + const unsigned name_len = Get16(v + 8); // len including the final null character + if (10 + name_len != pair.Val.Size()) + return S_FALSE; + if (v[10 + name_len - 1] != 0) + return S_FALSE; + AString name ((const char *)(v + 10)); + if (name.Len() != name_len - 1) + return S_FALSE; + PRF(printf(" SIBLING_LINK sibling_id = %6d : parent_id=%6d %s", + (unsigned)sibling_id, (unsigned)parent_id, name.Ptr())); + */ + continue; + } + + if (type == APFS_TYPE_SIBLING_MAP) + { + // struct j_sibling_map_key + // The object identifier in the header is the sibling's unique identifier + if (pair.Key.Size() != 8 || pair.Val.Size() != 8) + return S_FALSE; + /* + // j_sibling_map_val + // The inode number of the underlying file + const UInt64 file_id = Get64(pair.Val); + PRF(printf(" SIBLING_MAP : file_id = %d", (unsigned)file_id)); + */ + continue; + } + UnsupportedFeature = true; // return S_FALSE; } @@ -2596,7 +3154,7 @@ RINOK(OpenCallback->SetCompleted( &ProgressVal_NumFilesTotal, - &ProgressVal_Cur)); + &ProgressVal_Cur)) ProgressVal_Prev = ProgressVal_Cur; } } @@ -2623,7 +3181,7 @@ } else { - vol.UnsupportedFeature = true; + vol.UnsupportedMethod = true; } } } @@ -2635,6 +3193,8 @@ HeadersError = true; if (vol.UnsupportedFeature) UnsupportedFeature = true; + if (vol.UnsupportedMethod) + UnsupportedMethod = true; if (vol.NumAltStreams != 0) ThereAreAltStreams = true; @@ -2863,38 +3423,39 @@ -class CHandler: +Z7_class_CHandler_final: public IInArchive, public IArchiveGetRawProps, public IInArchiveGetStream, public CMyUnknownImp, public CDatabase { + Z7_IFACES_IMP_UNK_3( + IInArchive, + IArchiveGetRawProps, + IInArchiveGetStream) + CMyComPtr _stream; -public: - MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + int FindHashIndex_for_Item(UInt32 index); }; -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); OpenInStream = inStream; OpenCallback = callback; - RINOK(Open2()); + RINOK(Open2()) _stream = inStream; return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _stream.Release(); Clear(); @@ -2971,7 +3532,7 @@ } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -3006,6 +3567,7 @@ { UInt32 flags = 0; if (UnsupportedFeature) flags |= kpv_ErrorFlags_UnsupportedFeature; + if (UnsupportedMethod) flags |= kpv_ErrorFlags_UnsupportedMethod; if (flags != 0) prop = flags; break; @@ -3068,14 +3630,14 @@ } -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = 0; @@ -3083,7 +3645,7 @@ } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; @@ -3109,13 +3671,13 @@ } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; *propType = 0; - UNUSED_VAR(index); - UNUSED_VAR(propID); + UNUSED_VAR(index) + UNUSED_VAR(propID) return S_OK; } @@ -3133,7 +3695,7 @@ s.Add_UInt64(id); if (!inode.PrimaryName.IsEmpty()) { - s += '.'; + s.Add_Dot(); UString s2; Utf8Name_to_InterName(inode.PrimaryName, s2); s += s2; @@ -3184,7 +3746,7 @@ #ifdef APFS_SHOW_ALT_STREAMS if (IsViDef(ref.AttrIndex) && inode) { - s += ':'; + s.Add_Colon(); Utf8Name_to_InterName(inode->Attrs[(unsigned)ref.AttrIndex].Name, s2); // s2 += "a\\b"; // for debug s += s2; @@ -3204,7 +3766,7 @@ -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -3509,8 +4071,8 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN const bool allFilesMode = (numItems == (UInt32)(Int32)-1); @@ -3519,7 +4081,6 @@ if (numItems == 0) return S_OK; UInt32 i; - { UInt64 totalSize = 0; for (i = 0; i < numItems; i++) @@ -3527,25 +4088,29 @@ const UInt32 index = allFilesMode ? i : indices[i]; totalSize += GetSize(index); } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) } UInt64 currentTotalSize = 0, currentItemSize = 0; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + CMyComPtr2_Create copyCoder; - NHfs::CDecoder decoder; + // We don't know if zlib without Adler is allowed in APFS. + // But zlib without Adler is allowed in HFS. + // So here we allow apfs/zlib without Adler: + NHfs::CDecoder decoder(true); // IsAdlerOptional - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + for (i = 0;; i++, currentTotalSize += currentItemSize) { lps->InSize = currentTotalSize; lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + + if (i >= numItems) + break; const UInt32 index = allFilesMode ? i : indices[i]; const CRef2 &ref2 = Refs2[index]; @@ -3553,17 +4118,18 @@ currentItemSize = GetSize(index); + int opRes; + { CMyComPtr realOutStream; - const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (IsViNotDef(ref2.RefIndex)) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -3580,14 +4146,14 @@ if (isDir) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - int opRes = NExtract::NOperationResult::kDataError; + RINOK(extractCallback->PrepareOperation(askMode)) + opRes = NExtract::NOperationResult::kDataError; if (IsViDef(ref.NodeIndex)) { @@ -3643,32 +4209,93 @@ CMyComPtr inStream; if (GetStream(index, &inStream) == S_OK && inStream) { - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + CMyComPtr2 hashStream; + + if (vol.integrity.Is_SHA256()) + { + const int hashIndex = FindHashIndex_for_Item(index); + if (hashIndex != -1) + { + hashStream.Create_if_Empty(); + hashStream->SetStream(realOutStream); + hashStream->Init(&(vol.Hash_Vectors[(unsigned)hashIndex]), sb.block_size_Log); + } + } + + RINOK(copyCoder.Interface()->Code(inStream, + hashStream.IsDefined() ? + hashStream.Interface() : + realOutStream.Interface(), + NULL, NULL, lps)) opRes = NExtract::NOperationResult::kDataError; - if (copyCoderSpec->TotalSize == currentItemSize) + if (copyCoder->TotalSize == currentItemSize) + { opRes = NExtract::NOperationResult::kOK; - else if (copyCoderSpec->TotalSize < currentItemSize) + if (hashStream.IsDefined()) + if (!hashStream->FinalCheck()) + opRes = NExtract::NOperationResult::kCRCError; + } + else if (copyCoder->TotalSize < currentItemSize) opRes = NExtract::NOperationResult::kUnexpectedEnd; } } } - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = Refs2.Size(); return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +int CHandler::FindHashIndex_for_Item(UInt32 index) +{ + const CRef2 &ref2 = Refs2[index]; + const CVol &vol = Vols[ref2.VolIndex]; + if (IsViNotDef(ref2.RefIndex)) + return -1; + + const CRef &ref = vol.Refs[ref2.RefIndex]; + if (IsViNotDef(ref.NodeIndex)) + return -1; + const CNode &inode = vol.Nodes[ref.NodeIndex]; + + unsigned attrIndex = ref.GetAttrIndex(); + + if (IsViNotDef(attrIndex) + && !inode.dstream_defined + && inode.IsSymLink()) + { + attrIndex = inode.SymLinkIndex; + if (IsViNotDef(attrIndex)) + return -1; + } + + if (IsViDef(attrIndex)) + { + /* we have seen examples, where hash available for "com.apple.ResourceFork" stream. + these hashes for "com.apple.ResourceFork" stream are for unpacked data. + but the caller here needs packed data of stream. So we don't use hashes */ + return -1; + } + else + { + if (!inode.dstream_defined) + return -1; + const UInt64 id = vol.NodeIDs[ref.NodeIndex]; + return vol.Hash_IDs.FindInSorted(id); + } +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { *stream = NULL; @@ -3701,16 +4328,22 @@ const CAttr &attr = inode.Attrs[(unsigned)attrIndex]; if (!attr.dstream_defined) { - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Init(attr.Data, attr.Data.Size(), (IInArchive *)this); + CMyComPtr2 streamTemp; + streamTemp.Create_if_Empty(); + streamTemp->Init(attr.Data, attr.Data.Size(), (IInArchive *)this); *stream = streamTemp.Detach(); return S_OK; } const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id); - if (idIndex == -1) - return S_FALSE; - extents = &vol.SmallNodes[(unsigned)idIndex].Extents; + if (idIndex != -1) + extents = &vol.SmallNodes[(unsigned)idIndex].Extents; + else + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(attr.Id); + if (fext_Index == -1) + return S_FALSE; + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].Extents; + } rem = attr.dstream.size; } else @@ -3720,16 +4353,21 @@ return S_FALSE; if (inode.IsDir()) return S_FALSE; + extents = &inode.Extents; if (inode.dstream_defined) { rem = inode.dstream.size; + if (inode.Extents.Size() == 0) + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(vol.NodeIDs[ref.NodeIndex]); + if (fext_Index != -1) + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].Extents; + } } else { // return S_FALSE; // check it !!! How zero size files are stored with dstream_defined? } - - extents = &inode.Extents; } return GetStream2(_stream, extents, rem, stream); } @@ -3742,9 +4380,9 @@ *stream = NULL; if (!attr.dstream_defined) { - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Init(attr.Data, attr.Data.Size(), (IInArchive *)this); + CMyComPtr2 streamTemp; + streamTemp.Create_if_Empty(); + streamTemp->Init(attr.Data, attr.Data.Size(), (IInArchive *)this); *stream = streamTemp.Detach(); return S_OK; } @@ -3755,13 +4393,20 @@ HRESULT CDatabase::GetAttrStream_dstream( IInStream *apfsInStream, const CVol &vol, const CAttr &attr, ISequentialInStream **stream) { - const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id); - if (idIndex == -1) - return S_FALSE; - return GetStream2(apfsInStream, - &vol.SmallNodes[(unsigned)idIndex].Extents, - attr.dstream.size, - stream); + const CRecordVector *extents; + { + const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id); + if (idIndex != -1) + extents = &vol.SmallNodes[(unsigned)idIndex].Extents; + else + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(attr.Id); + if (fext_Index == -1) + return S_FALSE; + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].Extents; + } + } + return GetStream2(apfsInStream, extents, attr.dstream.size, stream); } @@ -3770,8 +4415,8 @@ const CRecordVector *extents, UInt64 rem, ISequentialInStream **stream) { - CExtentsStream *extentStreamSpec = new CExtentsStream(); - CMyComPtr extentStream = extentStreamSpec; + CMyComPtr2 extentStream; + extentStream.Create_if_Empty(); UInt64 virt = 0; FOR_VECTOR (i, *extents) @@ -3795,7 +4440,7 @@ se.Virt = virt; virt += cur; rem -= cur; - extentStreamSpec->Extents.Add(se); + extentStream->Extents.Add(se); if (rem == 0) if (i != extents->Size() - 1) return S_FALSE; @@ -3807,9 +4452,9 @@ CSeekExtent se; se.Phy = 0; se.Virt = virt; - extentStreamSpec->Extents.Add(se); - extentStreamSpec->Stream = apfsInStream; - extentStreamSpec->Init(); + extentStream->Extents.Add(se); + extentStream->Stream = apfsInStream; + extentStream->Init(); *stream = extentStream.Detach(); return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ApmHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApmHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ApmHandler.cpp 2021-01-24 16:10:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ApmHandler.cpp 2024-11-22 10:00:00.000000000 +0000 @@ -5,36 +5,62 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" -#include "../../Common/Defs.h" -#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" #include "../Common/RegisterArc.h" #include "../Common/StreamUtils.h" #include "HandlerCont.h" -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) +#define Get32(p) GetBe32a(p) using namespace NWindows; namespace NArchive { + +namespace NDmg { + const char *Find_Apple_FS_Ext(const AString &name); + bool Is_Apple_FS_Or_Unknown(const AString &name); +} + namespace NApm { static const Byte kSig0 = 'E'; static const Byte kSig1 = 'R'; +static const CUInt32PCharPair k_Flags[] = +{ + { 0, "VALID" }, + { 1, "ALLOCATED" }, + { 2, "IN_USE" }, + { 3, "BOOTABLE" }, + { 4, "READABLE" }, + { 5, "WRITABLE" }, + { 6, "OS_PIC_CODE" }, + // { 7, "OS_SPECIFIC_2" }, // "Unused" + { 8, "ChainCompatible" }, // "OS_SPECIFIC_1" + { 9, "RealDeviceDriver" }, + // { 10, "CanChainToNext" }, + { 30, "MOUNTED_AT_STARTUP" }, + { 31, "STARTUP" } +}; + +#define DPME_FLAGS_VALID (1u << 0) +#define DPME_FLAGS_ALLOCATED (1u << 1) + +static const unsigned k_Str_Size = 32; + struct CItem { UInt32 StartBlock; UInt32 NumBlocks; - char Name[32]; - char Type[32]; + UInt32 Flags; // pmPartStatus + char Name[k_Str_Size]; + char Type[k_Str_Size]; /* UInt32 DataStartBlock; UInt32 NumDataBlocks; - UInt32 Status; UInt32 BootStartBlock; UInt32 BootSize; UInt32 BootAddr; @@ -43,152 +69,212 @@ char Processor[16]; */ - bool Parse(const Byte *p, UInt32 &numBlocksInMap) + bool Is_Valid_and_Allocated() const + { return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; } + + bool Parse(const UInt32 *p32, UInt32 &numBlocksInMap) { - numBlocksInMap = Get32(p + 4); - StartBlock = Get32(p + 8); - NumBlocks = Get32(p + 0xC); - memcpy(Name, p + 0x10, 32); - memcpy(Type, p + 0x30, 32); - if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0) + if (GetUi32a(p32) != 0x4d50) // "PM" return false; + numBlocksInMap = Get32(p32 + 4 / 4); + StartBlock = Get32(p32 + 8 / 4); + NumBlocks = Get32(p32 + 0xc / 4); + Flags = Get32(p32 + 0x58 / 4); + memcpy(Name, p32 + 0x10 / 4, k_Str_Size); + memcpy(Type, p32 + 0x30 / 4, k_Str_Size); /* DataStartBlock = Get32(p + 0x50); NumDataBlocks = Get32(p + 0x54); - Status = Get32(p + 0x58); - BootStartBlock = Get32(p + 0x5C); + BootStartBlock = Get32(p + 0x5c); BootSize = Get32(p + 0x60); BootAddr = Get32(p + 0x64); if (Get32(p + 0x68) != 0) return false; - BootEntry = Get32(p + 0x6C); + BootEntry = Get32(p + 0x6c); if (Get32(p + 0x70) != 0) return false; BootChecksum = Get32(p + 0x74); - memcpy(Processor, p + 0x78, 16); + memcpy(Processor, p32 + 0x78 / 4, 16); */ return true; } }; -class CHandler: public CHandlerCont + +Z7_class_CHandler_final: public CHandlerCont { + Z7_IFACE_COM7_IMP(IInArchive_Cont) + CRecordVector _items; unsigned _blockSizeLog; - UInt32 _numBlocks; - UInt64 _phySize; bool _isArc; + // UInt32 _numBlocks; + UInt64 _phySize; - HRESULT ReadTables(IInStream *stream); UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override { const CItem &item = _items[index]; pos = BlocksToBytes(item.StartBlock); size = BlocksToBytes(item.NumBlocks); return NExtract::NOperationResult::kOK; } - -public: - INTERFACE_IInArchive_Cont(;) }; static const UInt32 kSectorSize = 512; +// we support only 4 cluster sizes: 512, 1024, 2048, 4096 */ + API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size) { if (size < kSectorSize) return k_IsArc_Res_NEED_MORE; - if (p[0] != kSig0 || p[1] != kSig1) + if (GetUi32(p + 12) != 0) + return k_IsArc_Res_NO; + UInt32 v = GetUi32(p); // we read as little-endian + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) return k_IsArc_Res_NO; - unsigned i; - for (i = 8; i < 16; i++) - if (p[i] != 0) - return k_IsArc_Res_NO; - UInt32 blockSize = Get16(p + 2); - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i >= 12) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; + if ((0x116u >> (v >> 17)) & 1) + return k_IsArc_Res_YES; + return k_IsArc_Res_NO; } } -HRESULT CHandler::ReadTables(IInStream *stream) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)) { - Byte buf[kSectorSize]; + COM_TRY_BEGIN + Close(); + + UInt32 buf32[kSectorSize / 4]; + unsigned numPadSectors, blockSizeLog_from_Header; { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - if (buf[0] != kSig0 || buf[1] != kSig1) + // Driver Descriptor Map (DDM) + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + // 8: UInt16 sbDevType : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 10: UInt16 sbDevId : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 12: UInt32 sbData : =0 + if (buf32[3] != 0) return S_FALSE; - UInt32 blockSize = Get16(buf + 2); - unsigned i; - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i >= 12) - return S_FALSE; - _blockSizeLog = i; - _numBlocks = Get32(buf + 4); - for (i = 8; i < 16; i++) - if (buf[i] != 0) - return S_FALSE; + UInt32 v = GetUi32a(buf32); // we read as little-endian + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) + return S_FALSE; + v >>= 16; + if (v == 0) + return S_FALSE; + if (v & (v - 1)) + return S_FALSE; + // v == { 16,8,4,2 } : block size (x256 bytes) + const unsigned a = +#if 1 + (0x30210u >> v) & 3; +#else + 0; // for debug : hardcoded switch to 512-bytes mode +#endif + numPadSectors = (1u << a) - 1; + _blockSizeLog = blockSizeLog_from_Header = 9 + a; } - unsigned numSkips = (unsigned)1 << (_blockSizeLog - 9); - for (unsigned j = 1; j < numSkips; j++) +/* + some APMs (that are ".iso" macOS installation files) contain + (blockSizeLog == 11) in DDM header, + and contain 2 overlapping maps: + 1) map for 512-bytes-step + 2) map for 2048-bytes-step + 512-bytes-step map is correct. + 2048-bytes-step map can be incorrect in some cases. + + macos 8 / OSX DP2 iso: + There is shared "hfs" item in both maps. + And correct (offset/size) values for "hfs" partition + can be calculated only in 512-bytes mode (ignoring blockSizeLog == 11). + But some records (Macintosh.Apple_Driver*_) + can be correct on both modes: 512-bytes mode / 2048-bytes-step. + + macos 921 ppc / Apple Mac OS X 10.3.0 iso: + Both maps are correct. + If we use 512-bytes-step, each 4th item is (Apple_Void) with zero size. + And these zero size (Apple_Void) items will be first items in 2048-bytes-step map. +*/ + +// we define Z7_APM_SWITCH_TO_512_BYTES, because +// we want to support old MACOS APMs that contain correct value only +// for 512-bytes-step mode +#define Z7_APM_SWITCH_TO_512_BYTES + + const UInt32 numBlocks_from_Header = Get32(buf32 + 1); + UInt32 numBlocks = 0; { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); + for (unsigned k = 0; k < numPadSectors; k++) + { + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (k == 0) + { + if (GetUi32a(buf32) == 0x4d50 // "PM" + // && (Get32(buf32 + 0x58 / 4) & 1) // Flags::VALID + // some old APMs don't use VALID flag for Apple_partition_map item + && Get32(buf32 + 8 / 4) == 1) // StartBlock + { + // we switch the mode to 512-bytes-step map reading: + numPadSectors = 0; + _blockSizeLog = 9; + break; + } + } +#endif + } } - UInt32 numBlocksInMap = 0; - for (unsigned i = 0;;) { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (i != 0 || _blockSizeLog == blockSizeLog_from_Header) +#endif + { + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + } CItem item; - - UInt32 numBlocksInMap2 = 0; - if (!item.Parse(buf, numBlocksInMap2)) + UInt32 numBlocksInMap = 0; + if (!item.Parse(buf32, numBlocksInMap)) return S_FALSE; - if (i == 0) - { - numBlocksInMap = numBlocksInMap2; - if (numBlocksInMap > (1 << 8)) - return S_FALSE; - } - else if (numBlocksInMap2 != numBlocksInMap) + // v24.09: we don't check that all entries have same (numBlocksInMap) values, + // because some APMs have different (numBlocksInMap) values, if (Apple_Void) is used. + if (numBlocksInMap > (1 << 8) || numBlocksInMap <= i) return S_FALSE; - UInt32 finish = item.StartBlock + item.NumBlocks; + const UInt32 finish = item.StartBlock + item.NumBlocks; if (finish < item.StartBlock) return S_FALSE; - _numBlocks = MyMax(_numBlocks, finish); + if (numBlocks < finish) + numBlocks = finish; _items.Add(item); - for (unsigned j = 1; j < numSkips; j++) + if (numPadSectors != 0) { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); + RINOK(stream->Seek(numPadSectors << 9, STREAM_SEEK_CUR, NULL)) } if (++i == numBlocksInMap) break; } - _phySize = BlocksToBytes(_numBlocks); + _phySize = BlocksToBytes(numBlocks); + // _numBlocks = numBlocks; + const UInt64 physSize = (UInt64)numBlocks_from_Header << blockSizeLog_from_Header; + if (_phySize < physSize) + _phySize = physSize; _isArc = true; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(ReadTables(stream)); _stream = stream; + return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() + +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _phySize = 0; @@ -197,30 +283,31 @@ return S_OK; } + static const Byte kProps[] = { kpidPath, kpidSize, - kpidOffset + kpidOffset, + kpidCharacts + // , kpidCpu }; static const Byte kArcProps[] = { kpidClusterSize + // , kpidNumBlocks }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -static AString GetString(const char *s) +static void GetString(AString &dest, const char *src) { - AString res; - for (unsigned i = 0; i < 32 && s[i] != 0; i++) - res += s[i]; - return res; + dest.SetFrom_CalcLen(src, k_Str_Size); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -231,11 +318,14 @@ int mainIndex = -1; FOR_VECTOR (i, _items) { - AString s (GetString(_items[i].Type)); - if (s != "Apple_Free" && - s != "Apple_partition_map") + const CItem &item = _items[i]; + if (!item.Is_Valid_and_Allocated()) + continue; + AString s; + GetString(s, item.Type); + if (NDmg::Is_Apple_FS_Or_Unknown(s)) { - if (mainIndex >= 0) + if (mainIndex != -1) { mainIndex = -1; break; @@ -243,12 +333,13 @@ mainIndex = (int)i; } } - if (mainIndex >= 0) - prop = (UInt32)mainIndex; + if (mainIndex != -1) + prop = (UInt32)(Int32)mainIndex; break; } case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; case kpidPhySize: prop = _phySize; break; + // case kpidNumBlocks: prop = _numBlocks; break; case kpidErrorFlags: { @@ -263,13 +354,13 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -278,25 +369,41 @@ { case kpidPath: { - AString s (GetString(item.Name)); + AString s; + GetString(s, item.Name); if (s.IsEmpty()) s.Add_UInt32(index); - AString type (GetString(item.Type)); - if (type == "Apple_HFS") - type = "hfs"; + AString type; + GetString(type, item.Type); + { + const char *ext = NDmg::Find_Apple_FS_Ext(type); + if (ext) + type = ext; + } if (!type.IsEmpty()) { - s += '.'; + s.Add_Dot(); s += type; } prop = s; break; } +/* + case kpidCpu: + { + AString s; + s.SetFrom_CalcLen(item.Processor, sizeof(item.Processor)); + if (!s.IsEmpty()) + prop = s; + break; + } +*/ case kpidSize: case kpidPackSize: prop = BlocksToBytes(item.NumBlocks); break; case kpidOffset: prop = BlocksToBytes(item.StartBlock); break; + case kpidCharacts: FLAGS_TO_PROP(k_Flags, item.Flags, prop); break; } prop.Detach(value); return S_OK; @@ -306,7 +413,7 @@ static const Byte k_Signature[] = { kSig0, kSig1 }; REGISTER_ARC_I( - "APM", "apm", 0, 0xD4, + "APM", "apm", NULL, 0xD4, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ArHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ArHandler.cpp 2022-04-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArHandler.cpp 2025-06-16 10:00:00.000000000 +0000 @@ -56,10 +56,8 @@ */ static const unsigned kSignatureLen = 8; - -#define SIGNATURE { '!', '<', 'a', 'r', 'c', 'h', '>', 0x0A } - -static const Byte kSignature[kSignatureLen] = SIGNATURE; +static const Byte kSignature[kSignatureLen] = + { '!', '<', 'a', 'r', 'c', 'h', '>', 0x0A }; static const unsigned kNameSize = 16; static const unsigned kTimeSize = 12; @@ -136,16 +134,16 @@ HRESULT Open(IInStream *inStream); HRESULT SkipData(UInt64 dataSize) { - return m_Stream->Seek(dataSize + (dataSize & 1), STREAM_SEEK_CUR, &Position); + return m_Stream->Seek((Int64)(dataSize + (dataSize & 1)), STREAM_SEEK_CUR, &Position); } }; HRESULT CInArchive::Open(IInStream *inStream) { SubType = kSubType_None; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &Position)); + RINOK(InStream_GetPos(inStream, Position)) char signature[kSignatureLen]; - RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)); + RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)) Position += kSignatureLen; if (memcmp(signature, kSignature, kSignatureLen) != 0) return S_FALSE; @@ -215,7 +213,7 @@ size_t processedSize = sizeof(header); item.HeaderPos = Position; item.HeaderSize = kHeaderSize; - RINOK(ReadStream(m_Stream, header, &processedSize)); + RINOK(ReadStream(m_Stream, header, &processedSize)) if (processedSize != sizeof(header)) return S_OK; if (header[kHeaderSize - 2] != 0x60 || @@ -235,7 +233,7 @@ cur[3] != 0) { // BSD variant - RIF(DecimalToNumber32(cur + 3, kNameSize - 3 , longNameLen)); + RIF(DecimalToNumber32(cur + 3, kNameSize - 3 , longNameLen)) if (longNameLen >= (1 << 12)) longNameLen = 0; } @@ -247,11 +245,11 @@ } cur += kNameSize; - RIF(DecimalToNumber32(cur, kTimeSize, item.MTime)); cur += kTimeSize; - RIF(DecimalToNumber32(cur, kUserSize, item.User)); cur += kUserSize; - RIF(DecimalToNumber32(cur, kUserSize, item.Group)); cur += kUserSize; - RIF(OctalToNumber32(cur, kModeSize, item.Mode)); cur += kModeSize; - RIF(DecimalToNumber(cur, kSizeSize, item.Size)); cur += kSizeSize; + RIF(DecimalToNumber32(cur, kTimeSize, item.MTime)) cur += kTimeSize; + RIF(DecimalToNumber32(cur, kUserSize, item.User)) cur += kUserSize; + RIF(DecimalToNumber32(cur, kUserSize, item.Group)) cur += kUserSize; + RIF(OctalToNumber32(cur, kModeSize, item.Mode)) cur += kModeSize; + RIF(DecimalToNumber(cur, kSizeSize, item.Size)) cur += kSizeSize; if (longNameLen != 0 && longNameLen <= item.Size) { @@ -260,7 +258,7 @@ char *s = item.Name.GetBuf(longNameLen); HRESULT res = ReadStream(m_Stream, s, &processedSize); item.Name.ReleaseBuf_CalcLen(longNameLen); - RINOK(res); + RINOK(res) if (processedSize != longNameLen) return S_OK; item.Size -= longNameLen; @@ -272,24 +270,22 @@ return S_OK; } -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + bool _isArc; CObjectVector _items; CMyComPtr _stream; - Int32 _mainSubfile; UInt64 _phySize; + Int32 _mainSubfile; EType _type; ESubType _subType; int _longNames_FileIndex; - AString _libFiles[2]; unsigned _numLibFiles; AString _errorMessage; - bool _isArc; - + AString _libFiles[2]; void UpdateErrorMessage(const char *s); @@ -298,16 +294,12 @@ int FindItem(UInt32 offset) const; HRESULT AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos); HRESULT ParseLibSymbols(IInStream *stream, unsigned fileIndex); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; void CHandler::UpdateErrorMessage(const char *s) { if (!_errorMessage.IsEmpty()) - _errorMessage += '\n'; + _errorMessage.Add_LF(); _errorMessage += s; } @@ -333,7 +325,7 @@ { unsigned i; for (i = 0; i < _items.Size(); i++) - if (_items[i].Name == "//") + if (_items[i].Name.IsEqualTo("//")) break; if (i == _items.Size()) return S_OK; @@ -342,11 +334,11 @@ const CItem &item = _items[fileIndex]; if (item.Size > ((UInt32)1 << 30)) return S_FALSE; - RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, item.GetDataPos())) const size_t size = (size_t)item.Size; CByteArr p(size); - RINOK(ReadStream_FALSE(stream, p, size)); + RINOK(ReadStream_FALSE(stream, p, size)) for (i = 0; i < _items.Size(); i++) { @@ -365,15 +357,15 @@ { if (pos >= size) return S_FALSE; - char c = p[pos]; + const Byte c = p[pos]; if (c == 0 || c == 0x0A) break; pos++; } - item2.Name.SetFrom((const char *)(p + start), pos - start); + item2.Name.SetFrom((const char *)(p + start), (unsigned)(pos - start)); } - _longNames_FileIndex = fileIndex; + _longNames_FileIndex = (int)fileIndex; return S_OK; } @@ -386,7 +378,7 @@ if (item.Name[0] == '/') continue; CItem &prev = _items[i - 1]; - if (item.Name == prev.Name) + if (item.Name.IsEqualTo(prev.Name)) { if (prev.SameNameIndex < 0) prev.SameNameIndex = 0; @@ -399,7 +391,7 @@ if (item.SameNameIndex < 0) continue; char sz[32]; - ConvertUInt32ToString(item.SameNameIndex + 1, sz); + ConvertUInt32ToString((unsigned)item.SameNameIndex + 1, sz); unsigned len = MyStringLen(sz); sz[len++] = '.'; sz[len] = 0; @@ -412,10 +404,10 @@ unsigned left = 0, right = _items.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - UInt64 midVal = _items[mid].HeaderPos; + const unsigned mid = (left + right) / 2; + const UInt64 midVal = _items[mid].HeaderPos; if (offset == midVal) - return mid; + return (int)mid; if (offset < midVal) right = mid; else @@ -426,7 +418,7 @@ HRESULT CHandler::AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos) { - int fileIndex = FindItem(offset); + const int fileIndex = FindItem(offset); if (fileIndex < (int)0) return S_FALSE; @@ -439,14 +431,14 @@ while (data[i++] != 0); AString &s = _libFiles[_numLibFiles]; - const AString &name = _items[fileIndex].Name; + const AString &name = _items[(unsigned)fileIndex].Name; s += name; if (!name.IsEmpty() && name.Back() == '/') s.DeleteBack(); s += " "; s += (const char *)(data + pos); - s += (char)0xD; - s += (char)0xA; + // s.Add_Char((char)0xD); + s.Add_LF(); pos = i; return S_OK; } @@ -456,42 +448,42 @@ HRESULT CHandler::ParseLibSymbols(IInStream *stream, unsigned fileIndex) { CItem &item = _items[fileIndex]; - if (item.Name != "/" && - item.Name != "__.SYMDEF" && - item.Name != "__.SYMDEF SORTED") + if (!item.Name.IsEqualTo("/") && + !item.Name.IsEqualTo("__.SYMDEF") && + !item.Name.IsEqualTo("__.SYMDEF SORTED")) return S_OK; if (item.Size > ((UInt32)1 << 30) || item.Size < 4) return S_OK; - RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, item.GetDataPos())) size_t size = (size_t)item.Size; CByteArr p(size); - RINOK(ReadStream_FALSE(stream, p, size)); + RINOK(ReadStream_FALSE(stream, p, size)) size_t pos = 0; - if (item.Name != "/") + if (!item.Name.IsEqualTo("/")) { - // __.SYMDEF parsing (BSD) + // "__.SYMDEF" parsing (BSD) unsigned be; for (be = 0; be < 2; be++) { - UInt32 tableSize = Get32(p, be); + const UInt32 tableSize = Get32(p, be); pos = 4; if (size - pos < tableSize || (tableSize & 7) != 0) continue; size_t namesStart = pos + tableSize; - UInt32 namesSize = Get32(p + namesStart, be); + const UInt32 namesSize = Get32(p.ConstData() + namesStart, be); namesStart += 4; if (namesStart > size || namesStart + namesSize != size) continue; - UInt32 numSymbols = tableSize >> 3; + const UInt32 numSymbols = tableSize >> 3; UInt32 i; for (i = 0; i < numSymbols; i++, pos += 8) { size_t namePos = Get32(p + pos, be); - UInt32 offset = Get32(p + pos + 4, be); + const UInt32 offset = Get32(p + pos + 4, be); if (AddFunc(offset, p + namesStart, namesSize, namePos) != S_OK) break; } @@ -509,7 +501,7 @@ else if (_numLibFiles == 0) { // archive symbol table (GNU) - UInt32 numSymbols = GetBe32(p); + const UInt32 numSymbols = GetBe32(p); pos = 4; if (numSymbols > (size - pos) / 4) return S_FALSE; @@ -517,15 +509,15 @@ for (UInt32 i = 0; i < numSymbols; i++) { - UInt32 offset = GetBe32(p + 4 + i * 4); - RINOK(AddFunc(offset, p, size, pos)); + const UInt32 offset = GetBe32(p + 4 + i * 4); + RINOK(AddFunc(offset, p, size, pos)) } _type = kType_ALib; } else { // Second linker file (Microsoft .lib) - UInt32 numMembers = GetUi32(p); + const UInt32 numMembers = GetUi32(p); pos = 4; if (numMembers > (size - pos) / 4) return S_FALSE; @@ -533,7 +525,7 @@ if (size - pos < 4) return S_FALSE; - UInt32 numSymbols = GetUi32(p + pos); + const UInt32 numSymbols = GetUi32(p + pos); pos += 4; if (numSymbols > (size - pos) / 2) return S_FALSE; @@ -543,56 +535,55 @@ for (UInt32 i = 0; i < numSymbols; i++) { // index is 1-based. So 32-bit numSymbols field works as item[0] - UInt32 index = GetUi16(p + indexStart + i * 2); + const UInt32 index = GetUi16(p + indexStart + i * 2); if (index == 0 || index > numMembers) return S_FALSE; - UInt32 offset = GetUi32(p + index * 4); - RINOK(AddFunc(offset, p, size, pos)); + const UInt32 offset = GetUi32(p + index * 4); + RINOK(AddFunc(offset, p, size, pos)) } _type = kType_Lib; } // size can be 2-byte aligned in linux files if (pos != size && pos + (pos & 1) != size) return S_FALSE; - item.TextFileIndex = _numLibFiles++; + item.TextFileIndex = (int)(_numLibFiles++); return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { Close(); - UInt64 fileSize = 0; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt64 fileSize; + RINOK(InStream_AtBegin_GetSize(stream, fileSize)) CInArchive arc; - RINOK(arc.Open(stream)); + RINOK(arc.Open(stream)) if (callback) { - RINOK(callback->SetTotal(NULL, &fileSize)); - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &arc.Position)); + RINOK(callback->SetTotal(NULL, &fileSize)) + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &arc.Position)) } CItem item; for (;;) { bool filled; - RINOK(arc.GetNextItem(item, filled)); + RINOK(arc.GetNextItem(item, filled)) if (!filled) break; _items.Add(item); arc.SkipData(item.Size); if (callback && (_items.Size() & 0xFF) == 0) { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &arc.Position)); + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &arc.Position)) } } @@ -610,9 +601,9 @@ if (ParseLongNames(stream) != S_OK) UpdateErrorMessage("Long file names parsing error"); if (_longNames_FileIndex >= 0) - _items.Delete(_longNames_FileIndex); + _items.Delete((unsigned)_longNames_FileIndex); - if (!_items.IsEmpty() && _items[0].Name == "debian-binary") + if (!_items.IsEmpty() && _items[0].Name.IsEqualTo("debian-binary")) { _type = kType_Deb; _items.DeleteFrontal(1); @@ -651,7 +642,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _phySize = 0; @@ -672,13 +663,13 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -711,7 +702,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -749,11 +740,11 @@ COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -771,63 +762,62 @@ UInt64 currentTotalSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; + Int32 opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) currentTotalSize += (item.TextFileIndex >= 0) ? (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size; if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (testMode) { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } - bool isOk = true; + opRes = NExtract::NOperationResult::kOK; if (item.TextFileIndex >= 0) { const AString &f = _libFiles[(unsigned)item.TextFileIndex]; if (realOutStream) - RINOK(WriteStream(realOutStream, f, f.Len())); + RINOK(WriteStream(realOutStream, f, f.Len())) } else { - RINOK(_stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - isOk = (copyCoderSpec->TotalSize == item.Size); - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(isOk ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + RINOK(InStream_SeekSet(_stream, item.GetDataPos())) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item.Size) + opRes = NExtract::NOperationResult::kDataError; + } + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN const CItem &item = _items[index]; @@ -843,7 +833,7 @@ } REGISTER_ARC_I( - "Ar", "ar a deb udeb lib", 0, 0xEC, + "Ar", "ar a deb udeb lib", NULL, 0xEC, kSignature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Archive.def 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive.def --- 7zip-22.01+dfsg/CPP/7zip/Archive/Archive.def 2015-03-06 10:56:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive.def 2023-04-03 11:00:00.000000000 +0000 @@ -10,3 +10,5 @@ SetLargePageMode PRIVATE SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Archive2.def 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive2.def --- 7zip-22.01+dfsg/CPP/7zip/Archive/Archive2.def 2015-02-12 07:12:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Archive2.def 2023-04-03 10:00:00.000000000 +0000 @@ -17,3 +17,5 @@ SetLargePageMode PRIVATE SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ArchiveExports.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArchiveExports.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ArchiveExports.cpp 2022-04-25 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArchiveExports.cpp 2023-03-23 11:00:00.000000000 +0000 @@ -10,7 +10,7 @@ #include "../Common/RegisterArc.h" -static const unsigned kNumArcsMax = 64; +static const unsigned kNumArcsMax = 72; static unsigned g_NumArcs = 0; static unsigned g_DefaultArcIndex = 0; static const CArcInfo *g_Arcs[kNumArcsMax]; @@ -24,9 +24,10 @@ g_DefaultArcIndex = g_NumArcs; g_Arcs[g_NumArcs++] = arcInfo; } + // else throw 1; } -DEFINE_GUID(CLSID_CArchiveHandler, +Z7_DEFINE_GUID(CLSID_CArchiveHandler, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -36,7 +37,7 @@ static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value) { - if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != NULL) value->vt = VT_BSTR; return S_OK; } @@ -52,7 +53,7 @@ CLS_ARC_ID_ITEM(cls) = 0; if (cls != CLSID_CArchiveHandler) return -1; - Byte id = CLS_ARC_ID_ITEM(*clsid); + const Byte id = CLS_ARC_ID_ITEM(*clsid); for (unsigned i = 0; i < g_NumArcs; i++) if (g_Arcs[i]->Id == id) return (int)i; @@ -64,11 +65,11 @@ { COM_TRY_BEGIN { - int needIn = (*iid == IID_IInArchive); - int needOut = (*iid == IID_IOutArchive); + const int needIn = (*iid == IID_IInArchive); + const int needOut = (*iid == IID_IOutArchive); if (!needIn && !needOut) return E_NOINTERFACE; - int formatIndex = FindFormatCalssId(clsid); + const int formatIndex = FindFormatCalssId(clsid); if (formatIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ArjHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArjHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ArjHandler.cpp 2022-02-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ArjHandler.cpp 2023-12-21 10:00:00.000000000 +0000 @@ -4,6 +4,7 @@ #include "../../../C/CpuArch.h" +#include "../../Common/AutoPtr.h" #include "../../Common/ComTry.h" #include "../../Common/StringConvert.h" @@ -28,15 +29,13 @@ namespace NDecoder { static const unsigned kMatchMinLen = 3; - static const UInt32 kWindowSize = 1 << 15; // must be >= (1 << 14) -class CCoder: - public ICompressCoder, - public CMyUnknownImp +class CCoder { CLzOutWindow _outWindow; NBitm::CDecoder _inBitStream; + // bool FinishMode; class CCoderReleaser { @@ -48,22 +47,20 @@ }; friend class CCoderReleaser; - HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress); + HRESULT CodeReal(UInt32 outSize, ICompressProgressInfo *progress); public: - MY_UNKNOWN_IMP - - bool FinishMode; - CCoder(): FinishMode(false) {} - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + // CCoder(): FinishMode(true) {} UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress); }; -HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress) + +HRESULT CCoder::CodeReal(UInt32 rem, ICompressProgressInfo *progress) { const UInt32 kStep = 1 << 20; - UInt64 next = 0; + UInt32 next = 0; if (rem > kStep && progress) next = rem - kStep; @@ -73,22 +70,20 @@ { if (_inBitStream.ExtraBitsWereRead()) return S_FALSE; - - UInt64 packSize = _inBitStream.GetProcessedSize(); - UInt64 pos = _outWindow.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); + const UInt64 packSize = _inBitStream.GetProcessedSize(); + const UInt64 pos = _outWindow.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) next = 0; if (rem > kStep) next = rem - kStep; } UInt32 len; - { const unsigned kNumBits = 7 + 7; - UInt32 val = _inBitStream.GetValue(kNumBits); + const UInt32 val = _inBitStream.GetValue(kNumBits); - if ((val & (1 << (kNumBits - 1))) == 0) + if ((val & (1u << (kNumBits - 1))) == 0) { _outWindow.PutByte((Byte)(val >> 5)); _inBitStream.MovePos(1 + 8); @@ -96,27 +91,24 @@ continue; } - UInt32 mask = 1 << (kNumBits - 2); unsigned w; - - for (w = 1; w < 7; w++, mask >>= 1) - if ((val & mask) == 0) - break; - - unsigned readBits = (w != 7 ? 1 : 0); - readBits += w + w; - len = (1 << w) - 1 + kMatchMinLen - 1 + - (((val >> (kNumBits - readBits)) & ((1 << w) - 1))); + { + UInt32 flag = (UInt32)1 << (kNumBits - 2); + for (w = 1; w < 7; w++, flag >>= 1) + if ((val & flag) == 0) + break; + } + const unsigned readBits = (w != 7 ? 1 : 0) + w * 2; + const UInt32 mask = ((UInt32)1 << w) - 1; + len = mask + kMatchMinLen - 1 + + ((val >> (kNumBits - readBits)) & mask); _inBitStream.MovePos(readBits); } - { const unsigned kNumBits = 4 + 13; - UInt32 val = _inBitStream.GetValue(kNumBits); - + const UInt32 val = _inBitStream.GetValue(kNumBits); unsigned readBits = 1; unsigned w; - if ((val & ((UInt32)1 << 16)) == 0) w = 9; else if ((val & ((UInt32)1 << 15)) == 0) w = 10; else if ((val & ((UInt32)1 << 14)) == 0) w = 11; @@ -124,61 +116,50 @@ else { w = 13; readBits = 0; } readBits += w + w - 9; - - UInt32 dist = ((UInt32)1 << w) - (1 << 9) + + const UInt32 dist = ((UInt32)1 << w) - (1 << 9) + (((val >> (kNumBits - readBits)) & ((1 << w) - 1))); _inBitStream.MovePos(readBits); - if (len > rem) - len = (UInt32)rem; - + { + // if (FinishMode) + return S_FALSE; + // else len = (UInt32)rem; + } if (!_outWindow.CopyBlock(dist, len)) return S_FALSE; rem -= len; } } - if (FinishMode) + // if (FinishMode) { if (_inBitStream.ReadAlignBits() != 0) return S_FALSE; } - if (_inBitStream.ExtraBitsWereRead()) return S_FALSE; - return S_OK; } - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress) { try { - if (!outSize) - return E_INVALIDARG; - if (!_outWindow.Create(kWindowSize)) return E_OUTOFMEMORY; if (!_inBitStream.Create(1 << 17)) return E_OUTOFMEMORY; - _outWindow.SetStream(outStream); _outWindow.Init(false); _inBitStream.SetStream(inStream); _inBitStream.Init(); - - CCoderReleaser coderReleaser(this); - HRESULT res; { - res = CodeReal(*outSize, progress); - if (res != S_OK) - return res; + CCoderReleaser coderReleaser(this); + RINOK(CodeReal(outSize, progress)) + coderReleaser.Disable(); } - - coderReleaser.Disable(); return _outWindow.Flush(); } catch(const CInBufferException &e) { return e.ErrorCode; } @@ -367,10 +348,10 @@ // LastChapter = p[29]; unsigned pos = headerSize; unsigned size1 = size - pos; - RINOK(ReadString(p + pos, size1, Name)); + RINOK(ReadString(p + pos, size1, Name)) pos += size1; size1 = size - pos; - RINOK(ReadString(p + pos, size1, Comment)); + RINOK(ReadString(p + pos, size1, Comment)) pos += size1; return S_OK; } @@ -477,10 +458,10 @@ unsigned pos = headerSize; unsigned size1 = size - pos; - RINOK(ReadString(p + pos, size1, Name)); + RINOK(ReadString(p + pos, size1, Name)) pos += size1; size1 = size - pos; - RINOK(ReadString(p + pos, size1, Comment)); + RINOK(ReadString(p + pos, size1, Comment)) pos += size1; return S_OK; @@ -570,7 +551,7 @@ if (extendedInfo) extendedInfo->Size += _blockSize; - READ_STREAM(_block, readSize); + READ_STREAM(_block, readSize) if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize)) { if (extendedInfo) @@ -591,28 +572,28 @@ for (UInt32 i = 0;; i++) { bool filled; - RINOK(ReadBlock(filled, &extendedInfo)); + RINOK(ReadBlock(filled, &extendedInfo)) if (!filled) return S_OK; if (Callback && (i & 0xFF) == 0) - RINOK(Callback->SetCompleted(&NumFiles, &Processed)); + RINOK(Callback->SetCompleted(&NumFiles, &Processed)) } } HRESULT CArc::Open() { bool filled; - RINOK(ReadBlock(filled, NULL)); // (extendedInfo = NULL) + RINOK(ReadBlock(filled, NULL)) // (extendedInfo = NULL) if (!filled) return S_FALSE; - RINOK(Header.Parse(_block, _blockSize)); + RINOK(Header.Parse(_block, _blockSize)) IsArc = true; return SkipExtendedHeaders(ExtendedInfo); } HRESULT CArc::GetNextItem(CItem &item, bool &filled) { - RINOK(ReadBlock(filled, NULL)); // (extendedInfo = NULL) + RINOK(ReadBlock(filled, NULL)) // (extendedInfo = NULL) if (!filled) return S_OK; filled = false; @@ -627,23 +608,18 @@ extraData = GetUi32(_block + pos); */ - RINOK(SkipExtendedHeaders(item.ExtendedInfo)); + RINOK(SkipExtendedHeaders(item.ExtendedInfo)) filled = true; return S_OK; } -class CHandler: - public IInArchive, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_0 + CObjectVector _items; CMyComPtr _stream; UInt64 _phySize; CArc _arc; -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback); }; @@ -696,7 +672,7 @@ prop = MultiByteToUnicodeString(s, CP_OEMCP); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -717,7 +693,7 @@ case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; case k_ErrorType_OK: - default: + // default: break; } prop = v; @@ -730,13 +706,13 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -766,16 +742,15 @@ { Close(); - UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(inStream, endPos)) _arc.Stream = inStream; _arc.Callback = callback; _arc.NumFiles = 0; _arc.Processed = 0; - RINOK(_arc.Open()); + RINOK(_arc.Open()) _phySize = _arc.Processed; if (_arc.Header.ArchiveSize != 0) @@ -787,7 +762,7 @@ bool filled; _arc.Error = k_ErrorType_OK; - RINOK(_arc.GetNextItem(item, filled)); + RINOK(_arc.GetNextItem(item, filled)) if (_arc.Error != k_ErrorType_OK) break; @@ -811,20 +786,20 @@ break; } - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, pos)) _arc.NumFiles = _items.Size(); _arc.Processed = pos; if (callback && (_items.Size() & 0xFF) == 0) { - RINOK(callback->SetCompleted(&_arc.NumFiles, &_arc.Processed)); + RINOK(callback->SetCompleted(&_arc.NumFiles, &_arc.Processed)) } } return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN HRESULT res; @@ -840,7 +815,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _arc.Close(); _phySize = 0; @@ -849,12 +824,12 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN UInt64 totalUnpacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -866,75 +841,70 @@ totalUnpacked += item.Size; // totalPacked += item.PackSize; } - extractCallback->SetTotal(totalUnpacked); + RINOK(extractCallback->SetTotal(totalUnpacked)) totalUnpacked = totalPacked = 0; - UInt64 curUnpacked, curPacked; + UInt32 curUnpacked, curPacked; - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL; - CMyComPtr lzhDecoder; - - NCompress::NArj::NDecoder::CCoder *arjDecoderSpec = NULL; - CMyComPtr arjDecoder; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - - CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(inStreamSpec); - inStreamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked) + CMyUniquePtr lzhDecoder; + CMyUniquePtr arjDecoder; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++, + totalUnpacked += curUnpacked, + totalPacked += curPacked) { lps->InSize = totalPacked; lps->OutSize = totalUnpacked; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; curUnpacked = curPacked = 0; - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) + Int32 opRes; { - // if (!testMode) + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + // realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + continue; } - continue; - } - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - curUnpacked = item.Size; - curPacked = item.PackSize; - - { - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(); + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + curUnpacked = item.Size; + curPacked = item.PackSize; + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + // realOutStream.Release(); + outStream->Init(); - inStreamSpec->Init(item.PackSize); + inStream->Init(item.PackSize); - UInt64 pos; - _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); + RINOK(InStream_SeekSet(_stream, item.DataPosition)) HRESULT result = S_OK; - Int32 opRes = NExtract::NOperationResult::kOK; + opRes = NExtract::NOperationResult::kOK; if (item.IsEncrypted()) opRes = NExtract::NOperationResult::kUnsupportedMethod; @@ -944,8 +914,8 @@ { case NCompressionMethod::kStored: { - result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) + result = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + if (result == S_OK && copyCoder->TotalSize != item.PackSize) result = S_FALSE; break; } @@ -953,29 +923,21 @@ case NCompressionMethod::kCompressed1b: case NCompressionMethod::kCompressed1c: { - if (!lzhDecoder) - { - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - } - lzhDecoderSpec->FinishMode = true; + lzhDecoder.Create_if_Empty(); + // lzhDecoder->FinishMode = true; const UInt32 kHistorySize = 26624; - lzhDecoderSpec->SetDictSize(kHistorySize); - result = lzhDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress); - if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize) + lzhDecoder->SetDictSize(kHistorySize); + result = lzhDecoder->Code(inStream, outStream, curUnpacked, lps); + if (result == S_OK && lzhDecoder->GetInputProcessedSize() != item.PackSize) result = S_FALSE; break; } case NCompressionMethod::kCompressed2: { - if (!arjDecoder) - { - arjDecoderSpec = new NCompress::NArj::NDecoder::CCoder; - arjDecoder = arjDecoderSpec; - } - arjDecoderSpec->FinishMode = true; - result = arjDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress); - if (result == S_OK && arjDecoderSpec->GetInputProcessedSize() != item.PackSize) + arjDecoder.Create_if_Empty(); + // arjDecoderSpec->FinishMode = true; + result = arjDecoder->Code(inStream, outStream, curUnpacked, lps); + if (result == S_OK && arjDecoder->GetInputProcessedSize() != item.PackSize) result = S_FALSE; break; } @@ -990,16 +952,14 @@ opRes = NExtract::NOperationResult::kDataError; else { - RINOK(result); - opRes = (outStreamSpec->GetCRC() == item.FileCRC) ? + RINOK(result) + opRes = (outStream->GetCRC() == item.FileCRC) ? NExtract::NOperationResult::kOK: NExtract::NOperationResult::kCRCError; } } - - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -1009,7 +969,7 @@ static const Byte k_Signature[] = { kSig0, kSig1 }; REGISTER_ARC_I( - "Arj", "arj", 0, 4, + "Arj", "arj", NULL, 4, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/AvbHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/AvbHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/AvbHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/AvbHandler.cpp 2023-03-27 17:00:00.000000000 +0000 @@ -0,0 +1,596 @@ +// AvbHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) + +using namespace NWindows; + +namespace NArchive { + +namespace NExt { +API_FUNC_IsArc IsArc_Ext_PhySize(const Byte *p, size_t size, UInt64 *phySize); +} + +namespace NAvb { + +static void AddNameToString(AString &s, const Byte *name, unsigned size, bool strictConvert) +{ + for (unsigned i = 0; i < size; i++) + { + Byte c = name[i]; + if (c == 0) + return; + if (strictConvert && c < 32) + c = '_'; + s += (char)c; + } +} + +/* Maximum size of a vbmeta image - 64 KiB. */ +#define VBMETA_MAX_SIZE (64 * 1024) + +#define SIGNATURE { 'A', 'V', 'B', 'f', 0, 0, 0, 1 } + +static const unsigned k_SignatureSize = 8; +static const Byte k_Signature[k_SignatureSize] = SIGNATURE; + +// #define AVB_FOOTER_MAGIC "AVBf" +// #define AVB_FOOTER_MAGIC_LEN 4 +/* The current footer version used - keep in sync with avbtool. */ +#define AVB_FOOTER_VERSION_MAJOR 1 + +/* The struct used as a footer used on partitions, used to find the + * AvbVBMetaImageHeader struct. This struct is always stored at the + * end of a partition. + */ +// #define AVB_FOOTER_SIZE 64 +static const unsigned kFooterSize = 64; + +struct CFooter +{ + /* 0: Four bytes equal to "AVBf" (AVB_FOOTER_MAGIC). */ + // Byte magic[AVB_FOOTER_MAGIC_LEN]; + /* 4: The major version of the footer struct. */ + UInt32 version_major; + /* 8: The minor version of the footer struct. */ + UInt32 version_minor; + + /* 12: The original size of the image on the partition. */ + UInt64 original_image_size; + + /* 20: The offset of the |AvbVBMetaImageHeader| struct. */ + UInt64 vbmeta_offset; + + /* 28: The size of the vbmeta block (header + auth + aux blocks). */ + UInt64 vbmeta_size; + + /* 36: Padding to ensure struct is size AVB_FOOTER_SIZE bytes. This + * must be set to zeroes. + */ + Byte reserved[28]; + + void Parse(const Byte *p) + { + G32 (4, version_major); + G32 (8, version_minor); + G64 (12, original_image_size); + G64 (20, vbmeta_offset); + G64 (28, vbmeta_size); + } +}; + + +/* Size of the vbmeta image header. */ +#define AVB_VBMETA_IMAGE_HEADER_SIZE 256 + +/* Magic for the vbmeta image header. */ +// #define AVB_MAGIC "AVB0" +// #define AVB_MAGIC_LEN 4 +/* Maximum size of the release string including the terminating NUL byte. */ +#define AVB_RELEASE_STRING_SIZE 48 + +struct AvbVBMetaImageHeader +{ + /* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */ + // Byte magic[AVB_MAGIC_LEN]; + + /* 4: The major version of libavb required for this header. */ + UInt32 required_libavb_version_major; + /* 8: The minor version of libavb required for this header. */ + UInt32 required_libavb_version_minor; + + /* 12: The size of the signature block. */ + UInt64 authentication_data_block_size; + /* 20: The size of the auxiliary data block. */ + UInt64 auxiliary_data_block_size; + + /* 28: The verification algorithm used, see |AvbAlgorithmType| enum. */ + UInt32 algorithm_type; + + /* 32: Offset into the "Authentication data" block of hash data. */ + UInt64 hash_offset; + /* 40: Length of the hash data. */ + UInt64 hash_size; + + /* 48: Offset into the "Authentication data" block of signature data. */ + UInt64 signature_offset; + /* 56: Length of the signature data. */ + UInt64 signature_size; + + /* 64: Offset into the "Auxiliary data" block of public key data. */ + UInt64 public_key_offset; + /* 72: Length of the public key data. */ + UInt64 public_key_size; + + /* 80: Offset into the "Auxiliary data" block of public key metadata. */ + UInt64 public_key_metadata_offset; + /* 88: Length of the public key metadata. Must be set to zero if there + * is no public key metadata. + */ + UInt64 public_key_metadata_size; + + /* 96: Offset into the "Auxiliary data" block of descriptor data. */ + UInt64 descriptors_offset; + /* 104: Length of descriptor data. */ + UInt64 descriptors_size; + + /* 112: The rollback index which can be used to prevent rollback to + * older versions. + */ + UInt64 rollback_index; + + /* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be + * set to zero if the vbmeta image is not a top-level image. + */ + UInt32 flags; + + /* 124: The location of the rollback index defined in this header. + * Only valid for the main vbmeta. For chained partitions, the rollback + * index location must be specified in the AvbChainPartitionDescriptor + * and this value must be set to 0. + */ + UInt32 rollback_index_location; + + /* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or + * "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL + * terminated. Applications must not make assumptions about how this + * string is formatted. + */ + Byte release_string[AVB_RELEASE_STRING_SIZE]; + + /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE + * bytes. This must be set to zeroes. + */ + // Byte reserved[80]; + bool Parse(const Byte *p); +}; + +bool AvbVBMetaImageHeader::Parse(const Byte *p) +{ + // Byte magic[AVB_MAGIC_LEN]; + if (Get32(p) != 0x41564230) // "AVB0" + return false; + G32 (4, required_libavb_version_major); + if (required_libavb_version_major != AVB_FOOTER_VERSION_MAJOR) // "AVB0" + return false; + G32 (8, required_libavb_version_minor); + G64 (12, authentication_data_block_size); + G64 (20, auxiliary_data_block_size); + G32 (28, algorithm_type); + G64 (32, hash_offset); + G64 (40, hash_size); + G64 (48, signature_offset); + G64 (56, signature_size); + G64 (64, public_key_offset); + G64 (72, public_key_size); + G64 (80, public_key_metadata_offset); + G64 (88, public_key_metadata_size); + G64 (96, descriptors_offset); + G64 (104, descriptors_size); + G64 (112, rollback_index); + G32 (120, flags); + G32 (124, rollback_index_location); + memcpy(release_string, p + 128, AVB_RELEASE_STRING_SIZE); + + /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE + * bytes. This must be set to zeroes. + */ + // Byte reserved[80]; + return true; +} + + +static const unsigned k_Descriptor_Size = 16; + +enum AvbDescriptorTag +{ + AVB_DESCRIPTOR_TAG_PROPERTY, + AVB_DESCRIPTOR_TAG_HASHTREE, + AVB_DESCRIPTOR_TAG_HASH, + AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE, + AVB_DESCRIPTOR_TAG_CHAIN_PARTITION +}; + +struct AvbDescriptor +{ + UInt64 Tag; + UInt64 Size; + + void Parse(const Byte *p) + { + G64 (0, Tag); + G64 (8, Size); + } +}; + + +enum AvbHashtreeDescriptorFlags +{ + AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB = (1 << 0), + AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE = (1 << 1) +}; + +/* A descriptor containing information about a dm-verity hashtree. + * + * Hash-trees are used to verify large partitions typically containing + * file systems. See + * https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity for more + * information about dm-verity. + * + * Following this struct are |partition_name_len| bytes of the + * partition name (UTF-8 encoded), |salt_len| bytes of salt, and then + * |root_digest_len| bytes of the root digest. + * + * The |reserved| field is for future expansion and must be set to NUL + * bytes. + * + * Changes in v1.1: + * - flags field is added which supports AVB_HASHTREE_DESCRIPTOR_FLAGS_USE_AB + * - digest_len may be zero, which indicates the use of a persistent digest + */ + +static const unsigned k_Hashtree_Size_Min = 164; + +struct AvbHashtreeDescriptor +{ + UInt32 dm_verity_version; + UInt64 image_size; + UInt64 tree_offset; + UInt64 tree_size; + UInt32 data_block_size; + UInt32 hash_block_size; + UInt32 fec_num_roots; + UInt64 fec_offset; + UInt64 fec_size; + Byte hash_algorithm[32]; + UInt32 partition_name_len; + UInt32 salt_len; + UInt32 root_digest_len; + UInt32 flags; + Byte reserved[60]; + void Parse(const Byte *p) + { + G32 (0, dm_verity_version); + G64 (4, image_size); + G64 (12, tree_offset); + G64 (20, tree_size); + G32 (28, data_block_size); + G32 (32, hash_block_size); + G32 (36, fec_num_roots); + G64 (40, fec_offset); + G64 (48, fec_size); + memcpy(hash_algorithm, p + 56, 32); + G32 (88, partition_name_len); + G32 (92, salt_len); + G32 (96, root_digest_len); + G32 (100, flags); + } +}; + +static const unsigned k_PropertyDescriptor_Size_Min = 16; + +struct AvbPropertyDescriptor +{ + UInt64 key_num_bytes; + UInt64 value_num_bytes; + + void Parse(const Byte *p) + { + G64 (0, key_num_bytes); + G64 (8, value_num_bytes); + } +}; + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + // UInt64 _startOffset; + UInt64 _phySize; + + CFooter Footer; + AString Name; + const char *Ext; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + if (index != 0) + return NExtract::NOperationResult::kUnavailable; + // pos = _startOffset; + pos = 0; + size = Footer.original_image_size; + return NExtract::NOperationResult::kOK; + } +}; + + +HRESULT CHandler::Open2(IInStream *stream) +{ + UInt64 fileSize; + { + Byte buf[kFooterSize]; + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) + if (fileSize < kFooterSize) + return S_FALSE; + RINOK(InStream_SeekSet(stream, fileSize - kFooterSize)) + RINOK(ReadStream_FALSE(stream, buf, kFooterSize)) + if (memcmp(buf, k_Signature, k_SignatureSize) != 0) + return S_FALSE; + Footer.Parse(buf); + if (Footer.vbmeta_size > VBMETA_MAX_SIZE || + Footer.vbmeta_size < AVB_VBMETA_IMAGE_HEADER_SIZE) + return S_FALSE; + for (unsigned i = 36; i < kFooterSize; i++) + if (buf[i] != 0) + return S_FALSE; + } + { + CByteBuffer buf; + buf.Alloc((size_t)Footer.vbmeta_size); + RINOK(InStream_SeekSet(stream, Footer.vbmeta_offset)) + RINOK(ReadStream_FALSE(stream, buf, (size_t)Footer.vbmeta_size)) + + AvbVBMetaImageHeader meta; + if (!meta.Parse(buf)) + return S_FALSE; + + unsigned offset = (unsigned)AVB_VBMETA_IMAGE_HEADER_SIZE; + unsigned rem = (unsigned)(Footer.vbmeta_size - offset); + + if (meta.authentication_data_block_size != 0) + { + if (rem < meta.authentication_data_block_size) + return S_FALSE; + const unsigned u = (unsigned)meta.authentication_data_block_size; + offset += u; + rem -= u; + } + + if (rem < meta.descriptors_offset || + rem - meta.descriptors_offset < meta.descriptors_size) + return S_FALSE; + rem = (unsigned)meta.descriptors_size; + while (rem != 0) + { + if (rem < k_Descriptor_Size) + return S_FALSE; + AvbDescriptor desc; + desc.Parse(buf + offset); + offset += k_Descriptor_Size; + rem -= k_Descriptor_Size; + if (desc.Size > rem) + return S_FALSE; + const unsigned descSize = (unsigned)desc.Size; + if (desc.Tag == AVB_DESCRIPTOR_TAG_HASHTREE) + { + if (descSize < k_Hashtree_Size_Min) + return S_FALSE; + AvbHashtreeDescriptor ht; + ht.Parse(buf + offset); + unsigned pos = k_Hashtree_Size_Min; + + if (pos + ht.partition_name_len > descSize) + return S_FALSE; + Name.Empty(); // UTF-8 + AddNameToString(Name, buf + offset + pos, ht.partition_name_len, false); + pos += ht.partition_name_len; + + if (pos + ht.salt_len > descSize) + return S_FALSE; + CByteBuffer salt; + salt.CopyFrom(buf + offset + pos, ht.salt_len); + pos += ht.salt_len; + + if (pos + ht.root_digest_len > descSize) + return S_FALSE; + CByteBuffer digest; + digest.CopyFrom(buf + offset + pos, ht.root_digest_len); + pos += ht.root_digest_len; + // what is that digest? + } + else if (desc.Tag == AVB_DESCRIPTOR_TAG_PROPERTY) + { + if (descSize < k_PropertyDescriptor_Size_Min + 2) + return S_FALSE; + AvbPropertyDescriptor pt; + pt.Parse(buf + offset); + unsigned pos = k_PropertyDescriptor_Size_Min; + + if (pt.key_num_bytes > descSize - pos - 1) + return S_FALSE; + AString key; // UTF-8 + AddNameToString(key, buf + offset + pos, (unsigned)pt.key_num_bytes, false); + pos += (unsigned)pt.key_num_bytes + 1; + + if (descSize < pos) + return S_FALSE; + if (pt.value_num_bytes > descSize - pos - 1) + return S_FALSE; + AString value; // UTF-8 + AddNameToString(value, buf + offset + pos, (unsigned)pt.value_num_bytes, false); + pos += (unsigned)pt.value_num_bytes + 1; + } + offset += descSize; + rem -= descSize; + } + + _phySize = fileSize; + + // _startOffset = 0; + return S_OK; + } +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + try + { + if (Open2(stream) != S_OK) + return S_FALSE; + _stream = stream; + + { + CMyComPtr parseStream; + if (GetStream(0, &parseStream) == S_OK && parseStream) + { + const size_t kParseSize = 1 << 11; + Byte buf[kParseSize]; + if (ReadStream_FAIL(parseStream, buf, kParseSize) == S_OK) + { + UInt64 extSize; + if (NExt::IsArc_Ext_PhySize(buf, kParseSize, &extSize) == k_IsArc_Res_YES) + if (extSize == Footer.original_image_size) + Ext = "ext"; + } + } + } + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _stream.Release(); + // _startOffset = 0; + _phySize = 0; + Ext = NULL; + Name.Empty(); + return S_OK; +} + + +static const Byte kArcProps[] = +{ + kpidName +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidPhySize: prop = _phySize; break; + case kpidName: + { + if (!Name.IsEmpty()) + { + AString s (Name); + s += ".avb"; + prop = s; + } + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidPath: + { + if (!Name.IsEmpty()) + { + AString s (Name); + s += '.'; + s += Ext ? Ext : "img"; + prop = s; + } + break; + } + case kpidPackSize: + case kpidSize: + prop = Footer.original_image_size; + break; + case kpidExtension: prop = (Ext ? Ext : "img"); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + + +REGISTER_ARC_I_NO_SIG( + "AVB", "avb img", NULL, 0xc0, + /* k_Signature, */ + 0, + /* NArcInfoFlags::kUseGlobalOffset | */ + NArcInfoFlags::kBackwardOpen + , + NULL) + +}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Base64Handler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Base64Handler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Base64Handler.cpp 2021-01-22 19:47:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Base64Handler.cpp 2023-12-11 09:00:00.000000000 +0000 @@ -207,7 +207,7 @@ { if (size == 0) return p; - UInt32 c = k_Base64Table[(Byte)(*p++)]; + const UInt32 c = k_Base64Table[(Byte)(*p++)]; size--; if (c == k_Code_Space) continue; @@ -225,7 +225,7 @@ for (;;) { - UInt32 c = k_Base64Table[(Byte)(*src++)]; + const UInt32 c = k_Base64Table[(Byte)(*src++)]; if (c < 64) { @@ -266,7 +266,7 @@ for (;;) { - Byte c = k_Base64Table[(Byte)(*src++)]; + const Byte c = k_Base64Table[(Byte)(*src++)]; if (c == k_Code_Space) continue; if (c == k_Code_Zero) @@ -279,18 +279,13 @@ namespace NArchive { namespace NBase64 { -class CHandler: - public IInArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_0 + bool _isArc; UInt64 _phySize; size_t _size; EBase64Res _sres; CByteBuffer _data; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) }; static const Byte kProps[] = @@ -302,13 +297,13 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; switch (propID) @@ -328,7 +323,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { // COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -349,22 +344,22 @@ while (size != 0) { const UInt32 kBlockSize = ((UInt32)1 << 24); - UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + const UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; UInt32 processedSizeLoc; - RINOK(stream->Read(data, curSize, &processedSizeLoc)); + RINOK(stream->Read(data, curSize, &processedSizeLoc)) if (processedSizeLoc == 0) return E_FAIL; data = (void *)((Byte *)data + processedSizeLoc); size -= processedSizeLoc; bytes += processedSizeLoc; const UInt64 files = 1; - RINOK(openCallback->SetCompleted(&files, &bytes)); + RINOK(openCallback->SetCompleted(&files, &bytes)) } return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) { COM_TRY_BEGIN { @@ -373,19 +368,16 @@ const unsigned kStartSize = 1 << 12; _data.Alloc(kStartSize); size_t size = kStartSize; - RINOK(ReadStream(stream, _data, &size)); - UInt32 isArcRes = IsArc_Base64(_data, size); - if (isArcRes == k_IsArc_Res_NO) + RINOK(ReadStream(stream, _data, &size)) + if (IsArc_Base64(_data, size) == k_IsArc_Res_NO) return S_FALSE; } _isArc = true; UInt64 packSize64; - RINOK(stream->Seek(0, STREAM_SEEK_END, &packSize64)); - + RINOK(InStream_GetSize_SeekToEnd(stream, packSize64)) if (packSize64 == 0) return S_FALSE; - size_t curSize = 1 << 16; if (curSize > packSize64) curSize = (size_t)packSize64; @@ -393,16 +385,16 @@ for (;;) { - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, 0)) _data.Alloc(curSize); - RINOK(ReadStream_OpenProgress(stream, _data, curSize, openCallback)); + RINOK(ReadStream_OpenProgress(stream, _data, curSize, openCallback)) const Byte *srcEnd; Byte *dest; _sres = Base64ToBin(_data, curSize, &srcEnd, &dest); - _size = dest - _data; - size_t mainSize = srcEnd - _data; + _size = (size_t)(dest - _data); + const size_t mainSize = (size_t)(srcEnd - _data); _phySize = mainSize; if (_sres == k_Base64_RES_UnexpectedChar) break; @@ -431,7 +423,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; _size = 0; @@ -442,48 +434,34 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = 1; if (numItems == 0) return S_OK; - if (numItems != 1 || *indices != 0) + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - RINOK(extractCallback->SetTotal(_size)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + RINOK(extractCallback->SetTotal(_size)) + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - + // RINOK(lps->SetCur()) + Int32 opRes; { - lps->InSize = lps->OutSize = 0; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - - extractCallback->PrepareOperation(askMode); - + RINOK(extractCallback->PrepareOperation(askMode)) if (realOutStream) { - RINOK(WriteStream(realOutStream, (const Byte *)_data, _size)); - realOutStream.Release(); + RINOK(WriteStream(realOutStream, (const Byte *)_data, _size)) } - - Int32 opRes = NExtract::NOperationResult::kOK; - + opRes = NExtract::NOperationResult::kOK; if (_sres != k_Base64_RES_Finished) { if (_sres == k_Base64_RES_NeedMoreInput) @@ -491,21 +469,20 @@ else if (_sres == k_Base64_RES_UnexpectedChar) opRes = NExtract::NOperationResult::kDataError; } - - RINOK(extractCallback->SetOperationResult(opRes)); } - + RINOK(extractCallback->SetOperationResult(opRes)) lps->InSize = _phySize; lps->OutSize = _size; return lps->SetCur(); - COM_TRY_END } REGISTER_ARC_I_NO_SIG( - "Base64", "b64", 0, 0xC5, + "Base64", "b64", NULL, 0xC5, 0, - NArcInfoFlags::kKeepName | NArcInfoFlags::kStartOpen | NArcInfoFlags::kByExtOnlyOpen, + NArcInfoFlags::kKeepName + | NArcInfoFlags::kStartOpen + | NArcInfoFlags::kByExtOnlyOpen, IsArc_Base64) }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Bz2Handler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Bz2Handler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Bz2Handler.cpp 2022-04-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Bz2Handler.cpp 2025-07-02 12:00:00.000000000 +0000 @@ -20,13 +20,11 @@ namespace NArchive { namespace NBz2 { -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveOpenSeq, + IOutArchive, + ISetProperties +) CMyComPtr _stream; CMyComPtr _seqStream; @@ -46,19 +44,6 @@ UInt64 _numBlocks; CSingleMethodProps _props; - -public: - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveOpenSeq, - IOutArchive, - ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - CHandler() { } }; static const Byte kProps[] = @@ -76,7 +61,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -88,29 +73,32 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; prop = v; + break; } + default: break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) { case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break; + default: break; } prop.Detach(value); return S_OK; @@ -133,13 +121,13 @@ } } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) { COM_TRY_BEGIN Close(); { Byte buf[kSignatureCheckSize]; - RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize)); + RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize)) if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO) return S_FALSE; _isArc = true; @@ -152,7 +140,7 @@ } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _isArc = true; @@ -160,7 +148,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _needSeekToStart = false; @@ -180,8 +168,8 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -190,113 +178,112 @@ return E_INVALIDARG; if (_packSize_Defined) - extractCallback->SetTotal(_packSize); + { + RINOK(extractCallback->SetTotal(_packSize)) + } + Int32 opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) if (_needSeekToStart) { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _needSeekToStart = true; // try { - NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder; - CMyComPtr decoder = decoderSpec; + CMyComPtr2_Create decoder; - #ifndef _7ZIP_ST - RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads)); + #ifndef Z7_ST + RINOK(decoder->SetNumberOfThreads(_props._numThreads)) #endif - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - - realOutStream.Release(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); - decoderSpec->FinishMode = true; - decoderSpec->Base.DecodeAllStreams = true; + decoder->FinishMode = true; + decoder->Base.DecodeAllStreams = true; _dataAfterEnd = false; _needMoreInput = false; - lps->InSize = 0; - lps->OutSize = 0; - - HRESULT result = decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress); + HRESULT result = decoder.Interface()->Code(_seqStream, outStream, NULL, NULL, lps); if (result != S_FALSE && result != S_OK) return result; - if (decoderSpec->Base.NumStreams == 0) + if (decoder->Base.NumStreams == 0) { _isArc = false; result = S_FALSE; } else { - const UInt64 inProcessedSize = decoderSpec->GetInputProcessedSize(); + const UInt64 inProcessedSize = decoder->GetInputProcessedSize(); UInt64 packSize = inProcessedSize; - if (decoderSpec->Base.NeedMoreInput) + if (decoder->Base.NeedMoreInput) _needMoreInput = true; - if (!decoderSpec->Base.IsBz) + if (!decoder->Base.IsBz) { - packSize = decoderSpec->Base.FinishedPackSize; + packSize = decoder->Base.FinishedPackSize; if (packSize != inProcessedSize) _dataAfterEnd = true; } _packSize = packSize; - _unpackSize = decoderSpec->GetOutProcessedSize(); - _numStreams = decoderSpec->Base.NumStreams; - _numBlocks = decoderSpec->GetNumBlocks(); + _unpackSize = decoder->GetOutProcessedSize(); + _numStreams = decoder->Base.NumStreams; + _numBlocks = decoder->GetNumBlocks(); _packSize_Defined = true; _unpackSize_Defined = true; _numStreams_Defined = true; _numBlocks_Defined = true; + + // RINOK( + lps.Interface()->SetRatioInfo(&packSize, &_unpackSize); } - outStream.Release(); - - Int32 opRes; + // outStream.Release(); if (!_isArc) opRes = NExtract::NOperationResult::kIsNotArc; else if (_needMoreInput) opRes = NExtract::NOperationResult::kUnexpectedEnd; - else if (decoderSpec->GetCrcError()) + else if (decoder->GetCrcError()) opRes = NExtract::NOperationResult::kCRCError; else if (_dataAfterEnd) opRes = NExtract::NOperationResult::kDataAfterEnd; else if (result == S_FALSE) opRes = NExtract::NOperationResult::kDataError; - else if (decoderSpec->Base.MinorError) + else if (decoder->Base.MinorError) opRes = NExtract::NOperationResult::kDataError; else if (result == S_OK) opRes = NExtract::NOperationResult::kOK; else return result; + } return extractCallback->SetOperationResult(opRes); // } catch(...) { return E_FAIL; } @@ -352,12 +339,13 @@ { { CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); + RINOK(updateCallback->GetStream(0, &fileInStream)) if (!fileInStream) return S_FALSE; { - CMyComPtr streamGetSize; - fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize); + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, fileInStream) if (streamGetSize) { UInt64 size; @@ -365,15 +353,14 @@ unpackSize = size; } } - RINOK(updateCallback->SetTotal(unpackSize)); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); + RINOK(updateCallback->SetTotal(unpackSize)) + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); { - NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder; - CMyComPtr encoder = encoderSpec; - RINOK(props.SetCoderProps(encoderSpec, NULL)); - RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); + CMyComPtr2_Create encoder; + RINOK(props.SetCoderProps(encoder.ClsPtr(), NULL)) + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) /* if (reportArcProp) { @@ -386,37 +373,42 @@ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); } -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; // *timeType = NFileTimeType::kUnix; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN if (numItems != 1) return E_INVALIDARG; + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) - /* - CMyComPtr reportArcProp; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); - */ + // Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, reportArcProp, updateCallback) if (IntToBool(newProps)) { { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) if (prop.vt != VT_EMPTY) if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; @@ -428,16 +420,20 @@ UInt64 size; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } CMethodProps props2 = _props; - #ifndef _7ZIP_ST +#ifndef Z7_ST props2.AddProp_NumThreads(_props._numThreads); - #endif +#ifdef _WIN32 + if (_props._numThreadGroups > 1) + props2.AddProp32(NCoderPropID::kNumThreadGroups, _props._numThreadGroups); +#endif +#endif return UpdateArchive(size, outStream, props2, updateCallback); } @@ -445,12 +441,12 @@ if (indexInArchive != 0) return E_INVALIDARG; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) if (opCallback) { RINOK(opCallback->ReportOperation( @@ -459,16 +455,16 @@ } if (_stream) - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) - return NCompress::CopyStream(_stream, outStream, progress); + return NCompress::CopyStream(_stream, outStream, lps); // return ReportArcProps(reportArcProp, NULL, NULL); COM_TRY_END } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { return _props.SetProperties(names, values, numProps); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.cpp 2015-08-31 06:53:06.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.cpp 2024-01-01 07:00:00.000000000 +0000 @@ -12,89 +12,111 @@ namespace NArchive { namespace NCab { -static const UInt32 kBlockSize = (1 << 16); +static const UInt32 kBlockSize = 1 << 16; +static const unsigned k_OverReadPadZone_Size = 32; +static const unsigned kHeaderSize = 8; +static const unsigned kReservedMax = 256; +static const unsigned kHeaderOffset = kBlockSize + k_OverReadPadZone_Size; -bool CCabBlockInStream::Create() +bool CBlockPackData::Create() throw() { if (!_buf) - _buf = (Byte *)::MyAlloc(kBlockSize); - return _buf != 0; + _buf = (Byte *)z7_AlignedAlloc(kBlockSize + k_OverReadPadZone_Size + kHeaderSize + kReservedMax); + return _buf != NULL; } -CCabBlockInStream::~CCabBlockInStream() +CBlockPackData::~CBlockPackData() throw() { - ::MyFree(_buf); + z7_AlignedFree(_buf); } -static UInt32 CheckSum(const Byte *p, UInt32 size) +static UInt32 CheckSum(const Byte *p, UInt32 size) throw() { +#ifdef MY_CPU_64BIT + + UInt64 sum64 = 0; + if (size >= 16) + { + const Byte *lim = p + (size_t)size - 16; + do + { + sum64 ^= GetUi64(p) ^ GetUi64(p + 8); + p += 16; + } + while (p <= lim); + size = (UInt32)(lim + 16 - p); + } + if (size >= 8) + { + sum64 ^= GetUi64(p); + p += 8; + size -= 8; + } + + UInt32 sum = (UInt32)(sum64 >> 32) ^ (UInt32)sum64; + +#else + UInt32 sum = 0; - - for (; size >= 8; size -= 8) + if (size >= 16) + { + const Byte *lim = p + (size_t)size - 16; + do + { + sum ^= GetUi32(p) + ^ GetUi32(p + 4) + ^ GetUi32(p + 8) + ^ GetUi32(p + 12); + p += 16; + } + while (p <= lim); + size = (UInt32)(lim + 16 - p); + } + if (size >= 8) { - sum ^= GetUi32(p) ^ GetUi32(p + 4); + sum ^= GetUi32(p + 0) ^ GetUi32(p + 4); p += 8; + size -= 8; } + +#endif if (size >= 4) { sum ^= GetUi32(p); p += 4; } - - size &= 3; - if (size > 2) sum ^= (UInt32)(*p++) << 16; - if (size > 1) sum ^= (UInt32)(*p++) << 8; - if (size > 0) sum ^= (UInt32)(*p++); - + if (size &= 3) + { + if (size >= 2) + { + if (size > 2) + sum ^= (UInt32)(*p++) << 16; + sum ^= (UInt32)(*p++) << 8; + } + sum ^= (UInt32)(*p++); + } return sum; } -HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize) + +HRESULT CBlockPackData::Read(ISequentialInStream *stream, Byte ReservedSize, UInt32 &packSizeRes, UInt32 &unpackSize) throw() { - const UInt32 kHeaderSize = 8; - const UInt32 kReservedMax = 256; - Byte header[kHeaderSize + kReservedMax]; - RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize)) - packSize = GetUi16(header + 4); - unpackSize = GetUi16(header + 6); + const UInt32 reserved8 = kHeaderSize + ReservedSize; + const Byte *header = _buf + kHeaderOffset; + RINOK(ReadStream_FALSE(stream, (void *)header, reserved8)) + unpackSize = GetUi16a(header + 6); + const UInt32 packSize = GetUi16a(header + 4); + packSizeRes = packSize; if (packSize > kBlockSize - _size) return S_FALSE; - RINOK(ReadStream_FALSE(stream, _buf + _size, packSize)); - - if (MsZip) - { - if (_size == 0) - { - if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B) - return S_FALSE; - _pos = 2; - } - if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */ - return S_FALSE; - } - - if (GetUi32(header) != 0) // checkSum - if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize)) + RINOK(ReadStream_FALSE(stream, _buf + _size, packSize)) + memset(_buf + _size + packSize, 0xff, k_OverReadPadZone_Size); + if (*(const UInt32 *)(const void *)header != 0) // checkSum + if (CheckSum(header, reserved8) != CheckSum(_buf + _size, packSize)) return S_FALSE; - _size += packSize; return S_OK; } -STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (size != 0) - { - UInt32 rem = _size - _pos; - if (size > rem) - size = rem; - memcpy(data, _buf + _pos, size); - _pos += size; - } - if (processedSize) - *processedSize = size; - return S_OK; -} - }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.h 2015-09-11 13:22:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabBlockInStream.h 2024-01-01 07:00:00.000000000 +0000 @@ -1,41 +1,26 @@ // CabBlockInStream.h -#ifndef __CAB_BLOCK_IN_STREAM_H -#define __CAB_BLOCK_IN_STREAM_H +#ifndef ZIP7_INC_CAB_BLOCK_IN_STREAM_H +#define ZIP7_INC_CAB_BLOCK_IN_STREAM_H -#include "../../../Common/MyCom.h" #include "../../IStream.h" namespace NArchive { namespace NCab { -class CCabBlockInStream: - public ISequentialInStream, - public CMyUnknownImp +class CBlockPackData { Byte *_buf; UInt32 _size; - UInt32 _pos; - public: - UInt32 ReservedSize; // < 256 - bool MsZip; - - MY_UNKNOWN_IMP - - CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {} - ~CCabBlockInStream(); - - bool Create(); - - void InitForNewBlock() { _size = 0; _pos = 0; } - - HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize); - - UInt32 GetPackSizeAvail() const { return _size - _pos; } - const Byte *GetData() const { return _buf + _pos; } - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + CBlockPackData(): _buf(NULL), _size(0) {} + ~CBlockPackData() throw(); + bool Create() throw(); + void InitForNewBlock() { _size = 0; } + HRESULT Read(ISequentialInStream *stream, Byte ReservedSize, UInt32 &packSize, UInt32 &unpackSize) throw(); + UInt32 GetPackSize() const { return _size; } + // 32 bytes of overread zone is available after PackSize: + const Byte *GetData() const { return _buf; } }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.cpp 2022-02-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.cpp 2024-03-02 10:00:00.000000000 +0000 @@ -5,7 +5,9 @@ // #include #include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" +#include "../../../Common/AutoPtr.h" #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" @@ -15,9 +17,9 @@ #include "../../../Windows/TimeUtils.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" -#include "../../Compress/CopyCoder.h" #include "../../Compress/DeflateDecoder.h" #include "../../Compress/LzxDecoder.h" #include "../../Compress/QuantumDecoder.h" @@ -32,9 +34,9 @@ namespace NArchive { namespace NCab { -// #define _CAB_DETAILS +// #define CAB_DETAILS -#ifdef _CAB_DETAILS +#ifdef CAB_DETAILS enum { kpidBlockReal = kpidUserDefined @@ -49,7 +51,7 @@ kpidAttrib, kpidMethod, kpidBlock - #ifdef _CAB_DETAILS + #ifdef CAB_DETAILS , // kpidBlockReal, // L"BlockReal", kpidOffset, @@ -83,7 +85,7 @@ static void SetMethodName(char *s, unsigned method, unsigned param) { - if (method < ARRAY_SIZE(kMethods)) + if (method < Z7_ARRAY_SIZE(kMethods)) { s = MyStpCpy(s, kMethods[method]); if (method != NHeader::NMethod::kLZX && @@ -95,7 +97,7 @@ ConvertUInt32ToString(method, s); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -112,14 +114,14 @@ FOR_VECTOR (i, folders) { const CFolder &folder = folders[i]; - unsigned method = folder.GetMethod(); + const unsigned method = folder.GetMethod(); mask |= ((UInt32)1 << method); if (method == NHeader::NMethod::kLZX || method == NHeader::NMethod::kQuantum) { - unsigned di = (method == NHeader::NMethod::kQuantum) ? 0 : 1; + const unsigned di = (method == NHeader::NMethod::kQuantum) ? 0 : 1; if (params[di] < folder.MethodMinor) - params[di] = folder.MethodMinor; + params[di] = folder.MethodMinor; } } } @@ -227,7 +229,7 @@ { AString s; s.Add_UInt32(ai.SetID); - s += '_'; + s.Add_Char('_'); s.Add_UInt32(ai.CabinetNumber + 1); s += ".cab"; prop = s; @@ -261,20 +263,21 @@ } // case kpidShortComment: + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; const CMvItem &mvItem = m_Database.Items[index]; const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; - unsigned itemIndex = mvItem.ItemIndex; + const unsigned itemIndex = mvItem.ItemIndex; const CItem &item = db.Items[itemIndex]; switch (propID) { @@ -305,7 +308,7 @@ if (realFolderIndex >= 0) { const CFolder &folder = db.Folders[(unsigned)realFolderIndex]; - char s[kMethodNameBufSize];; + char s[kMethodNameBufSize]; SetMethodName(s, folder.GetMethod(), folder.MethodMinor); prop = s; } @@ -314,22 +317,24 @@ case kpidBlock: prop.Set_Int32((Int32)m_Database.GetFolderIndex(&mvItem)); break; - #ifdef _CAB_DETAILS + #ifdef CAB_DETAILS // case kpidBlockReal: prop = (UInt32)item.FolderIndex; break; case kpidOffset: prop = (UInt32)item.Offset; break; case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break; #endif + + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback) + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); @@ -361,7 +366,7 @@ if (res == S_OK && !m_Database.Volumes.IsEmpty()) { const CArchInfo &lastArc = m_Database.Volumes.Back().ArcInfo; - unsigned cabNumber = db.ArcInfo.CabinetNumber; + const unsigned cabNumber = db.ArcInfo.CabinetNumber; if (lastArc.SetID != db.ArcInfo.SetID) res = S_FALSE; else if (prevChecked) @@ -418,7 +423,7 @@ if (callback) { - RINOK(callback->SetCompleted(&numItems, NULL)); + RINOK(callback->SetCompleted(&numItems, NULL)) } nextStream = NULL; @@ -471,7 +476,7 @@ startVolName_was_Requested = true; { NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) if (prop.vt == VT_BSTR) startVolName = prop.bstrVal; } @@ -479,7 +484,7 @@ break; } - HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + const HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); if (result == S_OK) break; if (result != S_FALSE) @@ -520,7 +525,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _errorMessage.Empty(); _isArc = false; @@ -534,15 +539,16 @@ return S_OK; } -class CFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_NOQIB_1( + CFolderOutStream + , ISequentialOutStream +) + bool m_TestMode; + bool TempBufMode; + bool m_IsOk; + bool m_FileIsOpen; + const CMvDatabaseEx *m_Database; const CRecordVector *m_ExtractStatuses; @@ -550,21 +556,18 @@ UInt32 TempBufSize; UInt32 TempBufWritten; unsigned NumIdenticalFiles; - bool TempBufMode; unsigned m_StartIndex; unsigned m_CurrentIndex; - CMyComPtr m_ExtractCallback; - bool m_TestMode; - CMyComPtr m_RealOutStream; - - bool m_IsOk; - bool m_FileIsOpen; UInt32 m_RemainFileSize; + UInt64 m_FolderSize; UInt64 m_PosInFolder; + CMyComPtr m_ExtractCallback; + CMyComPtr m_RealOutStream; + void FreeTempBuf() { ::MyFree(TempBuf); @@ -681,10 +684,10 @@ while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex]) { CMyComPtr stream; - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip)); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip)) if (stream) return E_FAIL; - RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip)); + RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip)) m_CurrentIndex++; m_FileIsOpen = true; CloseFile(); @@ -692,11 +695,11 @@ } } - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? m_TestMode ? NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kExtract : NExtract::NAskMode::kSkip; - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)) if (!m_RealOutStream && !m_TestMode) askMode = NExtract::NAskMode::kSkip; return m_ExtractCallback->PrepareOperation(askMode); @@ -711,19 +714,19 @@ { const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - UInt64 fileSize = item.Size; + const UInt64 fileSize = item.Size; if (fileSize != 0) return S_OK; - HRESULT result = OpenFile(); + const HRESULT result = OpenFile(); m_RealOutStream.Release(); - RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(result) + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } return S_OK; } -HRESULT CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { // (data == NULL) means Error_Data for solid folder flushing COM_TRY_BEGIN @@ -777,7 +780,7 @@ if (m_RemainFileSize == 0) { - RINOK(CloseFile()); + RINOK(CloseFile()) while (NumIdenticalFiles) { @@ -789,14 +792,14 @@ if (!TempBuf && TempBufMode && m_RealOutStream) { - RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnsupportedMethod)) } else { - RINOK(CloseFile()); + RINOK(CloseFile()) } - RINOK(result); + RINOK(result) } TempBufMode = false; @@ -823,14 +826,14 @@ m_RemainFileSize = item.Size; - UInt32 fileOffset = item.Offset; + const UInt32 fileOffset = item.Offset; if (fileOffset < m_PosInFolder) return E_FAIL; if (fileOffset > m_PosInFolder) { - UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size); + const UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size); realProcessed += numBytesToWrite; if (processedSize) *processedSize = realProcessed; @@ -842,7 +845,7 @@ if (fileOffset == m_PosInFolder) { - RINOK(OpenFile()); + RINOK(OpenFile()) m_FileIsOpen = true; m_CurrentIndex++; m_IsOk = true; @@ -860,11 +863,11 @@ { if (!NeedMoreWrite()) { - CMyComPtr callbackMessage; - m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); + CMyComPtr callbackMessage; + m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); if (callbackMessage) { - RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, NExtract::NOperationResult::kDataError)); + RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, NExtract::NOperationResult::kDataError)) } return S_OK; } @@ -873,12 +876,12 @@ { if (!NeedMoreWrite()) return S_OK; - UInt64 remain = GetRemain(); + const UInt64 remain = GetRemain(); UInt32 size = (UInt32)1 << 20; if (size > remain) size = (UInt32)remain; UInt32 processedSizeLocal = 0; - RINOK(Write(NULL, size, &processedSizeLocal)); + RINOK(Write(NULL, size, &processedSizeLocal)) } } @@ -887,28 +890,26 @@ { while (m_CurrentIndex < m_ExtractStatuses->Size()) { - HRESULT result = OpenFile(); + const HRESULT result = OpenFile(); if (result != S_FALSE && result != S_OK) return result; m_RealOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) m_CurrentIndex++; } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = m_Database.Items.Size(); if (numItems == 0) return S_OK; - bool testMode = (testModeSpec != 0); UInt64 totalUnPacked = 0; UInt32 i; @@ -917,12 +918,12 @@ for (i = 0; i < numItems; i++) { - unsigned index = allFilesMode ? i : indices[i]; + const unsigned index = allFilesMode ? i : indices[i]; const CMvItem &mvItem = m_Database.Items[index]; const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; if (item.IsDir()) continue; - int folderIndex = m_Database.GetFolderIndex(&mvItem); + const int folderIndex = m_Database.GetFolderIndex(&mvItem); if (folderIndex != lastFolder) totalUnPacked += lastFolderSize; lastFolder = folderIndex; @@ -930,79 +931,68 @@ } totalUnPacked += lastFolderSize; + RINOK(extractCallback->SetTotal(totalUnPacked)) - extractCallback->SetTotal(totalUnPacked); - - totalUnPacked = 0; - - UInt64 totalPacked = 0; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL; - CMyComPtr deflateDecoder; - - NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; - CMyComPtr lzxDecoder; + CMyComPtr2 deflateDecoder; + CMyUniquePtr lzxDecoder; + CMyUniquePtr quantumDecoder; - NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL; - CMyComPtr quantumDecoder; - - CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream(); - CMyComPtr cabBlockInStream = cabBlockInStreamSpec; - if (!cabBlockInStreamSpec->Create()) + CBlockPackData blockPackData; + if (!blockPackData.Create()) return E_OUTOFMEMORY; + CMyComPtr2_Create inBufStream; + CRecordVector extractStatuses; + + totalUnPacked = 0; + UInt64 totalPacked = 0; for (i = 0;;) { lps->OutSize = totalUnPacked; lps->InSize = totalPacked; - RINOK(lps->SetCur()); - + RINOK(lps->SetCur()) if (i >= numItems) break; - unsigned index = allFilesMode ? i : indices[i]; + const unsigned index = allFilesMode ? i : indices[i]; const CMvItem &mvItem = m_Database.Items[index]; const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; - unsigned itemIndex = mvItem.ItemIndex; + const unsigned itemIndex = mvItem.ItemIndex; const CItem &item = db.Items[itemIndex]; i++; if (item.IsDir()) { - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } - int folderIndex = m_Database.GetFolderIndex(&mvItem); + const int folderIndex = m_Database.GetFolderIndex(&mvItem); if (folderIndex < 0) { // If we need previous archive - Int32 askMode= testMode ? + const Int32 askMode= testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)) continue; } @@ -1017,12 +1007,12 @@ for (; i < numItems; i++) { - unsigned indexNext = allFilesMode ? i : indices[i]; + const unsigned indexNext = allFilesMode ? i : indices[i]; const CMvItem &mvItem2 = m_Database.Items[indexNext]; const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; if (item2.IsDir()) continue; - int newFolderIndex = m_Database.GetFolderIndex(&mvItem2); + const int newFolderIndex = m_Database.GetFolderIndex(&mvItem2); if (newFolderIndex != folderIndex) break; @@ -1033,8 +1023,7 @@ curUnpack = item2.GetEndOffset(); } - CFolderOutStream *cabFolderOutStream = new CFolderOutStream; - CMyComPtr outStream(cabFolderOutStream); + CMyComPtr2_Create cabFolderOutStream; const int folderIndex2 = item.GetFolderIndex(db.Folders.Size()); if (folderIndex2 < 0) @@ -1042,9 +1031,8 @@ const CFolder &folder = db.Folders[(unsigned)folderIndex2]; cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, - curUnpack, extractCallback, testMode); + curUnpack, extractCallback, testMode != 0); - cabBlockInStreamSpec->MsZip = false; HRESULT res = S_OK; switch (folder.GetMethod()) @@ -1053,30 +1041,17 @@ break; case NHeader::NMethod::kMSZip: - if (!deflateDecoder) - { - deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; - deflateDecoder = deflateDecoderSpec; - } - cabBlockInStreamSpec->MsZip = true; + deflateDecoder.Create_if_Empty(); break; case NHeader::NMethod::kLZX: - if (!lzxDecoder) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder; - lzxDecoder = lzxDecoderSpec; - } - res = lzxDecoderSpec->SetParams_and_Alloc(folder.MethodMinor); + lzxDecoder.Create_if_Empty(); + res = lzxDecoder->Set_DictBits_and_Alloc(folder.MethodMinor); break; case NHeader::NMethod::kQuantum: - if (!quantumDecoder) - { - quantumDecoderSpec = new NCompress::NQuantum::CDecoder; - quantumDecoder = quantumDecoderSpec; - } - res = quantumDecoderSpec->SetParams(folder.MethodMinor); + quantumDecoder.Create_if_Empty(); + res = quantumDecoder->SetParams(folder.MethodMinor); break; default: @@ -1086,11 +1061,11 @@ if (res == E_INVALIDARG) { - RINOK(cabFolderOutStream->Unsupported()); + RINOK(cabFolderOutStream->Unsupported()) totalUnPacked += curUnpack; continue; } - RINOK(res); + RINOK(res) { unsigned volIndex = mvItem.VolumeIndex; @@ -1114,8 +1089,7 @@ if (bl == 0) { - cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSize(); - RINOK(db2.Stream->Seek((Int64)(db2.StartPosition + folder2.DataStart), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(db2.Stream, db2.StartPosition + folder2.DataStart)) } if (bl == folder2.NumDataBlocks) @@ -1140,41 +1114,33 @@ bl++; if (!keepInputBuffer) - cabBlockInStreamSpec->InitForNewBlock(); + blockPackData.InitForNewBlock(); UInt32 packSize, unpackSize; - res = cabBlockInStreamSpec->PreRead(db2.Stream, packSize, unpackSize); + res = blockPackData.Read(db2.Stream, db2.ArcInfo.GetDataBlockReserveSize(), packSize, unpackSize); if (res == S_FALSE) break; - RINOK(res); + RINOK(res) keepInputBuffer = (unpackSize == 0); if (keepInputBuffer) continue; - UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); + const UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); totalPacked += packSize; - lps->OutSize = totalUnPacked2; - lps->InSize = totalPacked; - RINOK(lps->SetCur()); - - const UInt32 kBlockSizeMax = (1 << 15); - - /* We don't try to reduce last block. - Note that LZX converts data with x86 filter. - and filter needs larger input data than reduced size. - It's simpler to decompress full chunk here. - also we need full block for quantum for more integrity checks */ - - if (unpackSize > kBlockSizeMax) + if (totalUnPacked2 - lps->OutSize >= (1 << 26) + || totalPacked - lps->InSize >= (1 << 24)) { - res = S_FALSE; - break; + lps->OutSize = totalUnPacked2; + lps->InSize = totalPacked; + RINOK(lps->SetCur()) } + const unsigned kBlockSizeMax = 1u << 15; + if (unpackSize != kBlockSizeMax) { - if (thereWasNotAlignedChunk) + if (unpackSize > kBlockSizeMax || thereWasNotAlignedChunk) { res = S_FALSE; break; @@ -1182,55 +1148,95 @@ thereWasNotAlignedChunk = true; } - UInt64 unpackSize64 = unpackSize; - UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail(); + /* We don't try to reduce last block. + Note that LZX converts data with x86 filter. + and filter needs larger input data than reduced size. + It's simpler to decompress full chunk here. + also we need full block for quantum for more integrity checks */ + + const UInt64 unpackSize64 = unpackSize; + const UInt32 packSizeChunk = blockPackData.GetPackSize(); switch (folder2.GetMethod()) { case NHeader::NMethod::kNone: - res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL); + if (unpackSize != packSizeChunk) + { + res = S_FALSE; + break; + } + res = WriteStream(cabFolderOutStream, blockPackData.GetData(), packSizeChunk); break; case NHeader::NMethod::kMSZip: - deflateDecoderSpec->Set_KeepHistory(keepHistory); - /* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block. - But PyCabArc can create CAB archives that doesn't have finish marker at the end of block. + { + /* v24.00 : fixed : we check 2-bytes MSZIP signature only + when block was constructed from all volumes. */ + const Byte *packData = blockPackData.GetData(); + if (unpackSize > (1u << 15) + 12 /* MSZIP specification */ + || packSizeChunk < 2 || GetUi16(packData) != 0x4b43) + { + res = S_FALSE; + break; + } + const UInt32 packSizeChunk_2 = packSizeChunk - 2; + inBufStream->Init(packData + 2, packSizeChunk_2); + + deflateDecoder->Set_KeepHistory(keepHistory); + /* v9.31: now we follow MSZIP specification that requires + to finish deflate stream at the end of each block. + But PyCabArc can create CAB archives that don't have + finish marker at the end of block. Cabarc probably ignores such errors in cab archives. - Maybe we also should ignore that error? + Maybe we also should ignore such error? Or we should extract full file and show the warning? */ - deflateDecoderSpec->Set_NeedFinishInput(true); - res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL); + deflateDecoder->Set_NeedFinishInput(true); + res = deflateDecoder.Interface()->Code(inBufStream, cabFolderOutStream, NULL, &unpackSize64, NULL); if (res == S_OK) { - if (!deflateDecoderSpec->IsFinished()) + if (!deflateDecoder->IsFinished()) + res = S_FALSE; + if (!deflateDecoder->IsFinalBlock()) res = S_FALSE; - if (!deflateDecoderSpec->IsFinalBlock()) + if (deflateDecoder->GetInputProcessedSize() != packSizeChunk_2) res = S_FALSE; } break; + } case NHeader::NMethod::kLZX: - lzxDecoderSpec->SetKeepHistory(keepHistory); - lzxDecoderSpec->KeepHistoryForNext = true; - - res = lzxDecoderSpec->Code(cabBlockInStreamSpec->GetData(), packSizeChunk, unpackSize); - + lzxDecoder->Set_KeepHistory(keepHistory); + lzxDecoder->Set_KeepHistoryForNext(true); + res = lzxDecoder->Code_WithExceedReadWrite(blockPackData.GetData(), + packSizeChunk, unpackSize); if (res == S_OK) - res = WriteStream(outStream, - lzxDecoderSpec->GetUnpackData(), - lzxDecoderSpec->GetUnpackSize()); + res = WriteStream(cabFolderOutStream, + lzxDecoder->GetUnpackData(), + lzxDecoder->GetUnpackSize()); break; case NHeader::NMethod::kQuantum: - res = quantumDecoderSpec->Code(cabBlockInStreamSpec->GetData(), - packSizeChunk, outStream, unpackSize, keepHistory); + { + res = quantumDecoder->Code(blockPackData.GetData(), + packSizeChunk, unpackSize, keepHistory); + if (res == S_OK) + { + const UInt32 num = unpackSize; + res = WriteStream(cabFolderOutStream, + quantumDecoder->GetDataPtr() - num, num); + } + break; + } + default: + // it's unexpected case, because we checked method before + // res = E_NOTIMPL; break; } if (res != S_OK) { if (res != S_FALSE) - RINOK(res); + return res; break; } @@ -1239,13 +1245,13 @@ if (res == S_OK) { - RINOK(cabFolderOutStream->WriteEmptyFiles()); + RINOK(cabFolderOutStream->WriteEmptyFiles()) } } if (res != S_OK || cabFolderOutStream->NeedMoreWrite()) { - RINOK(cabFolderOutStream->FlushCorrupted((unsigned)folderIndex2)); + RINOK(cabFolderOutStream->FlushCorrupted((unsigned)folderIndex2)) } totalUnPacked += curUnpack; @@ -1257,7 +1263,7 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = m_Database.Items.Size(); return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.h 2013-11-02 15:57:53.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // CabHandler.h -#ifndef __CAB_HANDLER_H -#define __CAB_HANDLER_H +#ifndef ZIP7_INC_CAB_HANDLER_H +#define ZIP7_INC_CAB_HANDLER_H #include "../../../Common/MyCom.h" @@ -12,16 +12,8 @@ namespace NArchive { namespace NCab { -class CHandler: - public IInArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInArchive) +Z7_CLASS_IMP_CHandler_IInArchive_0 - INTERFACE_IInArchive(;) - -private: CMvDatabaseEx m_Database; UString _errorMessage; bool _isArc; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabHeader.h 2015-02-10 08:17:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/CabHeader.h -#ifndef __ARCHIVE_CAB_HEADER_H -#define __ARCHIVE_CAB_HEADER_H +#ifndef ZIP7_INC_ARCHIVE_CAB_HEADER_H +#define ZIP7_INC_ARCHIVE_CAB_HEADER_H #include "../../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabIn.cpp 2021-01-25 15:17:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.cpp 2024-01-01 07:00:00.000000000 +0000 @@ -76,21 +76,20 @@ const Byte *Signature; UInt32 SignatureSize; - UInt32 _HeaderSize; - UInt32 _AlignSize; - UInt32 _BufUseCapacity; + UInt32 _headerSize; + UInt32 _alignSize; + UInt32 _bufUseCapacity; + const UInt64 *SearchLimit; ISequentialInStream *Stream; UInt64 Processed; // Global offset of start of Buf - const UInt64 *SearchLimit; - UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize) { - _HeaderSize = headerSize; - for (_AlignSize = (1 << 5); _AlignSize < _HeaderSize; _AlignSize <<= 1); - _BufUseCapacity = basicSize + _AlignSize; - return _BufUseCapacity + 16; + _headerSize = headerSize; + for (_alignSize = (1 << 5); _alignSize < _headerSize; _alignSize <<= 1); + _bufUseCapacity = basicSize + _alignSize; + return _bufUseCapacity + 16; } /* @@ -108,19 +107,19 @@ { Buf[End] = Signature[0]; // it's for fast search; - while (End - Pos >= _HeaderSize) + while (End - Pos >= _headerSize) { const Byte *p = Buf + Pos; - Byte b = Signature[0]; + const Byte b = Signature[0]; for (;;) { if (*p == b) { break; } p++; if (*p == b) { break; } p++; } Pos = (UInt32)(p - Buf); - if (End - Pos < _HeaderSize) + if (End - Pos < _headerSize) { - Pos = End - _HeaderSize + 1; + Pos = End - _headerSize + 1; break; } UInt32 i; @@ -130,28 +129,28 @@ Pos++; } - if (Pos >= _AlignSize) + if (Pos >= _alignSize) { - UInt32 num = (Pos & ~(_AlignSize - 1)); + const UInt32 num = (Pos & ~(_alignSize - 1)); Processed += num; Pos -= num; End -= num; memmove(Buf, Buf + num, End); } - UInt32 rem = _BufUseCapacity - End; + UInt32 rem = _bufUseCapacity - End; if (SearchLimit) { if (Processed + Pos > *SearchLimit) return S_FALSE; - UInt64 rem2 = *SearchLimit - (Processed + End) + _HeaderSize; + const UInt64 rem2 = *SearchLimit - (Processed + End) + _headerSize; if (rem > rem2) rem = (UInt32)rem2; } UInt32 processedSize; - if (Processed == 0 && rem == _BufUseCapacity - _HeaderSize) - rem -= _AlignSize; // to make reads more aligned. - RINOK(Stream->Read(Buf + End, rem, &processedSize)); + if (Processed == 0 && rem == _bufUseCapacity - _headerSize) + rem -= _alignSize; // to make reads more aligned. + RINOK(Stream->Read(Buf + End, rem, &processedSize)) if (processedSize == 0) return S_FALSE; End += processedSize; @@ -189,7 +188,7 @@ HeaderError = false; db.Clear(); - RINOK(db.Stream->Seek(0, STREAM_SEEK_CUR, &db.StartPosition)); + RINOK(InStream_GetPos(db.Stream, db.StartPosition)) // UInt64 temp = db.StartPosition; CByteBuffer buffer; @@ -201,12 +200,12 @@ // for (int iii = 0; iii < 10000; iii++) { - // db.StartPosition = temp; RINOK(db.Stream->Seek(db.StartPosition, STREAM_SEEK_SET, NULL)); + // db.StartPosition = temp; RINOK(InStream_SeekSet(db.Stream, db.StartPosition)) const UInt32 kMainHeaderSize = 32; Byte header[kMainHeaderSize]; const UInt32 kBufSize = 1 << 15; - RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize)); + RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize)) if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header)) { limitedStreamSpec = new CLimitedSequentialInStream; @@ -216,7 +215,7 @@ buffer.Alloc(kBufSize); memcpy(buffer, header, kMainHeaderSize); UInt32 numProcessedBytes; - RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes)); + RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes)) _inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize); } else @@ -241,14 +240,14 @@ for (;;) { - RINOK(finder.Find()); + RINOK(finder.Find()) if (ai.Parse(finder.Buf + finder.Pos)) { db.StartPosition = finder.Processed + finder.Pos; limitedStreamSpec = new CLimitedSequentialInStream; limitedStreamSpec->SetStream(db.Stream); limitedStream = limitedStreamSpec; - UInt32 remInFinder = finder.End - finder.Pos; + const UInt32 remInFinder = finder.End - finder.Pos; if (ai.Size <= remInFinder) { limitedStreamSpec->Init(0); @@ -273,7 +272,7 @@ _tempBuf.Alloc(1 << 12); Byte p[16]; - unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0); + const unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0); Read(p, nextSize); ai.SetID = Get16(p); ai.CabinetNumber = Get16(p + 2); @@ -311,7 +310,7 @@ { // printf("\n!!! Seek Error !!!!\n"); // fflush(stdout); - RINOK(db.Stream->Seek((Int64)(db.StartPosition + ai.FileHeadersOffset), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(db.Stream, db.StartPosition + ai.FileHeadersOffset)) limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset); _inBuffer.Init(); } @@ -325,8 +324,8 @@ item.Size = Get32(p); item.Offset = Get32(p + 4); item.FolderIndex = Get16(p + 8); - UInt16 pureDate = Get16(p + 10); - UInt16 pureTime = Get16(p + 12); + const UInt16 pureDate = Get16(p + 10); + const UInt16 pureTime = Get16(p + 12); item.Time = (((UInt32)pureDate << 16)) | pureTime; item.Attributes = Get16(p + 14); @@ -357,7 +356,7 @@ -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) { @@ -365,17 +364,17 @@ const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex]; const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; const CItem &item1 = db1.Items[p1->ItemIndex]; - const CItem &item2 = db2.Items[p2->ItemIndex];; - bool isDir1 = item1.IsDir(); - bool isDir2 = item2.IsDir(); + const CItem &item2 = db2.Items[p2->ItemIndex]; + const bool isDir1 = item1.IsDir(); + const bool isDir2 = item2.IsDir(); if (isDir1 && !isDir2) return -1; if (isDir2 && !isDir1) return 1; - int f1 = mvDb.GetFolderIndex(p1); - int f2 = mvDb.GetFolderIndex(p2); - RINOZ(MyCompare(f1, f2)); - RINOZ(MyCompare(item1.Offset, item2.Offset)); - RINOZ(MyCompare(item1.Size, item2.Size)); - RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); + const int f1 = mvDb.GetFolderIndex(p1); + const int f2 = mvDb.GetFolderIndex(p2); + RINOZ(MyCompare(f1, f2)) + RINOZ(MyCompare(item1.Offset, item2.Offset)) + RINOZ(MyCompare(item1.Size, item2.Size)) + RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)) return MyCompare(p1->ItemIndex, p2->ItemIndex); } @@ -387,7 +386,7 @@ const CDatabaseEx &db1 = Volumes[p1->VolumeIndex]; const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; const CItem &item1 = db1.Items[p1->ItemIndex]; - const CItem &item2 = db2.Items[p2->ItemIndex];; + const CItem &item2 = db2.Items[p2->ItemIndex]; return GetFolderIndex(p1) == GetFolderIndex(p2) && item1.Offset == item2.Offset && item1.Size == item2.Size @@ -434,7 +433,7 @@ FOR_VECTOR (i, Items) { - int folderIndex = GetFolderIndex(&Items[i]); + const int folderIndex = GetFolderIndex(&Items[i]); while (folderIndex >= (int)FolderStartFileIndex.Size()) FolderStartFileIndex.Add(i); } @@ -452,7 +451,7 @@ if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty()) return false; const CFolder &f0 = db0.Folders.Back(); - const CFolder &f1 = db1.Folders.Front(); + const CFolder &f1 = db1.Folders.FrontItem(); if (f0.MethodMajor != f1.MethodMajor || f0.MethodMinor != f1.MethodMinor) return false; @@ -466,14 +465,14 @@ FOR_VECTOR (i, Items) { const CMvItem &mvItem = Items[i]; - int fIndex = GetFolderIndex(&mvItem); + const int fIndex = GetFolderIndex(&mvItem); if (fIndex >= (int)FolderStartFileIndex.Size()) return false; const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; if (item.IsDir()) continue; - int folderIndex = GetFolderIndex(&mvItem); + const int folderIndex = GetFolderIndex(&mvItem); if (folderIndex != prevFolder) prevFolder = folderIndex; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabIn.h 2021-01-25 15:08:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabIn.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/CabIn.h -#ifndef __ARCHIVE_CAB_IN_H -#define __ARCHIVE_CAB_IN_H +#ifndef ZIP7_INC_ARCHIVE_CAB_IN_H +#define ZIP7_INC_ARCHIVE_CAB_IN_H #include "../../../Common/MyBuffer.h" #include "../../../Common/MyCom.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabItem.h 2021-01-25 15:07:17.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/CabItem.h -#ifndef __ARCHIVE_CAB_ITEM_H -#define __ARCHIVE_CAB_ITEM_H +#ifndef ZIP7_INC_ARCHIVE_CAB_ITEM_H +#define ZIP7_INC_ARCHIVE_CAB_ITEM_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/CabRegister.cpp 2015-03-25 12:05:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/CabRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -10,7 +10,7 @@ namespace NCab { REGISTER_ARC_I( - "Cab", "cab", 0, 8, + "Cab", "cab", NULL, 8, NHeader::kMarker, 0, NArcInfoFlags::kFindSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Cab/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Cab/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.cpp 2020-09-28 09:26:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.cpp 2024-01-01 08:00:00.000000000 +0000 @@ -2,6 +2,7 @@ #include "StdAfx.h" +#include "../../../Common/AutoPtr.h" #include "../../../Common/ComTry.h" #include "../../../Common/StringConvert.h" #include "../../../Common/UTFConvert.h" @@ -27,9 +28,9 @@ namespace NArchive { namespace NChm { -// #define _CHM_DETAILS +// #define CHM_DETAILS -#ifdef _CHM_DETAILS +#ifdef CHM_DETAILS enum { @@ -45,7 +46,7 @@ kpidMethod, kpidBlock - #ifdef _CHM_DETAILS + #ifdef CHM_DETAILS , L"Section", kpidSection, kpidOffset @@ -63,7 +64,7 @@ IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { // COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -97,7 +98,7 @@ // COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -160,7 +161,7 @@ prop = m_Database.GetFolder(index); break; - #ifdef _CHM_DETAILS + #ifdef CHM_DETAILS case kpidSection: prop = (UInt32)item.Section; break; case kpidOffset: prop = (UInt32)item.Offset; break; @@ -173,34 +174,10 @@ COM_TRY_END } -/* -class CProgressImp: public CProgressVirt -{ - CMyComPtr _callback; -public: - STDMETHOD(SetTotal)(const UInt64 *numFiles); - STDMETHOD(SetCompleted)(const UInt64 *numFiles); - CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}; -}; - -STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles) -{ - if (_callback) - return _callback->SetCompleted(numFiles, NULL); - return S_OK; -} - -STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) -{ - if (_callback) - return _callback->SetCompleted(numFiles, NULL); - return S_OK; -} -*/ -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); @@ -208,13 +185,13 @@ { CInArchive archive(_help2); // CProgressImp progressImp(openArchiveCallback); - HRESULT res = archive.Open(inStream, maxCheckStartPosition, m_Database); + const HRESULT res = archive.Open(inStream, maxCheckStartPosition, m_Database); if (!archive.IsArc) m_ErrorFlags |= kpv_ErrorFlags_IsNotArc; if (archive.HeadersError) m_ErrorFlags |= kpv_ErrorFlags_HeadersError; if (archive.UnexpectedEnd) m_ErrorFlags |= kpv_ErrorFlags_UnexpectedEnd; if (archive.UnsupportedFeature) m_ErrorFlags |= kpv_ErrorFlags_UnsupportedFeature; - RINOK(res); + RINOK(res) /* if (m_Database.LowLevel) return S_FALSE; @@ -229,7 +206,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { m_ErrorFlags = 0; m_Database.Clear(); @@ -237,15 +214,22 @@ return S_OK; } -class CChmFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP +Z7_CLASS_IMP_NOQIB_1( + CChmFolderOutStream + , ISequentialOutStream +) + bool m_TestMode; + bool m_IsOk; + bool m_FileIsOpen; + const CFilesDatabase *m_Database; + CMyComPtr m_ExtractCallback; + CMyComPtr m_RealOutStream; + UInt64 m_RemainFileSize; + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +public: UInt64 m_FolderSize; UInt64 m_PosInFolder; @@ -255,19 +239,6 @@ unsigned m_CurrentIndex; unsigned m_NumFiles; -private: - const CFilesDatabase *m_Database; - CMyComPtr m_ExtractCallback; - bool m_TestMode; - - bool m_IsOk; - bool m_FileIsOpen; - UInt64 m_RemainFileSize; - CMyComPtr m_RealOutStream; - - HRESULT OpenFile(); - HRESULT WriteEmptyFiles(); -public: void Init( const CFilesDatabase *database, IArchiveExtractCallback *extractCallback, @@ -290,12 +261,12 @@ HRESULT CChmFolderOutStream::OpenFile() { - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? m_TestMode ? NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kExtract : NExtract::NAskMode::kSkip; m_RealOutStream.Release(); - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)) if (!m_RealOutStream && !m_TestMode) askMode = NExtract::NAskMode::kSkip; return m_ExtractCallback->PrepareOperation(askMode); @@ -307,13 +278,13 @@ return S_OK; for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++) { - UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); + const UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); if (fileSize != 0) return S_OK; - HRESULT result = OpenFile(); + const HRESULT result = OpenFile(); m_RealOutStream.Release(); - RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(result) + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } return S_OK; } @@ -358,7 +329,7 @@ RINOK(m_ExtractCallback->SetOperationResult( m_IsOk ? NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) m_FileIsOpen = false; } if (realProcessed > 0) @@ -395,7 +366,7 @@ if (fileOffset == m_PosInSection) { - RINOK(OpenFile()); + RINOK(OpenFile()) m_FileIsOpen = true; m_CurrentIndex++; m_IsOk = true; @@ -406,7 +377,7 @@ return WriteEmptyFiles(); } -STDMETHODIMP CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return Write2(data, size, processedSize, true); } @@ -423,7 +394,7 @@ { UInt32 size = (UInt32)MyMin(maxSize - m_PosInFolder, (UInt64)kBufferSize); UInt32 processedSizeLocal = 0; - RINOK(Write2(buffer, size, &processedSizeLocal, false)); + RINOK(Write2(buffer, size, &processedSizeLocal, false)) if (processedSizeLocal == 0) return S_OK; } @@ -431,11 +402,11 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = m_Database.NewFormat ? 1: @@ -444,21 +415,18 @@ m_Database.Indices.Size()); if (numItems == 0) return S_OK; - bool testMode = (testModeSpec != 0); + const bool testMode = (testModeSpec != 0); UInt64 currentTotalSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - UInt32 i; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(m_Stream); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(m_Stream); + + UInt32 i; if (m_Database.LowLevel) { @@ -471,7 +439,7 @@ for (i = 0; i < numItems; i++) totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { @@ -479,13 +447,13 @@ lps->InSize = currentTotalSize; // Change it lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr realOutStream; - Int32 askMode= testMode ? + const Int32 askMode= testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (m_Database.NewFormat) { @@ -495,10 +463,10 @@ continue; if (!testMode) { - UInt32 size = m_Database.NewFormatString.Len(); - RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)); + const unsigned size = m_Database.NewFormatString.Len(); + RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)) } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -508,36 +476,36 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (item.Section != 0) { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } if (testMode) { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); + RINOK(InStream_SeekSet(m_Stream, m_Database.ContentOffset + item.Offset)) + inStream->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + RINOK(extractCallback->SetOperationResult((copyCoder->TotalSize == item.Size) ? NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return S_OK; } - UInt64 lastFolderIndex = ((UInt64)0 - 1); + UInt64 lastFolderIndex = (UInt64)0 - 1; for (i = 0; i < numItems; i++) { - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = m_Database.Items[m_Database.Indices[index]]; const UInt64 sectionIndex = item.Section; if (item.IsDir() || item.Size == 0) @@ -564,12 +532,10 @@ } } - RINOK(extractCallback->SetTotal(currentTotalSize)); + RINOK(extractCallback->SetTotal(currentTotalSize)) - NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; - CMyComPtr lzxDecoder; - CChmFolderOutStream *chmFolderOutStream = 0; - CMyComPtr outStream; + CMyUniquePtr lzxDecoder; + CMyComPtr2_Create chmFolderOutStream; currentTotalSize = 0; @@ -579,7 +545,7 @@ for (i = 0;;) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + RINOK(extractCallback->SetCompleted(¤tTotalSize)) if (i >= numItems) break; @@ -588,17 +554,17 @@ i++; const CItem &item = m_Database.Items[m_Database.Indices[index]]; const UInt64 sectionIndex = item.Section; - Int32 askMode= testMode ? + const Int32 askMode= testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; if (item.IsDir()) { CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -608,21 +574,21 @@ if (item.Size == 0 || sectionIndex == 0) { CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) Int32 opRes = NExtract::NOperationResult::kOK; if (!testMode && item.Size != 0) { - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != item.Size) + RINOK(InStream_SeekSet(m_Stream, m_Database.ContentOffset + item.Offset)) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item.Size) opRes = NExtract::NOperationResult::kDataError; } realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) currentTotalSize += item.Size; continue; } @@ -631,11 +597,11 @@ { // we must report error here; CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)) continue; } @@ -644,34 +610,24 @@ if (!section.IsLzx()) { CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; - if (!chmFolderOutStream) - { - chmFolderOutStream = new CChmFolderOutStream; - outStream = chmFolderOutStream; - } - chmFolderOutStream->Init(&m_Database, extractCallback, testMode); - if (!lzxDecoderSpec) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder; - lzxDecoder = lzxDecoderSpec; - } + lzxDecoder.Create_if_Empty(); UInt64 folderIndex = m_Database.GetFolder(index); const UInt64 compressedPos = m_Database.ContentOffset + section.Offset; - RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits())); + RINOK(lzxDecoder->Set_DictBits_and_Alloc(lzxInfo.GetNumDictBits())) const CItem *lastItem = &item; extractStatuses.Clear(); @@ -679,14 +635,14 @@ for (;; folderIndex++) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + RINOK(extractCallback->SetCompleted(¤tTotalSize)) - UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); + const UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); UInt64 finishPos = lastItem->Offset + lastItem->Size; - UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); + const UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); lastFolderIndex = m_Database.GetLastFolder(index); - UInt64 folderSize = lzxInfo.GetFolderSize(); + const UInt64 folderSize = lzxInfo.GetFolderSize(); UInt64 unPackSize = folderSize; if (extractStatuses.IsEmpty()) @@ -702,7 +658,7 @@ const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]]; if (nextItem.Section != sectionIndex) break; - UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); + const UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); if (nextFolderIndex != folderIndex) break; for (index++; index < nextIndex; index++) @@ -727,44 +683,48 @@ try { - UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); + const UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); const CResetTable &rt = lzxInfo.ResetTable; - UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); + const UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); for (UInt32 b = 0; b < numBlocks; b++) { UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; - RINOK(extractCallback->SetCompleted(&completedSize)); + RINOK(extractCallback->SetCompleted(&completedSize)) UInt64 bCur = startBlock + b; if (bCur >= rt.ResetOffsets.Size()) return E_FAIL; - UInt64 offset = rt.ResetOffsets[(unsigned)bCur]; + const UInt64 offset = rt.ResetOffsets[(unsigned)bCur]; UInt64 compressedSize; rt.GetCompressedSizeOfBlock(bCur, compressedSize); // chm writes full blocks. So we don't need to use reduced size for last block - RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(m_Stream); - streamSpec->Init(compressedSize); + RINOK(InStream_SeekSet(m_Stream, compressedPos + offset)) + inStream->Init(compressedSize); - lzxDecoderSpec->SetKeepHistory(b > 0); + lzxDecoder->Set_KeepHistory(b > 0); - size_t compressedSizeT = (size_t)compressedSize; - if (compressedSizeT != compressedSize) - throw 2; - packBuf.AllocAtLeast(compressedSizeT); - - HRESULT res = ReadStream_FALSE(inStream, packBuf, compressedSizeT); - - if (res == S_OK) + HRESULT res = S_FALSE; + if (compressedSize <= (1u << 30)) { - lzxDecoderSpec->KeepHistoryForNext = true; - res = lzxDecoderSpec->Code(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize; + const unsigned kAdditionalInputSize = 32; + const size_t compressedSizeT = (size_t)compressedSize; + const size_t allocSize = compressedSizeT + kAdditionalInputSize; + if (allocSize <= compressedSize) + throw 2; + packBuf.AllocAtLeast(allocSize); + res = ReadStream_FALSE(inStream, packBuf, compressedSizeT); if (res == S_OK) - res = WriteStream(chmFolderOutStream, - lzxDecoderSpec->GetUnpackData(), - lzxDecoderSpec->GetUnpackSize()); + { + memset(packBuf + compressedSizeT, 0xff, kAdditionalInputSize); + lzxDecoder->Set_KeepHistoryForNext(true); + res = lzxDecoder->Code_WithExceedReadWrite(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize; + if (res == S_OK) + res = WriteStream(chmFolderOutStream, + lzxDecoder->GetUnpackData(), + lzxDecoder->GetUnpackSize()); + } } if (res != S_OK) @@ -777,7 +737,7 @@ } catch(...) { - RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)); + RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)) } currentTotalSize += folderSize; @@ -790,9 +750,9 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { - *numItems = m_Database.NewFormat ? 1: + *numItems = m_Database.NewFormat ? 1: (m_Database.LowLevel ? m_Database.Items.Size(): m_Database.Indices.Size()); @@ -805,7 +765,7 @@ REGISTER_ARC_I_CLS( CHandler(false), - "Chm", "chm chi chq chw", 0, 0xE9, + "Chm", "chm chi chq chw", NULL, 0xE9, k_Signature, 0, 0, @@ -819,7 +779,7 @@ REGISTER_ARC_I_CLS( CHandler(true), - "Hxs", "hxs hxi hxr hxq hxw lit", 0, 0xCE, + "Hxs", "hxs hxi hxr hxq hxw lit", NULL, 0xCE, k_Signature, 0, NArcInfoFlags::kFindSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.h 2013-11-03 07:12:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmHandler.h 2023-03-26 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ChmHandler.h -#ifndef __ARCHIVE_CHM_HANDLER_H -#define __ARCHIVE_CHM_HANDLER_H +#ifndef ZIP7_INC_ARCHIVE_CHM_HANDLER_H +#define ZIP7_INC_ARCHIVE_CHM_HANDLER_H #include "../../../Common/MyCom.h" @@ -12,22 +12,14 @@ namespace NArchive { namespace NChm { -class CHandler: - public IInArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - - bool _help2; - CHandler(bool help2): _help2(help2) {} +Z7_CLASS_IMP_CHandler_IInArchive_0 -private: CFilesDatabase m_Database; CMyComPtr m_Stream; + bool _help2; UInt32 m_ErrorFlags; +public: + CHandler(bool help2): _help2(help2) {} }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.cpp 2021-04-18 08:30:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.cpp 2024-01-01 08:00:00.000000000 +0000 @@ -10,6 +10,7 @@ #include "../../../Common/UTFConvert.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" #include "ChmIn.h" @@ -46,20 +47,15 @@ return memcmp(g1, g2, 16) == 0; } -static char GetHex(unsigned v) +static void PrintByte(unsigned b, AString &s) { - return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); -} - -static void PrintByte(Byte b, AString &s) -{ - s += GetHex(b >> 4); - s += GetHex(b & 0xF); + s += (char)GET_HEX_CHAR_UPPER(b >> 4); + s += (char)GET_HEX_CHAR_LOWER(b & 0xF); } AString CMethodInfo::GetGuidString() const { - char s[48]; + char s[16 * 2 + 8]; RawLeGuidToString_Braced(Guid, s); // MyStringUpper_Ascii(s); return (AString)s; @@ -92,12 +88,14 @@ else { s = GetGuidString(); - if (ControlData.Size() > 0) + /* + if (ControlData.Size() > 0 && ControlData.Size() <= (1 << 6)) { - s += ':'; + s.Add_Colon(); for (size_t i = 0; i < ControlData.Size(); i++) PrintByte(ControlData[i], s); } + */ } } return s; @@ -176,7 +174,7 @@ UInt64 val = 0; for (int i = 0; i < 9; i++) { - Byte b = ReadByte(); + const unsigned b = ReadByte(); val |= (b & 0x7F); if (b < 0x80) return val; @@ -205,7 +203,7 @@ s.Empty(); while (size-- != 0) { - wchar_t c = ReadUInt16(); + const wchar_t c = ReadUInt16(); if (c == 0) { Skip(2 * size); @@ -217,7 +215,7 @@ HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size) { - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, pos)) CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr limitedStream(streamSpec); streamSpec->SetStream(inStream); @@ -231,7 +229,7 @@ HRESULT CInArchive::ReadDirEntry(CDatabase &database) { CItem item; - UInt64 nameLen = ReadEncInt(); + const UInt64 nameLen = ReadEncInt(); if (nameLen == 0 || nameLen > (1 << 13)) return S_FALSE; ReadString((unsigned)nameLen, item.Name); @@ -332,7 +330,7 @@ // One quickref entry exists for every n entries in the file, where n // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. - UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk + const UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt32(); // Always 0 @@ -344,19 +342,19 @@ for (;;) { - UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; - UInt32 offsetLimit = dirChunkSize - quickrefLength; + const UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + const UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; - RINOK(ReadDirEntry(database)); + RINOK(ReadDirEntry(database)) numItems++; } Skip(quickrefLength - 2); - unsigned rrr = ReadUInt16(); + const unsigned rrr = ReadUInt16(); if (rrr != numItems) { // Lazarus 9-26-2 chm contains 0 here. @@ -537,40 +535,46 @@ unsigned numItems = 0; for (;;) { - UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; - UInt32 offsetLimit = dirChunkSize - quickrefLength; + const UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + const UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; if (database.NewFormat) { - UInt16 nameLen = ReadUInt16(); + const unsigned nameLen = ReadUInt16(); if (nameLen == 0) return S_FALSE; UString name; - ReadUString((unsigned)nameLen, name); + ReadUString(nameLen, name); AString s; ConvertUnicodeToUTF8(name, s); - Byte b = ReadByte(); - s.Add_Space(); - PrintByte(b, s); + { + const unsigned b = ReadByte(); + s.Add_Space(); + PrintByte(b, s); + } s.Add_Space(); UInt64 len = ReadEncInt(); // then number of items ? // then length ? // then some data (binary encoding?) - while (len-- != 0) + if (len > 1u << 29) // what limit here we need? + return S_FALSE; + if (len) + do { - b = ReadByte(); + const unsigned b = ReadByte(); PrintByte(b, s); } + while (--len); database.NewFormatString += s; database.NewFormatString += "\r\n"; } else { - RINOK(ReadDirEntry(database)); + RINOK(ReadDirEntry(database)) } numItems++; } @@ -612,11 +616,11 @@ { AString s (kStorage); s += name; - s += '/'; + s.Add_Slash(); return s; } -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param) { @@ -634,9 +638,9 @@ } else { - RINOZ(MyCompare(item1.Section, item2.Section)); - RINOZ(MyCompare(item1.Offset, item2.Offset)); - RINOZ(MyCompare(item1.Size, item2.Size)); + RINOZ(MyCompare(item1.Section, item2.Section)) + RINOZ(MyCompare(item1.Offset, item2.Offset)) + RINOZ(MyCompare(item1.Size, item2.Size)) } return MyCompare(*p1, *p2); } @@ -705,13 +709,13 @@ { { // The NameList file - RINOK(DecompressStream(inStream, database, (AString)kNameList)); + RINOK(DecompressStream(inStream, database, (AString)kNameList)) /* UInt16 length = */ ReadUInt16(); UInt16 numSections = ReadUInt16(); for (unsigned i = 0; i < numSections; i++) { CSectionInfo section; - UInt16 nameLen = ReadUInt16(); + const unsigned nameLen = ReadUInt16(); UString name; ReadUString(nameLen, name); if (ReadUInt16() != 0) @@ -740,7 +744,7 @@ if (database.Help2Format) { // Transform List - RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); + RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)) if ((_chunkSize & 0xF) != 0) return S_FALSE; unsigned numGuids = (unsigned)(_chunkSize / 0x10); @@ -762,7 +766,7 @@ { // Control Data - RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)); + RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)) FOR_VECTOR (mi, section.Methods) { @@ -781,38 +785,43 @@ { // There is bug in VC6, if we use function call as parameter for inline function - UInt32 val32 = ReadUInt32(); - int n = GetLog(val32); + const UInt32 val32 = ReadUInt32(); + const int n = GetLog(val32); if (n < 0 || n > 16) return S_FALSE; - li.ResetIntervalBits = n; + li.ResetIntervalBits = (unsigned)n; } { - UInt32 val32 = ReadUInt32(); - int n = GetLog(val32); + const UInt32 val32 = ReadUInt32(); + const int n = GetLog(val32); if (n < 0 || n > 16) return S_FALSE; - li.WindowSizeBits = n; + li.WindowSizeBits = (unsigned)n; } li.CacheSize = ReadUInt32(); numDWORDS -= 5; - while (numDWORDS-- != 0) + if (numDWORDS) + do ReadUInt32(); + while (--numDWORDS); } else { - UInt32 numBytes = numDWORDS * 4; - method.ControlData.Alloc(numBytes); - ReadBytes(method.ControlData, numBytes); + if (numDWORDS > 1u << 27) + return S_FALSE; + const size_t numBytes = (size_t)numDWORDS * 4; + // method.ControlData.Alloc(numBytes); + // ReadBytes(method.ControlData, numBytes); + Skip(numBytes); } } } { // SpanInfo - RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)); + RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)) section.UncompressedSize = ReadUInt64(); } @@ -824,7 +833,7 @@ { // ResetTable; RINOK(DecompressStream(inStream, database, transformPrefix + - method.GetGuidString() + kResetTable)); + method.GetGuidString() + kResetTable)) CResetTable &rt = method.LzxInfo.ResetTable; if (_chunkSize < 4) @@ -840,10 +849,10 @@ } else { - UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) + const UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) if (ver != 2 && ver != 3) return S_FALSE; - UInt32 numEntries = ReadUInt32(); + const UInt32 numEntries = ReadUInt32(); const unsigned kEntrySize = 8; if (ReadUInt32() != kEntrySize) return S_FALSE; @@ -906,7 +915,7 @@ database.Help2Format = _help2; const UInt32 chmVersion = 3; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); + RINOK(InStream_GetPos(inStream, database.StartPosition)) if (!_inBuffer.Create(1 << 14)) return E_OUTOFMEMORY; @@ -942,7 +951,7 @@ } database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize; - RINOK(OpenHelp2(inStream, database)); + RINOK(OpenHelp2(inStream, database)) if (database.NewFormat) return S_OK; } @@ -952,7 +961,7 @@ return S_FALSE; if (ReadUInt32() != chmVersion) return S_FALSE; - RINOK(OpenChm(inStream, database)); + RINOK(OpenChm(inStream, database)) } @@ -969,7 +978,7 @@ database.HighLevelClear(); return S_OK; } - RINOK(res); + RINOK(res) if (!database.CheckSectionRefs()) HeadersError = true; database.LowLevel = false; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.h 2022-07-14 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/ChmIn.h 2024-01-01 08:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/ChmIn.h -#ifndef __ARCHIVE_CHM_IN_H -#define __ARCHIVE_CHM_IN_H +#ifndef ZIP7_INC_ARCHIVE_CHM_IN_H +#define ZIP7_INC_ARCHIVE_CHM_IN_H #include "../../../Common/MyBuffer.h" #include "../../../Common/MyString.h" @@ -45,9 +45,9 @@ struct CDatabase { + CObjectVector Items; UInt64 StartPosition; UInt64 ContentOffset; - CObjectVector Items; AString NewFormatString; bool Help2Format; bool NewFormat; @@ -59,7 +59,7 @@ { FOR_VECTOR (i, Items) if (Items[i].Name == name) - return i; + return (int)i; return -1; } @@ -137,14 +137,14 @@ return 0; } - UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; } + UInt64 GetFolderSize() const { return (UInt64)kBlockSize << ResetIntervalBits; } UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); } UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); } UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; } bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const { - UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + const UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); if (blockIndex >= ResetTable.ResetOffsets.Size()) return false; offset = ResetTable.ResetOffsets[(unsigned)blockIndex]; @@ -162,7 +162,7 @@ struct CMethodInfo { Byte Guid[16]; - CByteBuffer ControlData; + // CByteBuffer ControlData; CLzxInfo LzxInfo; bool IsLzx() const; @@ -188,9 +188,9 @@ class CFilesDatabase: public CDatabase { public: - bool LowLevel; CUIntVector Indices; CObjectVector Sections; + bool LowLevel; UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; } UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Chm/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Chm/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ComHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ComHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ComHandler.cpp 2021-03-25 16:20:10.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ComHandler.cpp 2025-04-26 11:18:00.000000000 +0000 @@ -26,8 +26,8 @@ namespace NArchive { namespace NCom { -#define SIGNATURE { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } -static const Byte kSignature[] = SIGNATURE; +static const Byte kSignature[] = + { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; enum EType { @@ -68,7 +68,7 @@ static const Byte kRootStorage = 5; } -static const UInt32 kNameSizeMax = 64; +static const unsigned kNameSizeMax = 64; struct CItem { @@ -98,29 +98,30 @@ class CDatabase { - UInt32 NumSectorsInMiniStream; CObjArray MiniSids; HRESULT AddNode(int parent, UInt32 did); -public: +public: CObjArray Fat; - UInt32 FatSize; - CObjArray Mat; - UInt32 MatSize; - CObjectVector Items; CRecordVector Refs; +private: + UInt32 NumSectorsInMiniStream; +public: + UInt32 MatSize; + UInt32 FatSize; UInt32 LongStreamMinSize; unsigned SectorSizeBits; unsigned MiniSectorSizeBits; Int32 MainSubfile; + EType Type; UInt64 PhySize; - EType Type; + UInt64 PhySize_Aligned; bool IsNotArcType() const { @@ -129,10 +130,12 @@ Type != k_Type_Msp; } - void UpdatePhySize(UInt64 val) + void UpdatePhySize(UInt64 val, UInt64 val_Aligned) { if (PhySize < val) PhySize = val; + if (PhySize_Aligned < val_Aligned) + PhySize_Aligned = val_Aligned; } HRESULT ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid); HRESULT ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest); @@ -145,14 +148,14 @@ UInt64 GetItemPackSize(UInt64 size) const { - UInt64 mask = ((UInt64)1 << (IsLargeStream(size) ? SectorSizeBits : MiniSectorSizeBits)) - 1; + const UInt64 mask = ((UInt32)1 << (IsLargeStream(size) ? SectorSizeBits : MiniSectorSizeBits)) - 1; return (size + mask) & ~mask; } bool GetMiniCluster(UInt32 sid, UInt64 &res) const { - unsigned subBits = SectorSizeBits - MiniSectorSizeBits; - UInt32 fid = sid >> subBits; + const unsigned subBits = SectorSizeBits - MiniSectorSizeBits; + const UInt32 fid = sid >> subBits; if (fid >= NumSectorsInMiniStream) return false; res = (((UInt64)MiniSids[fid] + 1) << subBits) + (sid & ((1 << subBits) - 1)); @@ -165,15 +168,16 @@ HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) { - UpdatePhySize(((UInt64)sid + 2) << sectorSizeBits); - RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL)); + const UInt64 end = ((UInt64)sid + 2) << sectorSizeBits; + UpdatePhySize(end, end); + RINOK(InStream_SeekSet(inStream, (((UInt64)sid + 1) << sectorSizeBits))) return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits); } HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) { - RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)); - UInt32 sectorSize = (UInt32)1 << sectorSizeBits; + RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)) + const UInt32 sectorSize = (UInt32)1 << sectorSizeBits; for (UInt32 t = 0; t < sectorSize; t += 4) *dest++ = Get32(buf + t); return S_OK; @@ -205,6 +209,7 @@ void CDatabase::Clear() { PhySize = 0; + PhySize_Aligned = 0; Fat.Free(); MiniSids.Free(); @@ -227,14 +232,14 @@ CRef ref; ref.Parent = parent; ref.Did = did; - int index = Refs.Add(ref); + const unsigned index = Refs.Add(ref); if (Refs.Size() > Items.Size()) return S_FALSE; - RINOK(AddNode(parent, item.LeftDid)); - RINOK(AddNode(parent, item.RightDid)); + RINOK(AddNode(parent, item.LeftDid)) + RINOK(AddNode(parent, item.RightDid)) if (item.IsDir()) { - RINOK(AddNode(index, item.SonDid)); + RINOK(AddNode((int)index, item.SonDid)) } return S_OK; } @@ -244,12 +249,12 @@ UString res; for (unsigned i = 0; i < s.Len(); i++) { - wchar_t c = s[i]; - if (c < 0x20) + const wchar_t c = s[i]; + if ((unsigned)(int)c < 0x20) { - res += '['; - res.Add_UInt32(c); - res += ']'; + res.Add_Char('['); + res.Add_UInt32((UInt32)(unsigned)(int)c); + res.Add_Char(']'); } else res += c; @@ -304,20 +309,20 @@ if (i == 0) res += k_Msi_ID; */ - c -= k_Msi_StartUnicodeChar; + c -= (wchar_t)k_Msi_StartUnicodeChar; - unsigned c0 = (unsigned)c & k_Msi_CharMask; - unsigned c1 = (unsigned)c >> k_Msi_NumBits; + const unsigned c0 = (unsigned)c & k_Msi_CharMask; + const unsigned c1 = (unsigned)c >> k_Msi_NumBits; if (c1 <= k_Msi_NumChars) { - res += k_Msi_Chars[c0]; + res.Add_Char(k_Msi_Chars[c0]); if (c1 == k_Msi_NumChars) break; - res += k_Msi_Chars[c1]; + res.Add_Char(k_Msi_Chars[c1]); } else - res += k_Msi_SpecChar; + res.Add_Char(k_Msi_SpecChar); } return true; } @@ -360,7 +365,7 @@ if (!s.IsEmpty()) s.InsertAtFront(WCHAR_PATH_SEPARATOR); s.Insert(0, ConvertName(item.Name)); - index = ref.Parent; + index = (unsigned)ref.Parent; } return s; } @@ -368,14 +373,14 @@ HRESULT CDatabase::Update_PhySize_WithItem(unsigned index) { const CItem &item = Items[index]; - bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); + const bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); if (!isLargeStream) return S_OK; - unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; + const unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; // streamSpec->Size = item.Size; - UInt32 clusterSize = (UInt32)1 << bsLog; - UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; + const UInt32 clusterSize = (UInt32)1 << bsLog; + const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; if (numClusters64 >= ((UInt32)1 << 31)) return S_FALSE; UInt32 sid = item.Sid; @@ -389,7 +394,13 @@ { if (sid >= FatSize) return S_FALSE; - UpdatePhySize(((UInt64)sid + 2) << bsLog); + UInt64 end = ((UInt64)sid + 1) << bsLog; + const UInt64 end_Aligned = end + clusterSize; + if (size < clusterSize) + end += size; + else + end = end_Aligned; + UpdatePhySize(end, end_Aligned); sid = Fat[sid]; } if (size <= clusterSize) @@ -415,8 +426,8 @@ const UInt32 kHeaderSize = 512; Byte p[kHeaderSize]; PhySize = kHeaderSize; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)); - if (memcmp(p, kSignature, ARRAY_SIZE(kSignature)) != 0) + RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)) + if (memcmp(p, kSignature, Z7_ARRAY_SIZE(kSignature)) != 0) return S_FALSE; if (Get16(p + 0x1A) > 4) // majorVer return S_FALSE; @@ -461,7 +472,7 @@ UInt32 sid = Get32(p + 0x44); for (UInt32 s = 0; s < numSectorsForBat; s++) { - RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)); + RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)) i += numSidsInSec - 1; sid = bat[i]; } @@ -474,7 +485,7 @@ { if (j >= numBatItems) return S_FALSE; - RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)); + RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)) } FatSize = numFatItems = i; } @@ -490,7 +501,7 @@ UInt32 sid = Get32(p + 0x3C); // short-sector table SID for (i = 0; i < numMatItems; i += numSidsInSec) { - RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)); + RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)) if (sid >= numFatItems) return S_FALSE; sid = Fat[sid]; @@ -511,11 +522,15 @@ if (used[sid]) return S_FALSE; used[sid] = 1; - RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)); + RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)) for (UInt32 i = 0; i < sectSize; i += 128) { CItem item; item.Parse(sect + i, mode64bit); + // we use (item.Size) check here. + // so we don't need additional overflow checks for (item.Size +) in another code + if (item.Size >= ((UInt64)1 << 63)) + return S_FALSE; Items.Add(item); } sid = Fat[sid]; @@ -563,7 +578,7 @@ } } - RINOK(AddNode(-1, root.SonDid)); + RINOK(AddNode(-1, root.SonDid)) unsigned numCabs = 0; @@ -584,7 +599,7 @@ ) { numCabs++; - MainSubfile = i; + MainSubfile = (int)i; } } } @@ -599,6 +614,17 @@ } } { + if (PhySize != PhySize_Aligned) + { + /* some msi (in rare cases) have unaligned size of archive, + where there is no padding data after payload data in last cluster of archive */ + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) + if (PhySize != fileSize) + PhySize = PhySize_Aligned; + } + } + { FOR_VECTOR (t, Items) { const CItem &item = Items[t]; @@ -634,17 +660,11 @@ return S_OK; } -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CMyComPtr _stream; CDatabase _db; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; static const Byte kProps[] = @@ -666,7 +686,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -684,7 +704,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -705,9 +725,9 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); @@ -722,18 +742,18 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _db.Clear(); _stream.Release(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _db.Refs.Size(); if (numItems == 0) @@ -746,36 +766,34 @@ if (!item.IsDir()) totalSize += item.Size; } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 totalPackSize; totalSize = totalPackSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); for (i = 0; i < numItems; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); - Int32 index = allFilesMode ? i : indices[i]; + RINOK(lps->SetCur()) + const UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = _db.Items[_db.Refs[index].Did]; - + Int32 res; + { CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -784,8 +802,8 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 res = NExtract::NOperationResult::kDataError; + RINOK(extractCallback->PrepareOperation(askMode)) + res = NExtract::NOperationResult::kDataError; CMyComPtr inStream; HRESULT hres = GetStream(index, &inStream); if (hres == S_FALSE) @@ -794,45 +812,45 @@ res = NExtract::NOperationResult::kUnsupportedMethod; else { - RINOK(hres); + RINOK(hres) if (inStream) { - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) res = NExtract::NOperationResult::kOK; } } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); + } + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _db.Refs.Size(); return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; - UInt32 itemIndex = _db.Refs[index].Did; + *stream = NULL; + const UInt32 itemIndex = _db.Refs[index].Did; const CItem &item = _db.Items[itemIndex]; CClusterInStream *streamSpec = new CClusterInStream; CMyComPtr streamTemp = streamSpec; streamSpec->Stream = _stream; streamSpec->StartOffset = 0; - bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); - int bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; + const bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); + const unsigned bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; streamSpec->BlockSizeLog = bsLog; streamSpec->Size = item.Size; - UInt32 clusterSize = (UInt32)1 << bsLog; - UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; + const UInt32 clusterSize = (UInt32)1 << bsLog; + const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; if (numClusters64 >= ((UInt32)1 << 31)) return E_NOTIMPL; streamSpec->Vector.ClearAndReserve((unsigned)numClusters64); @@ -864,14 +882,14 @@ } if (sid != NFatID::kEndOfChain) return S_FALSE; - RINOK(streamSpec->InitAndSeek()); + RINOK(streamSpec->InitAndSeek()) *stream = streamTemp.Detach(); return S_OK; COM_TRY_END } REGISTER_ARC_I( - "Compound", "msi msp doc xls ppt", 0, 0xE5, + "Compound", "msi msp doc xls ppt", NULL, 0xE5, kSignature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.cpp 2021-03-07 09:01:09.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.cpp 2023-09-26 16:00:00.000000000 +0000 @@ -6,7 +6,7 @@ #ifdef USE_MIXER_ST -STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; @@ -21,7 +21,7 @@ } -STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -32,7 +32,7 @@ return result; } -STDMETHODIMP COutStreamCalcSize::OutStreamFinish() +Z7_COM7F_IMF(COutStreamCalcSize::OutStreamFinish()) { HRESULT result = S_OK; if (_stream) @@ -73,7 +73,7 @@ if (getInStreamProcessedSize) { UInt64 processed; - RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)); + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) if (processed != (UInt64)(Int64)-1) { const UInt64 size = PackSizes[0]; @@ -97,7 +97,7 @@ if (!PackSizePointers[i]) continue; UInt64 processed; - RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed)); + RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed)) if (processed != (UInt64)(Int64)-1) { const UInt64 size = PackSizes[i]; @@ -343,13 +343,11 @@ { IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2); { - CMyComPtr s; - unk->QueryInterface(IID_ISequentialInStream, (void**)&s); + Z7_DECL_CMyComPtr_QI_FROM(ISequentialInStream, s, unk) c2.CanRead = (s != NULL); } { - CMyComPtr s; - unk->QueryInterface(IID_ISequentialOutStream, (void**)&s); + Z7_DECL_CMyComPtr_QI_FROM(ISequentialOutStream, s, unk) c2.CanWrite = (s != NULL); } } @@ -382,8 +380,8 @@ if (!seqInStream) return E_NOTIMPL; - UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; - UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; + const UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; + const UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; bool isSet = false; @@ -394,8 +392,8 @@ if (setStream) { CMyComPtr seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)); - RINOK(setStream->SetInStream(seqInStream2)); + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)) + RINOK(setStream->SetInStream(seqInStream2)) isSet = true; } } @@ -410,8 +408,8 @@ for (UInt32 i = 0; i < numInStreams; i++) { CMyComPtr seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)); - RINOK(setStream2->SetInStream2(i, seqInStream2)); + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)) + RINOK(setStream2->SetInStream2(i, seqInStream2)) } } @@ -451,7 +449,7 @@ return E_INVALIDARG; RINOK(GetInStream2(inStreams, /* inSizes, */ - _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream)); + _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream)) while (_binderStreams.Size() <= (unsigned)bond) _binderStreams.AddNew(); @@ -504,7 +502,7 @@ if (bond < 0) return E_INVALIDARG; - UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); UInt32 coderIndex = inStreamIndex; UInt32 coderStreamIndex = 0; @@ -523,8 +521,8 @@ if (!seqOutStream) return E_NOTIMPL; - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; bool isSet = false; @@ -535,8 +533,8 @@ if (setOutStream) { CMyComPtr seqOutStream2; - RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)); - RINOK(setOutStream->SetOutStream(seqOutStream2)); + RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)) + RINOK(setOutStream->SetOutStream(seqOutStream2)) isSet = true; } } @@ -552,8 +550,8 @@ for (UInt32 i = 0; i < numOutStreams; i++) { CMyComPtr seqOutStream2; - RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)); - RINOK(setStream2->SetOutStream2(i, seqOutStream2)); + RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)) + RINOK(setStream2->SetOutStream2(i, seqOutStream2)) } */ } @@ -616,7 +614,7 @@ if (bond < 0) return E_INVALIDARG; - UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); UInt32 coderIndex = inStreamIndex; UInt32 coderStreamIndex = 0; @@ -639,8 +637,8 @@ { CCoder &coder = _coders[coderIndex]; - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; HRESULT res = S_OK; for (unsigned i = 0; i < numOutStreams; i++) @@ -671,7 +669,7 @@ if (coder.NumStreams != 1) break; - UInt32 st = _bi.Coder_to_Stream[ci]; + const UInt32 st = _bi.Coder_to_Stream[ci]; if (_bi.IsStream_in_PackStreams(st)) break; const int bond = _bi.FindBond_for_PackStream(st); @@ -706,32 +704,32 @@ dataAfterEnd_Error = false; _binderStreams.Clear(); - unsigned ci = MainCoderIndex; + const unsigned ci = MainCoderIndex; const CCoder &mainCoder = _coders[MainCoderIndex]; CObjectVector< CMyComPtr > seqInStreams; CObjectVector< CMyComPtr > seqOutStreams; - UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; - UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; + const UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; + const UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; - UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; - UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + const UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + const UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; UInt32 i; for (i = 0; i < numInStreams; i++) { CMyComPtr seqInStream; - RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)); + RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)) seqInStreams.Add(seqInStream); } for (i = 0; i < numOutStreams; i++) { CMyComPtr seqOutStream; - RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)); + RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)) seqOutStreams.Add(seqOutStream); } @@ -755,20 +753,24 @@ CMyComPtr initEncoder; coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder); if (initEncoder) - RINOK(initEncoder->InitEncoder()); + { + RINOK(initEncoder->InitEncoder()) + } } else { CMyComPtr setOutStreamSize; coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); if (setOutStreamSize) + { RINOK(setOutStreamSize->SetOutStreamSize( - EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)); + EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)) + } } } - const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : &mainCoder.PackSizePointers.Front(); - const UInt64 * const *outSizes2 = EncodeMode ? &mainCoder.PackSizePointers.Front() : &mainCoder.UnpackSizePointer; + const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : mainCoder.PackSizePointers.ConstData(); + const UInt64 * const *outSizes2 = EncodeMode ? mainCoder.PackSizePointers.ConstData() : &mainCoder.UnpackSizePointer; HRESULT res; if (mainCoder.Coder) @@ -781,8 +783,8 @@ else { res = mainCoder.Coder2->Code( - &seqInStreamsSpec.Front(), isSizes2, numInStreams, - &seqOutStreamsSpec.Front(), outSizes2, numOutStreams, + seqInStreamsSpec.ConstData(), isSizes2, numInStreams, + seqOutStreamsSpec.ConstData(), outSizes2, numOutStreams, progress); } @@ -811,7 +813,7 @@ for (i = 0; i < _coders.Size(); i++) { - RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */)); + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */)) } return S_OK; @@ -834,7 +836,7 @@ coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); if (setOutStreamSize) { - RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)); + RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)) } } @@ -907,8 +909,8 @@ progress); else Result = Coder2->Code( - &InStreamPointers.Front(), EncodeMode ? &UnpackSizePointer : &PackSizePointers.Front(), numInStreams, - &OutStreamPointers.Front(), EncodeMode ? &PackSizePointers.Front(): &UnpackSizePointer, numOutStreams, + InStreamPointers.ConstData(), EncodeMode ? &UnpackSizePointer : PackSizePointers.ConstData(), numInStreams, + OutStreamPointers.ConstData(), EncodeMode ? PackSizePointers.ConstData(): &UnpackSizePointer, numOutStreams, progress); } @@ -919,7 +921,7 @@ _streamBinders.Clear(); FOR_VECTOR (i, _bi.Bonds) { - // RINOK(_streamBinders.AddNew().CreateEvents()); + // RINOK(_streamBinders.AddNew().CreateEvents()) _streamBinders.AddNew(); } return S_OK; @@ -946,7 +948,7 @@ { FOR_VECTOR (i, _streamBinders) { - RINOK(_streamBinders[i].Create_ReInit()); + RINOK(_streamBinders[i].Create_ReInit()) } return S_OK; } @@ -986,8 +988,8 @@ UInt32 j; - unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; - unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; + const unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; + const unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; coderInfo.InStreams.Clear(); for (j = 0; j < numInStreams; j++) @@ -1102,8 +1104,8 @@ if (wres != 0) return HRESULT_FROM_WIN32(wres); - RINOK(ReturnIfError(E_ABORT)); - RINOK(ReturnIfError(E_OUTOFMEMORY)); + RINOK(ReturnIfError(E_ABORT)) + RINOK(ReturnIfError(E_OUTOFMEMORY)) for (i = 0; i < _coders.Size(); i++) { @@ -1115,7 +1117,7 @@ return result; } - RINOK(ReturnIfError(S_FALSE)); + RINOK(ReturnIfError(S_FALSE)) for (i = 0; i < _coders.Size(); i++) { @@ -1126,7 +1128,7 @@ for (i = 0; i < _coders.Size(); i++) { - RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */)); + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */)) } return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.h 2021-01-24 16:19:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/CoderMixer2.h 2023-04-05 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // CoderMixer2.h -#ifndef __CODER_MIXER2_H -#define __CODER_MIXER2_H +#ifndef ZIP7_INC_CODER_MIXER2_H +#define ZIP7_INC_CODER_MIXER2_H #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" @@ -10,11 +10,11 @@ #include "../../Common/CreateCoder.h" -#ifdef _7ZIP_ST +#ifdef Z7_ST #define USE_MIXER_ST #else #define USE_MIXER_MT - #ifndef _SFX + #ifndef Z7_SFX #define USE_MIXER_ST #endif #endif @@ -28,18 +28,13 @@ #ifdef USE_MIXER_ST -class CSequentialInStreamCalcSize: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_COM_1( + CSequentialInStreamCalcSize + , ISequentialInStream +) + bool _wasFinished; CMyComPtr _stream; UInt64 _size; - bool _wasFinished; public: void SetStream(ISequentialInStream *stream) { _stream = stream; } void Init() @@ -53,19 +48,14 @@ }; -class COutStreamCalcSize: - public ISequentialOutStream, - public IOutStreamFinish, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + COutStreamCalcSize + , ISequentialOutStream + , IOutStreamFinish +) CMyComPtr _stream; UInt64 _size; public: - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init() { _size = 0; } @@ -122,7 +112,7 @@ bool SetUnpackCoder() { bool isOk = false; - FOR_VECTOR(i, Coders) + FOR_VECTOR (i, Coders) { if (FindBond_for_UnpackStream(i) < 0) { @@ -142,7 +132,7 @@ int FindStream_in_PackStreams(UInt32 streamIndex) const { - FOR_VECTOR(i, PackStreams) + FOR_VECTOR (i, PackStreams) if (PackStreams[i] == streamIndex) return (int)i; return -1; @@ -189,11 +179,12 @@ class CCoder { - CLASS_NO_COPY(CCoder); + Z7_CLASS_NO_COPY(CCoder) public: CMyComPtr Coder; CMyComPtr Coder2; UInt32 NumStreams; + bool Finish; UInt64 UnpackSize; const UInt64 *UnpackSizePointer; @@ -201,8 +192,6 @@ CRecordVector PackSizes; CRecordVector PackSizePointers; - bool Finish; - CCoder(): Finish(false) {} void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish); @@ -251,7 +240,7 @@ // , InternalPackSizeError(false) {} - virtual ~CMixer() {}; + virtual ~CMixer() {} /* Sequence of calling: @@ -323,7 +312,8 @@ public CMixer, public CMyUnknownImp { - CLASS_NO_COPY(CMixerST) + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerST) HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ UInt32 outStreamIndex, ISequentialInStream **inStreamRes); @@ -340,23 +330,21 @@ CObjectVector _binderStreams; - MY_UNKNOWN_IMP - CMixerST(bool encodeMode); - ~CMixerST(); + ~CMixerST() Z7_DESTRUCTOR_override; - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual HRESULT ReInit2(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } virtual HRESULT Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, ICompressProgressInfo *progress, - bool &dataAfterEnd_Error); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; HRESULT GetMainUnpackStream( ISequentialInStream * const *inStreams, @@ -372,12 +360,12 @@ class CCoderMT: public CCoder, public CVirtThread { - CLASS_NO_COPY(CCoderMT) + Z7_CLASS_NO_COPY(CCoderMT) CRecordVector InStreamPointers; CRecordVector OutStreamPointers; private: - void Execute(); + virtual void Execute() Z7_override; public: bool EncodeMode; HRESULT Result; @@ -397,7 +385,7 @@ class CReleaser { - CLASS_NO_COPY(CReleaser) + Z7_CLASS_NO_COPY(CReleaser) CCoderMT &_c; public: CReleaser(CCoderMT &c): _c(c) {} @@ -405,7 +393,14 @@ }; CCoderMT(): EncodeMode(false) {} - virtual ~CCoderMT() { CVirtThread::WaitThreadFinish(); } + ~CCoderMT() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before CCoder destructor, + and before destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } void Code(ICompressProgressInfo *progress); }; @@ -416,32 +411,31 @@ public CMixer, public CMyUnknownImp { - CLASS_NO_COPY(CMixerMT) + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerMT) CObjectVector _streamBinders; HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams); HRESULT ReturnIfError(HRESULT code); - // virtual ~CMixerMT() {}; + // virtual ~CMixerMT() {} public: CObjectVector _coders; - MY_UNKNOWN_IMP - - virtual HRESULT SetBindInfo(const CBindInfo &bindInfo); - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual HRESULT ReInit2(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) + virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) Z7_override; + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } virtual HRESULT Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, ICompressProgressInfo *progress, - bool &dataAfterEnd_Error); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; CMixerMT(bool encodeMode): CMixer(encodeMode) {} }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.cpp 2012-09-19 11:36:06.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -4,7 +4,7 @@ #include "DummyOutStream.h" -STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = size; HRESULT res = S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.h 2013-01-17 08:10:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/DummyOutStream.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,24 +1,22 @@ // DummyOutStream.h -#ifndef __DUMMY_OUT_STREAM_H -#define __DUMMY_OUT_STREAM_H +#ifndef ZIP7_INC_DUMMY_OUT_STREAM_H +#define ZIP7_INC_DUMMY_OUT_STREAM_H #include "../../../Common/MyCom.h" #include "../../IStream.h" -class CDummyOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CDummyOutStream + , ISequentialOutStream +) CMyComPtr _stream; UInt64 _size; public: void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } void ReleaseStream() { _stream.Release(); } void Init() { _size = 0; } - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _size; } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/FindSignature.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/FindSignature.cpp 2015-08-01 09:18:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.cpp 2024-01-24 17:00:00.000000000 +0000 @@ -16,36 +16,36 @@ { resPos = 0; CByteBuffer byteBuffer2(signatureSize); - RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)); + RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)) if (memcmp(byteBuffer2, signature, signatureSize) == 0) return S_OK; - const UInt32 kBufferSize = (1 << 16); + const size_t kBufferSize = 1 << 16; CByteBuffer byteBuffer(kBufferSize); Byte *buffer = byteBuffer; - UInt32 numPrevBytes = signatureSize - 1; + size_t numPrevBytes = signatureSize - 1; memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); resPos = 1; for (;;) { - if (limit != NULL) + if (limit) if (resPos > *limit) return S_FALSE; do { - UInt32 numReadBytes = kBufferSize - numPrevBytes; + const size_t numReadBytes = kBufferSize - numPrevBytes; UInt32 processedSize; - RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); - numPrevBytes += processedSize; + RINOK(stream->Read(buffer + numPrevBytes, (UInt32)numReadBytes, &processedSize)) + numPrevBytes += (size_t)processedSize; if (processedSize == 0) return S_FALSE; } while (numPrevBytes < signatureSize); - UInt32 numTests = numPrevBytes - signatureSize + 1; - for (UInt32 pos = 0; pos < numTests; pos++) + const size_t numTests = numPrevBytes - signatureSize + 1; + for (size_t pos = 0; pos < numTests; pos++) { - Byte b = signature[0]; + const Byte b = signature[0]; for (; buffer[pos] != b && pos < numTests; pos++); if (pos == numTests) break; @@ -60,3 +60,31 @@ memmove(buffer, buffer + numTests, numPrevBytes); } } + +namespace NArchive { +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) +{ + areThereNonZeros = false; + numZeros = 0; + const size_t kBufSize = 1 << 11; + Byte buf[kBufSize]; + for (;;) + { + UInt32 size = 0; + RINOK(stream->Read(buf, kBufSize, &size)) + if (size == 0) + return S_OK; + for (UInt32 i = 0; i < size; i++) + if (buf[i] != 0) + { + areThereNonZeros = true; + numZeros += i; + return S_OK; + } + numZeros += size; + if (numZeros > maxSize) + return S_OK; + } +} +} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/FindSignature.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/FindSignature.h 2015-08-01 09:18:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/FindSignature.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // FindSignature.h -#ifndef __FIND_SIGNATURE_H -#define __FIND_SIGNATURE_H +#ifndef ZIP7_INC_FIND_SIGNATURE_H +#define ZIP7_INC_FIND_SIGNATURE_H #include "../../IStream.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.cpp 2022-05-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.cpp 2025-07-02 06:00:00.000000000 +0000 @@ -4,8 +4,6 @@ #include "../../../Common/StringToInt.h" -#include "../Common/ParseProperties.h" - #include "HandlerOut.h" namespace NArchive { @@ -82,13 +80,14 @@ return true; } + bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres) { hres = S_OK; if (name.IsPrefixedBy_Ascii_NoCase("mt")) { - #ifndef _7ZIP_ST + #ifndef Z7_ST _numThreads = _numProcessors; _numThreads_WasForced = false; hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced); @@ -112,7 +111,7 @@ } -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value) { @@ -127,7 +126,7 @@ SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level); } -#ifndef _7ZIP_ST +#ifndef Z7_ST static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value) { @@ -151,7 +150,12 @@ SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); } -#endif // _7ZIP_ST +void CMultiMethodProps::Set_Method_NumThreadGroups_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreadGroups) +{ + SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreadGroups, numThreadGroups); +} + +#endif // Z7_ST void CMultiMethodProps::InitMulti() @@ -189,7 +193,7 @@ { name.Delete(0, 2); UInt32 v = 9; - RINOK(ParsePropToUInt32(name, value, v)); + RINOK(ParsePropToUInt32(name, value, v)) _analysisLevel = (int)v; return S_OK; } @@ -208,13 +212,13 @@ } UInt32 number; - unsigned index = ParseStringToUInt32(name, number); - UString realName = name.Ptr(index); + const unsigned index = ParseStringToUInt32(name, number); + const UString realName = name.Ptr(index); if (index == 0) { if (name.IsEqualTo("f")) { - HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); + const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); if (res == S_OK) return res; if (value.vt != VT_BSTR) @@ -224,7 +228,7 @@ number = 0; } if (number > 64) - return E_FAIL; + return E_INVALIDARG; for (unsigned j = _methods.Size(); j <= number; j++) _methods.AddNew(); return _methods[number].ParseMethodFromPROPVARIANT(realName, value); @@ -250,7 +254,7 @@ if (name.IsPrefixedBy_Ascii_NoCase("x")) { UInt32 a = 9; - RINOK(ParsePropToUInt32(name.Ptr(1), value, a)); + RINOK(ParsePropToUInt32(name.Ptr(1), value, a)) _level = a; AddProp_Level(a); // processed = true; @@ -264,7 +268,7 @@ return S_OK; } } - RINOK(ParseMethodFromPROPVARIANT(name, value)); + RINOK(ParseMethodFromPROPVARIANT(name, value)) return S_OK; } @@ -275,7 +279,7 @@ for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetProperty(names[i], values[i])); + RINOK(SetProperty(names[i], values[i])) } return S_OK; @@ -286,7 +290,7 @@ static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) { - RINOK(PROPVARIANT_to_bool(prop, dest.Val)); + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) dest.Def = true; return S_OK; } @@ -300,7 +304,7 @@ if (name.IsPrefixedBy_Ascii_NoCase("tp")) { UInt32 v = 0; - RINOK(ParsePropToUInt32(name.Ptr(2), prop, v)); + RINOK(ParsePropToUInt32(name.Ptr(2), prop, v)) Prec = v; return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.h 2022-05-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/HandlerOut.h 2025-07-02 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // HandlerOut.h -#ifndef __HANDLER_OUT_H -#define __HANDLER_OUT_H +#ifndef ZIP7_INC_HANDLER_OUT_H +#define ZIP7_INC_HANDLER_OUT_H #include "../../../Windows/System.h" @@ -17,12 +17,22 @@ void InitCommon() { // _Write_MTime = true; - #ifndef _7ZIP_ST - _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors(); - _numThreads_WasForced = false; - #endif - - UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28; + { +#ifndef Z7_ST + _numThreads_WasForced = false; + UInt32 numThreads; +#ifdef _WIN32 + NWindows::NSystem::CProcessAffinity aff; + numThreads = aff.Load_and_GetNumberOfThreads(); + _numThreadGroups = aff.IsGroupMode ? aff.Groups.GroupSizes.Size() : 0; +#else + numThreads = NWindows::NSystem::GetNumberOfProcessors(); +#endif // _WIN32 + _numProcessors = _numThreads = numThreads; +#endif // Z7_ST + } + + size_t memAvail = (size_t)sizeof(size_t) << 28; _memAvail = memAvail; _memUsage_Compress = memAvail; _memUsage_Decompress = memAvail; @@ -46,16 +56,19 @@ } public: - #ifndef _7ZIP_ST +#ifndef Z7_ST UInt32 _numThreads; UInt32 _numProcessors; +#ifdef _WIN32 + UInt32 _numThreadGroups; +#endif bool _numThreads_WasForced; - #endif +#endif bool _memUsage_WasSet; UInt64 _memUsage_Compress; UInt64 _memUsage_Decompress; - UInt64 _memAvail; + size_t _memAvail; bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); @@ -63,7 +76,7 @@ }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY class CMultiMethodProps: public CCommonMethodProps { @@ -80,10 +93,12 @@ void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const; - #ifndef _7ZIP_ST +#ifndef Z7_ST static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads); static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads); - #endif + + static void Set_Method_NumThreadGroups_IfNotFinded(CMethodProps &props, UInt32 numThreadGroups); +#endif unsigned GetNumEmptyMethods() const diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 2014-12-23 07:43:17.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -4,22 +4,33 @@ #include "InStreamWithCRC.h" -STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; - if (_stream) - result = _stream->Read(data, size, &realProcessed); - _size += realProcessed; - if (size != 0 && realProcessed == 0) - _wasFinished = true; - _crc = CrcUpdate(_crc, data, realProcessed); + if (size != 0) + { + if (_stream) + result = _stream->Read(data, size, &realProcessed); + _size += realProcessed; + if (realProcessed == 0) + _wasFinished = true; + else + _crc = CrcUpdate(_crc, data, realProcessed); + } if (processedSize) *processedSize = realProcessed; return result; } -STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamWithCRC::GetSize(UInt64 *size)) +{ + *size = _fullSize; + return S_OK; +} + + +Z7_COM7F_IMF(CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; @@ -36,7 +47,7 @@ return result; } -STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin != STREAM_SEEK_SET || offset != 0) return E_FAIL; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.h 2010-05-15 09:55:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/InStreamWithCRC.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // InStreamWithCRC.h -#ifndef __IN_STREAM_WITH_CRC_H -#define __IN_STREAM_WITH_CRC_H +#ifndef ZIP7_INC_IN_STREAM_WITH_CRC_H +#define ZIP7_INC_IN_STREAM_WITH_CRC_H #include "../../../../C/7zCrc.h" @@ -9,26 +9,29 @@ #include "../../IStream.h" -class CSequentialInStreamWithCRC: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_NOQIB_2( + CSequentialInStreamWithCRC + , ISequentialInStream + , IStreamGetSize +) CMyComPtr _stream; UInt64 _size; UInt32 _crc; bool _wasFinished; + UInt64 _fullSize; public: - void SetStream(ISequentialInStream *stream) { _stream = stream; } + + CSequentialInStreamWithCRC(): + _fullSize((UInt64)(Int64)-1) + {} + + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void SetFullSize(UInt64 fullSize) { _fullSize = fullSize; } void Init() { _size = 0; - _wasFinished = false; _crc = CRC_INIT_VAL; + _wasFinished = false; } void ReleaseStream() { _stream.Release(); } UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } @@ -36,22 +39,16 @@ bool WasFinished() const { return _wasFinished; } }; -class CInStreamWithCRC: - public IInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -private: +Z7_CLASS_IMP_IInStream( + CInStreamWithCRC +) CMyComPtr _stream; UInt64 _size; UInt32 _crc; // bool _wasFinished; public: - void SetStream(IInStream *stream) { _stream = stream; } + void SetStream(IInStream *stream) { _stream = stream; } void Init() { _size = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.cpp 2022-01-09 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.cpp 2025-06-18 11:00:00.000000000 +0000 @@ -47,6 +47,25 @@ } +#if WCHAR_PATH_SEPARATOR != L'/' +void ReplaceToWinSlashes(UString &name, bool useBackslashReplacement) +{ + // name.Replace(kUnixPathSepar, kOsPathSepar); + const unsigned len = name.Len(); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = name[i]; + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + else if (useBackslashReplacement && c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + else + continue; + name.ReplaceOneCharAtPos(i, c); + } +} +#endif + void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool #if WCHAR_PATH_SEPARATOR != L'/' useBackslashReplacement @@ -57,21 +76,7 @@ return; #if WCHAR_PATH_SEPARATOR != L'/' - { - // name.Replace(kUnixPathSepar, kOsPathSepar); - const unsigned len = name.Len(); - for (unsigned i = 0; i < len; i++) - { - wchar_t c = name[i]; - if (c == L'/') - c = WCHAR_PATH_SEPARATOR; - else if (useBackslashReplacement && c == L'\\') - c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme - else - continue; - name.ReplaceOneCharAtPos(i, c); - } - } + ReplaceToWinSlashes(name, useBackslashReplacement); #endif if (name.Back() == kOsPathSepar) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.h 2022-01-09 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ItemNameUtils.h 2025-06-16 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/Common/ItemNameUtils.h -#ifndef __ARCHIVE_ITEM_NAME_UTILS_H -#define __ARCHIVE_ITEM_NAME_UTILS_H +#ifndef ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H +#define ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H #include "../../../Common/MyString.h" @@ -13,6 +13,9 @@ UString GetOsPath(const UString &name); UString GetOsPath_Remove_TailSlash(const UString &name); +#if WCHAR_PATH_SEPARATOR != L'/' +void ReplaceToWinSlashes(UString &name, bool useBackslashReplacement); +#endif void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool useBackslashReplacement = false); void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *s, unsigned len); void NormalizeSlashes_in_FileName_for_OsPath(UString &name); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/MultiStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/MultiStream.cpp 2021-01-24 16:26:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.cpp 2023-04-05 08:00:00.000000000 +0000 @@ -4,7 +4,7 @@ #include "MultiStream.h" -STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -23,10 +23,7 @@ else if (_pos >= m.GlobalOffset + m.Size) left = mid + 1; else - { - _streamIndex = mid; break; - } mid = (left + right) / 2; } _streamIndex = mid; @@ -36,12 +33,14 @@ UInt64 localPos = _pos - s.GlobalOffset; if (localPos != s.LocalPos) { - RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos)); + RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos)) } - UInt64 rem = s.Size - localPos; - if (size > rem) - size = (UInt32)rem; - HRESULT result = s.Stream->Read(data, size, &size); + { + const UInt64 rem = s.Size - localPos; + if (size > rem) + size = (UInt32)rem; + } + const HRESULT result = s.Stream->Read(data, size, &size); _pos += size; s.LocalPos += size; if (processedSize) @@ -49,7 +48,7 @@ return result; } -STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -72,6 +71,9 @@ public ISequentialOutStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) + unsigned _volIndex; UInt64 _volSize; UInt64 _curPos; @@ -80,8 +82,6 @@ CCRC _crc; public: - MY_UNKNOWN_IMP - CFileItem _file; CUpdateOptions _options; CMyComPtr VolumeCallback; @@ -98,7 +98,6 @@ } HRESULT Flush(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; HRESULT COutVolumeStream::Flush() @@ -107,7 +106,7 @@ { _file.UnPackSize = _curPos; _file.FileCRC = _crc.GetDigest(); - RINOK(WriteVolumeHeader(_archive, _file, _options)); + RINOK(WriteVolumeHeader(_archive, _file, _options)) _archive.Close(); _volumeStream.Release(); _file.StartPos += _file.UnPackSize; @@ -117,7 +116,10 @@ */ /* -STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + +#include "../../../Common/Defs.h" + +Z7_COM7F_IMF(COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -126,8 +128,8 @@ if (_streamIndex >= Streams.Size()) { CSubStreamInfo subStream; - RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); - RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)) + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)) subStream.Pos = 0; Streams.Add(subStream); continue; @@ -142,15 +144,15 @@ if (_offsetPos != subStream.Pos) { CMyComPtr outStream; - RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)) + RINOK(outStream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) subStream.Pos = _offsetPos; } - UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + const UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); UInt32 realProcessed; - RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)) + data = (const void *)((const Byte *)data + realProcessed); size -= realProcessed; subStream.Pos += realProcessed; _offsetPos += realProcessed; @@ -170,7 +172,7 @@ return S_OK; } -STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -181,11 +183,11 @@ } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _absPos = offset; + _absPos = (UInt64)offset; _offsetPos = _absPos; _streamIndex = 0; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } */ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/MultiStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/MultiStream.h 2014-12-31 13:40:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/MultiStream.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,20 +1,21 @@ // MultiStream.h -#ifndef __MULTI_STREAM_H -#define __MULTI_STREAM_H +#ifndef ZIP7_INC_MULTI_STREAM_H +#define ZIP7_INC_MULTI_STREAM_H #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" #include "../../IStream.h" +#include "../../Archive/IArchive.h" -class CMultiStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CMultiStream +) + + unsigned _streamIndex; UInt64 _pos; UInt64 _totalLength; - unsigned _streamIndex; public: @@ -24,12 +25,12 @@ UInt64 Size; UInt64 GlobalOffset; UInt64 LocalPos; - CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {} }; - + + CMyComPtr updateCallbackFile; CObjectVector Streams; - + HRESULT Init() { UInt64 total = 0; @@ -37,26 +38,27 @@ { CSubStreamInfo &s = Streams[i]; s.GlobalOffset = total; - total += Streams[i].Size; - RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos)); + total += s.Size; + s.LocalPos = 0; + { + // it was already set to start + // RINOK(InStream_GetPos(s.Stream, s.LocalPos)); + } } _totalLength = total; _pos = 0; _streamIndex = 0; return S_OK; } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; /* -class COutMultiStream: - public IOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + COutMultiStream, + IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + unsigned _streamIndex; // required stream UInt64 _offsetPos; // offset from start of _streamIndex index UInt64 _absPos; @@ -78,11 +80,6 @@ _absPos = 0; _length = 0; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; */ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 2009-03-14 10:28:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -4,7 +4,7 @@ #include "OutStreamWithCRC.h" -STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -12,7 +12,7 @@ if (_calculate) _crc = CrcUpdate(_crc, data, size); _size += size; - if (processedSize != NULL) + if (processedSize) *processedSize = size; return result; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.h 2012-02-12 06:06:54.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithCRC.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // OutStreamWithCRC.h -#ifndef __OUT_STREAM_WITH_CRC_H -#define __OUT_STREAM_WITH_CRC_H +#ifndef ZIP7_INC_OUT_STREAM_WITH_CRC_H +#define ZIP7_INC_OUT_STREAM_WITH_CRC_H #include "../../../../C/7zCrc.h" @@ -9,17 +9,15 @@ #include "../../IStream.h" -class COutStreamWithCRC: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithCRC + , ISequentialOutStream +) CMyComPtr _stream; UInt64 _size; UInt32 _crc; bool _calculate; public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(bool calculate = true) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp 2019-08-29 11:00:55.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp 2023-12-14 13:00:00.000000000 +0000 @@ -4,7 +4,7 @@ #include "OutStreamWithSha1.h" -STDMETHODIMP COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -16,3 +16,14 @@ *processedSize = size; return result; } + +Z7_COM7F_IMF(CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + Sha1_Update(Sha(), (const Byte *)data, realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + return result; +} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.h 2021-01-26 11:47:10.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/OutStreamWithSha1.h 2023-12-14 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // OutStreamWithSha1.h -#ifndef __OUT_STREAM_WITH_SHA1_H -#define __OUT_STREAM_WITH_SHA1_H +#ifndef ZIP7_INC_OUT_STREAM_WITH_SHA1_H +#define ZIP7_INC_OUT_STREAM_WITH_SHA1_H #include "../../../../C/Sha1.h" @@ -10,34 +10,52 @@ #include "../../IStream.h" -class COutStreamWithSha1: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSha1 + , ISequentialOutStream +) + bool _calculate; CMyComPtr _stream; + CAlignedBuffer1 _sha; UInt64 _size; - // CSha1 _sha; - bool _calculate; - CAlignedBuffer _sha; CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } public: - MY_UNKNOWN_IMP - COutStreamWithSha1(): _sha(sizeof(CSha1)) {} - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(bool calculate = true) { - _size = 0; _calculate = calculate; + _size = 0; Sha1_Init(Sha()); } void InitSha1() { Sha1_Init(Sha()); } UInt64 GetSize() const { return _size; } void Final(Byte *digest) { Sha1_Final(Sha(), digest); } }; + + +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithSha1 + , ISequentialInStream +) + CMyComPtr _stream; + CAlignedBuffer1 _sha; + UInt64 _size; + + CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } +public: + CInStreamWithSha1(): _sha(sizeof(CSha1)) {} + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + Sha1_Init(Sha()); + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + void Final(Byte *digest) { Sha1_Final(Sha(), digest); } +}; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ParseProperties.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ParseProperties.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/ParseProperties.h 2011-02-06 08:34:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/ParseProperties.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ // ParseProperties.h -#ifndef __PARSE_PROPERTIES_H -#define __PARSE_PROPERTIES_H +#ifndef ZIP7_INC_PARSE_PROPERTIES_H +#define ZIP7_INC_PARSE_PROPERTIES_H #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Common/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Common/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/CpioHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CpioHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/CpioHandler.cpp 2022-02-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CpioHandler.cpp 2025-06-21 07:00:00.000000000 +0000 @@ -30,8 +30,6 @@ static const Byte kMagicBin0 = 0xC7; static const Byte kMagicBin1 = 0x71; -// #define MAGIC_ASCII { '0', '7', '0', '7', '0' } - static const Byte kMagicHex = '1'; // New ASCII Format static const Byte kMagicHexCrc = '2'; // New CRC Format static const Byte kMagicOct = '7'; // Portable ASCII Format @@ -44,41 +42,6 @@ static const unsigned k_RecordSize_Max = k_HexRecord_Size; - /* - struct CBinRecord - { - unsigned short c_magic; - short c_dev; - unsigned short c_ino; - unsigned short c_mode; - unsigned short c_uid; - unsigned short c_gid; - unsigned short c_nlink; - short c_rdev; - unsigned short c_mtimes[2]; - unsigned short c_namesize; - unsigned short c_filesizes[2]; - }; - - struct CHexRecord - { - char Magic[6]; - char inode[8]; - char Mode[8]; - char UID[8]; - char GID[8]; - char nlink[8]; - char mtime[8]; - char Size[8]; // must be 0 for FIFOs and directories - char DevMajor[8]; - char DevMinor[8]; - char RDevMajor[8]; //only valid for chr and blk special files - char RDevMinor[8]; //only valid for chr and blk special files - char NameSize[8]; // count includes terminating NUL in pathname - char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file - }; -*/ - enum EType { k_Type_BinLe, @@ -99,114 +62,163 @@ struct CItem { - AString Name; UInt32 inode; + unsigned MainIndex_ForInode; UInt32 Mode; - UInt32 UID; - UInt32 GID; - UInt64 Size; UInt32 MTime; - - UInt32 NumLinks; UInt32 DevMajor; UInt32 DevMinor; + UInt64 Size; + AString Name; + UInt32 NumLinks; + UInt32 UID; + UInt32 GID; UInt32 RDevMajor; UInt32 RDevMinor; UInt32 ChkSum; - UInt32 Align; + UInt32 AlignMask; EType Type; UInt32 HeaderSize; UInt64 HeaderPos; + CByteBuffer Data; // for symlink + + + UInt32 GetAlignedSize(UInt32 size) const + { + return (size + AlignMask) & ~(UInt32)AlignMask; + } + + UInt64 GetPackSize() const + { + const UInt64 alignMask64 = AlignMask; + return (Size + alignMask64) & ~(UInt64)alignMask64; + } + + bool IsSame_inode_Dev(const CItem &item) const + { + return inode == item.inode + && DevMajor == item.DevMajor + && DevMinor == item.DevMinor; + } + bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; } bool IsCrcFormat() const { return Type == k_Type_HexCrc; } bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } + bool Is_SymLink() const { return MY_LIN_S_ISLNK(Mode); } bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; } UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } }; + enum EErrorType { k_ErrorType_OK, + k_ErrorType_BadSignature, k_ErrorType_Corrupted, k_ErrorType_UnexpectedEnd }; + struct CInArchive { + EErrorType errorType; ISequentialInStream *Stream; UInt64 Processed; + CItem item; HRESULT Read(void *data, size_t *size); - HRESULT GetNextItem(CItem &item, EErrorType &errorType); + HRESULT GetNextItem(); }; HRESULT CInArchive::Read(void *data, size_t *size) { - HRESULT res = ReadStream(Stream, data, size); + const HRESULT res = ReadStream(Stream, data, size); Processed += *size; return res; } -static bool ReadHex(const Byte *p, UInt32 &resVal) + +static bool CheckOctRecord(const Byte *p) +{ + for (unsigned i = 6; i < k_OctRecord_Size; i++) + { + const unsigned c = (unsigned)p[i] - '0'; + if (c > 7) + return false; + } + return true; +} + +static bool CheckHexRecord(const Byte *p) +{ + for (unsigned i = 6; i < k_HexRecord_Size; i++) + { + unsigned c = p[i]; + c -= '0'; + if (c > 9) + { + c -= 'A' - '0'; + c &= ~0x20u; + if (c > 5) + return false; + } + } + return true; +} + +static UInt32 ReadHex(const Byte *p) { char sz[16]; memcpy(sz, p, 8); sz[8] = 0; const char *end; - resVal = ConvertHexStringToUInt32(sz, &end); - return (unsigned)(end - sz) == 8; + return ConvertHexStringToUInt32(sz, &end); } -static bool ReadOct6(const Byte *p, UInt32 &resVal) +static UInt32 ReadOct6(const Byte *p) { char sz[16]; memcpy(sz, p, 6); sz[6] = 0; const char *end; - resVal = ConvertOctStringToUInt32(sz, &end); - return (unsigned)(end - sz) == 6; + return ConvertOctStringToUInt32(sz, &end); } -static bool ReadOct11(const Byte *p, UInt64 &resVal) +static UInt64 ReadOct11(const Byte *p) { char sz[16]; memcpy(sz, p, 11); sz[11] = 0; const char *end; - resVal = ConvertOctStringToUInt64(sz, &end); - return (unsigned)(end - sz) == 11; + return ConvertOctStringToUInt64(sz, &end); } -#define READ_HEX(y) { if (!ReadHex(p2, y)) return S_OK; p2 += 8; } -#define READ_OCT_6(y) { if (!ReadOct6(p2, y)) return S_OK; p2 += 6; } -#define READ_OCT_11(y) { if (!ReadOct11(p2, y)) return S_OK; p2 += 11; } - -static UInt32 GetAlignedSize(UInt32 size, UInt32 align) -{ - while ((size & (align - 1)) != 0) - size++; - return size; -} - -static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); } -static UInt32 Get32(const Byte *p, bool be) { return ((UInt32)Get16(p, be) << 16) + Get16(p + 2, be); } - -#define G16(offs, v) v = Get16(p + (offs), be) -#define G32(offs, v) v = Get32(p + (offs), be) +#define READ_HEX( y, dest) dest = ReadHex (p + 6 + (y) * 8); +#define READ_OCT_6( y, dest) dest = ReadOct6 (p + 6 + (y)); +#define READ_OCT_11( y, dest) dest = ReadOct11(p + 6 + (y)); + +#define Get32spec(p) (((UInt32)GetUi16(p) << 16) + GetUi16(p + 2)) +#define G16(offs, v) v = GetUi16(p + (offs)) +#define G32(offs, v) v = Get32spec(p + (offs)) static const unsigned kNameSizeMax = 1 << 12; + API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size) { if (size < k_BinRecord_Size) return k_IsArc_Res_NEED_MORE; + UInt32 namePos; UInt32 nameSize; - UInt32 numLinks; + UInt32 mode; + // UInt32 rDevMinor; + UInt32 rDevMajor = 0; + if (p[0] == '0') { if (p[1] != '7' || @@ -214,94 +226,123 @@ p[3] != '7' || p[4] != '0') return k_IsArc_Res_NO; - if (p[5] == '7') + if (p[5] == kMagicOct) { if (size < k_OctRecord_Size) return k_IsArc_Res_NEED_MORE; - for (unsigned i = 6; i < k_OctRecord_Size; i++) - { - char c = p[i]; - if (c < '0' || c > '7') - return k_IsArc_Res_NO; - } - ReadOct6(p + 6 * 6, numLinks); - ReadOct6(p + 8 * 6 + 11, nameSize); + if (!CheckOctRecord(p)) + return k_IsArc_Res_NO; + READ_OCT_6 (2 * 6, mode) + // READ_OCT_6 (6 * 6, rDevMinor) + READ_OCT_6 (7 * 6 + 11, nameSize) + namePos = k_OctRecord_Size; } - else if (p[5] == '1' || p[5] == '2') + else if (p[5] == kMagicHex || p[5] == kMagicHexCrc) { if (size < k_HexRecord_Size) return k_IsArc_Res_NEED_MORE; - for (unsigned i = 6; i < k_HexRecord_Size; i++) - { - char c = p[i]; - if ((c < '0' || c > '9') && - (c < 'A' || c > 'F') && - (c < 'a' || c > 'f')) - return k_IsArc_Res_NO; - } - ReadHex(p + 6 + 4 * 8, numLinks); - ReadHex(p + 6 + 11 * 8, nameSize); + if (!CheckHexRecord(p)) + return k_IsArc_Res_NO; + READ_HEX (1, mode) + READ_HEX (9, rDevMajor) + // READ_HEX (10, rDevMinor) + READ_HEX (11, nameSize) + namePos = k_HexRecord_Size; } else return k_IsArc_Res_NO; } else { - UInt32 rDevMinor; if (p[0] == kMagicBin0 && p[1] == kMagicBin1) { - numLinks = GetUi16(p + 12); - rDevMinor = GetUi16(p + 14); + mode = GetUi16(p + 6); + // rDevMinor = GetUi16(p + 14); nameSize = GetUi16(p + 20); } else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) { - numLinks = GetBe16(p + 12); - rDevMinor = GetBe16(p + 14); + mode = GetBe16(p + 6); + // rDevMinor = GetBe16(p + 14); nameSize = GetBe16(p + 20); } else return k_IsArc_Res_NO; + namePos = k_BinRecord_Size; + } - if (rDevMinor != 0) - return k_IsArc_Res_NO; - if (nameSize > (1 << 8)) + if (mode >= (1 << 16)) + return k_IsArc_Res_NO; + + /* v23.02: we have disabled rDevMinor check because real file + from Apple contains rDevMinor==255 by some unknown reason */ + if (rDevMajor != 0 + // || rDevMinor != 0 + ) + { + if (!MY_LIN_S_ISCHR(mode) && + !MY_LIN_S_ISBLK(mode)) return k_IsArc_Res_NO; } - // 20.03: some cpio files have (numLinks == 0). - // if (numLinks == 0) return k_IsArc_Res_NO; - if (numLinks >= (1 << 10)) - return k_IsArc_Res_NO; + + // nameSize must include the null byte if (nameSize == 0 || nameSize > kNameSizeMax) return k_IsArc_Res_NO; + { + unsigned lim = namePos + nameSize - 1; + if (lim >= size) + lim = (unsigned)size; + else if (p[lim] != 0) + return k_IsArc_Res_NO; + for (unsigned i = namePos; i < lim; i++) + if (p[i] == 0) + return k_IsArc_Res_NO; + } + return k_IsArc_Res_YES; } } + #define READ_STREAM(_dest_, _size_) \ { size_t processed = (_size_); RINOK(Read(_dest_, &processed)); \ if (processed != (_size_)) { errorType = k_ErrorType_UnexpectedEnd; return S_OK; } } -HRESULT CInArchive::GetNextItem(CItem &item, EErrorType &errorType) +HRESULT CInArchive::GetNextItem() { - errorType = k_ErrorType_Corrupted; + errorType = k_ErrorType_BadSignature; Byte p[k_RecordSize_Max]; READ_STREAM(p, k_BinRecord_Size) UInt32 nameSize; + UInt32 namePos; + + /* we try to reduce probability of false detection, + so we check some fields for unuxpected values */ if (p[0] != '0') { - bool be; - if (p[0] == kMagicBin0 && p[1] == kMagicBin1) { be = false; item.Type = k_Type_BinLe; } - else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) { be = true; item.Type = k_Type_BinBe; } - else return S_FALSE; + if (p[0] == kMagicBin0 && p[1] == kMagicBin1) { item.Type = k_Type_BinLe; } + else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) + { + for (unsigned i = 2; i < k_BinRecord_Size; i += 2) + { + const Byte b = p[i]; + p[i] = p[i + 1]; + p[i + 1] = b; + } + item.Type = k_Type_BinBe; + } + else + return S_OK; - item.Align = 2; + errorType = k_ErrorType_Corrupted; + + item.AlignMask = 2 - 1; item.DevMajor = 0; - item.RDevMajor =0; + item.RDevMajor = 0; item.ChkSum = 0; G16(2, item.DevMinor); @@ -315,13 +356,7 @@ G16(20, nameSize); G32(22, item.Size); - /* - if (item.RDevMinor != 0) - return S_FALSE; - */ - - item.HeaderSize = GetAlignedSize(nameSize + k_BinRecord_Size, item.Align); - nameSize = item.HeaderSize - k_BinRecord_Size; + namePos = k_BinRecord_Size; } else { @@ -329,104 +364,142 @@ p[2] != '0' || p[3] != '7' || p[4] != '0') - return S_FALSE; + return S_OK; if (p[5] == kMagicOct) { + errorType = k_ErrorType_Corrupted; + item.Type = k_Type_Oct; READ_STREAM(p + k_BinRecord_Size, k_OctRecord_Size - k_BinRecord_Size) - item.Align = 1; + item.AlignMask = 1 - 1; item.DevMajor = 0; item.RDevMajor = 0; + item.ChkSum = 0; + + if (!CheckOctRecord(p)) + return S_OK; - const Byte *p2 = p + 6; - READ_OCT_6(item.DevMinor); - READ_OCT_6(item.inode); - READ_OCT_6(item.Mode); - READ_OCT_6(item.UID); - READ_OCT_6(item.GID); - READ_OCT_6(item.NumLinks); - READ_OCT_6(item.RDevMinor); + READ_OCT_6 (0, item.DevMinor) + READ_OCT_6 (1 * 6, item.inode) + READ_OCT_6 (2 * 6, item.Mode) + READ_OCT_6 (3 * 6, item.UID) + READ_OCT_6 (4 * 6, item.GID) + READ_OCT_6 (5 * 6, item.NumLinks) + READ_OCT_6 (6 * 6, item.RDevMinor) { UInt64 mTime64; - READ_OCT_11(mTime64); + READ_OCT_11 (7 * 6, mTime64) item.MTime = 0; - if (mTime64 < (UInt32)(Int32)-1) + if (mTime64 <= (UInt32)(Int32)-1) item.MTime = (UInt32)mTime64; } - READ_OCT_6(nameSize); - READ_OCT_11(item.Size); // ????? - item.HeaderSize = GetAlignedSize(nameSize + k_OctRecord_Size, item.Align); - nameSize = item.HeaderSize - k_OctRecord_Size; + READ_OCT_6 (7 * 6 + 11, nameSize) + READ_OCT_11 (8 * 6 + 11, item.Size) // ????? + + namePos = k_OctRecord_Size; } else { - if (p[5] == kMagicHex) - item.Type = k_Type_Hex; - else if (p[5] == kMagicHexCrc) - item.Type = k_Type_HexCrc; - else - return S_FALSE; + if (p[5] == kMagicHex) item.Type = k_Type_Hex; + else if (p[5] == kMagicHexCrc) item.Type = k_Type_HexCrc; + else return S_OK; + + errorType = k_ErrorType_Corrupted; READ_STREAM(p + k_BinRecord_Size, k_HexRecord_Size - k_BinRecord_Size) - item.Align = 4; + if (!CheckHexRecord(p)) + return S_OK; + + item.AlignMask = 4 - 1; + READ_HEX (0, item.inode) + READ_HEX (1, item.Mode) + READ_HEX (2, item.UID) + READ_HEX (3, item.GID) + READ_HEX (4, item.NumLinks) + READ_HEX (5, item.MTime) + READ_HEX (6, item.Size) + READ_HEX (7, item.DevMajor) + READ_HEX (8, item.DevMinor) + READ_HEX (9, item.RDevMajor) + READ_HEX (10, item.RDevMinor) + READ_HEX (11, nameSize) + READ_HEX (12, item.ChkSum) - const Byte *p2 = p + 6; - READ_HEX(item.inode); - READ_HEX(item.Mode); - READ_HEX(item.UID); - READ_HEX(item.GID); - READ_HEX(item.NumLinks); - READ_HEX(item.MTime); - { - UInt32 size32; - READ_HEX(size32); - item.Size = size32; - } - READ_HEX(item.DevMajor); - READ_HEX(item.DevMinor); - READ_HEX(item.RDevMajor); - READ_HEX(item.RDevMinor); - READ_HEX(nameSize); - READ_HEX(item.ChkSum); - if (nameSize >= kNameSizeMax) + if (item.Type == k_Type_Hex && item.ChkSum != 0) return S_OK; - item.HeaderSize = GetAlignedSize(nameSize + k_HexRecord_Size, item.Align); - nameSize = item.HeaderSize - k_HexRecord_Size; + + namePos = k_HexRecord_Size; } } - if (nameSize > kNameSizeMax) - return S_FALSE; - if (nameSize == 0 || nameSize >= kNameSizeMax) + + if (item.Mode >= (1 << 16)) return S_OK; - char *s = item.Name.GetBuf(nameSize); - size_t processedSize = nameSize; - RINOK(Read(s, &processedSize)); - item.Name.ReleaseBuf_CalcLen(nameSize); - if (processedSize != nameSize) + + /* v23.02: we have disabled rDevMinor check because real file + from Apple contains rDevMinor==255 by some unknown reason + cpio 2.13 and older versions: it copies stat::st_rdev to archive. + and stat::st_rdev can be non-zero for some old linux/filesystems cases for regular files. + cpio 2.14 (2023) copies st_rdev to archive only if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) + v25.00: we have disabled RDevMajor check here to support some rare case created by cpio 2.13- with old linux. + But we still keep full check in IsArc_Cpio() to reduce false cpio detection cases. + */ +#if 0 // 0 : to disable check to support some old linux cpio archives. + if (item.RDevMajor != 0 + // || item.RDevMinor != 0 + ) { + if (!MY_LIN_S_ISCHR(item.Mode) && + !MY_LIN_S_ISBLK(item.Mode)) + return S_OK; + } +#endif + + // Size must be 0 for FIFOs and directories + if (item.IsDir() || MY_LIN_S_ISFIFO(item.Mode)) + if (item.Size != 0) + return S_OK; + + // nameSize must include the null byte + if (nameSize == 0 || nameSize > kNameSizeMax) + return S_OK; + item.HeaderSize = item.GetAlignedSize(namePos + nameSize); + const UInt32 rem = item.HeaderSize - namePos; + char *s = item.Name.GetBuf(rem); + size_t processedSize = rem; + RINOK(Read(s, &processedSize)) + if (processedSize != rem) + { + item.Name.ReleaseBuf_SetEnd(0); errorType = k_ErrorType_UnexpectedEnd; return S_OK; } + bool pad_error = false; + for (size_t i = nameSize; i < processedSize; i++) + if (s[i] != 0) + pad_error = true; + item.Name.ReleaseBuf_CalcLen(nameSize); + if (item.Name.Len() + 1 != nameSize || pad_error) + return S_OK; errorType = k_ErrorType_OK; return S_OK; } -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CObjectVector _items; CMyComPtr _stream; UInt64 _phySize; - EType _Type; + EType _type; EErrorType _error; bool _isArc; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + bool _moreThanOneHardLinks_Error; + bool _numLinks_Error; + bool _pad_Error; + bool _symLink_Error; }; static const Byte kArcProps[] = @@ -439,22 +512,35 @@ kpidPath, kpidIsDir, kpidSize, + kpidPackSize, kpidMTime, kpidPosixAttrib, - kpidLinks + kpidLinks, + kpidINode, + kpidUserId, + kpidGroupId, + kpidDevMajor, + kpidDevMinor, + kpidDeviceMajor, + kpidDeviceMinor, + kpidChecksum, + kpidSymLink, + kpidStreamId, // for debug + kpidOffset }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; switch (propID) { - case kpidSubType: prop = k_Types[(unsigned)_Type]; break; + case kpidSubType: prop = k_Types[(unsigned)_type]; break; case kpidPhySize: prop = _phySize; break; + case kpidINode: prop = true; break; case kpidErrorFlags: { UInt32 v = 0; @@ -463,14 +549,28 @@ switch (_error) { case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; - case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; + case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; case k_ErrorType_OK: - default: + case k_ErrorType_BadSignature: + // default: break; } prop = v; break; } + case kpidWarningFlags: + { + UInt32 v = 0; + if (_moreThanOneHardLinks_Error) + v |= kpv_ErrorFlags_UnsupportedFeature; // kpv_ErrorFlags_HeadersError + if (_numLinks_Error + || _pad_Error + || _symLink_Error) + v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } } prop.Detach(value); return S_OK; @@ -478,22 +578,43 @@ } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +static int CompareItems(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + const unsigned index1 = *p1; + const unsigned index2 = *p2; + const CItem &i1 = items[index1]; + const CItem &i2 = items[index2]; + if (i1.DevMajor < i2.DevMajor) return -1; + if (i1.DevMajor > i2.DevMajor) return 1; + if (i1.DevMinor < i2.DevMinor) return -1; + if (i1.DevMinor > i2.DevMinor) return 1; + if (i1.inode < i2.inode) return -1; + if (i1.inode > i2.inode) return 1; + if (i1.IsDir()) + { + if (!i2.IsDir()) + return -1; + } + else if (i2.IsDir()) + return 1; + return MyCompare(index1, index2); +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { Close(); - UInt64 endPos = 0; - - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(stream, endPos)) if (callback) { - RINOK(callback->SetTotal(NULL, &endPos)); + RINOK(callback->SetTotal(NULL, &endPos)) } - _items.Clear(); CInArchive arc; arc.Stream = stream; @@ -501,70 +622,98 @@ for (;;) { - CItem item; + CItem &item = arc.item; item.HeaderPos = arc.Processed; - HRESULT result = arc.GetNextItem(item, _error); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; + + RINOK(arc.GetNextItem()) + + _error = arc.errorType; + if (_error != k_ErrorType_OK) { - if (_error == k_ErrorType_Corrupted) + if (_error == k_ErrorType_BadSignature || + _error == k_ErrorType_Corrupted) arc.Processed = item.HeaderPos; break; } + if (_items.IsEmpty()) - _Type = item.Type; + _type = item.Type; else if (_items.Back().Type != item.Type) { _error = k_ErrorType_Corrupted; arc.Processed = item.HeaderPos; break; } + if (item.IsTrailer()) break; + item.MainIndex_ForInode = _items.Size(); _items.Add(item); + const UInt64 dataSize = item.GetPackSize(); + arc.Processed += dataSize; + if (arc.Processed > endPos) { - // archive.SkipDataRecords(item.Size, item.Align); - UInt64 dataSize = item.Size; - UInt32 align = item.Align; - while ((dataSize & (align - 1)) != 0) - dataSize++; - - // _error = k_ErrorType_UnexpectedEnd; break; - - arc.Processed += dataSize; - if (arc.Processed > endPos) + _error = k_ErrorType_UnexpectedEnd; + break; + } + + if (item.Is_SymLink() && dataSize <= (1 << 12) && item.Size != 0) + { + size_t cur = (size_t)dataSize; + CByteBuffer buf; + buf.Alloc(cur); + RINOK(ReadStream(stream, buf, &cur)) + if (cur != dataSize) { _error = k_ErrorType_UnexpectedEnd; break; } - - UInt64 newPostion; - RINOK(stream->Seek(dataSize, STREAM_SEEK_CUR, &newPostion)); - if (arc.Processed != newPostion) + size_t i; + + for (i = (size_t)item.Size; i < dataSize; i++) + if (buf[i] != 0) + break; + if (i != dataSize) + _pad_Error = true; + + for (i = 0; i < (size_t)item.Size; i++) + if (buf[i] == 0) + break; + if (i != (size_t)item.Size) + _symLink_Error = true; + else + _items.Back().Data.CopyFrom(buf, (size_t)item.Size); + } + else if (dataSize != 0) + { + UInt64 newPos; + RINOK(stream->Seek((Int64)dataSize, STREAM_SEEK_CUR, &newPos)) + if (arc.Processed != newPos) return E_FAIL; } - if (callback && (_items.Size() & 0xFF) == 0) + if (callback && (_items.Size() & 0xFFF) == 0) { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &item.HeaderPos)); + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &item.HeaderPos)) } } + _phySize = arc.Processed; + } + + { if (_error != k_ErrorType_OK) { + // we try to reduce probability of false detection if (_items.Size() == 0) return S_FALSE; + // bin file uses small signature. So we do additional check for single item case. if (_items.Size() == 1 && _items[0].IsBin()) - { - // probably it's false detected archive. So we return error return S_FALSE; - } } else { @@ -574,16 +723,15 @@ const unsigned kTailSize_MAX = 1 << 9; Byte buf[kTailSize_MAX]; - unsigned pos = (unsigned)arc.Processed & (kTailSize_MAX - 1); + unsigned pos = (unsigned)_phySize & (kTailSize_MAX - 1); if (pos != 0) // use this check to support 512 bytes alignment only for (;;) { - unsigned rem = kTailSize_MAX - pos; + const unsigned rem = kTailSize_MAX - pos; size_t processed = rem; - RINOK(ReadStream(stream, buf + pos, &processed)); + RINOK(ReadStream(stream, buf + pos, &processed)) if (processed != rem) break; - for (; pos < kTailSize_MAX && buf[pos] == 0; pos++) {} if (pos != kTailSize_MAX) @@ -596,32 +744,134 @@ break; } } + } + + { + /* there was such cpio archive example with hard links: + { + all hard links (same dev/inode) are stored in neighboring items, and + (item.Size == 0) for non last hard link items + (item.Size != 0) for last hard link item + } + but here we sort items by (dev/inode) to support cases + where hard links (same dev/inode) are not stored in neighboring items. + + // note: some cpio files have (numLinks == 0) ?? + */ + + CUIntVector indices; + { + const unsigned numItems = _items.Size(); + indices.ClearAndSetSize(numItems); + if (numItems != 0) + { + unsigned *vals = &indices[0]; + for (unsigned i = 0; i < numItems; i++) + vals[i] = i; + indices.Sort(CompareItems, (void *)&_items); + } + } + + /* Note: if cpio archive (maybe incorrect) contains + more then one non empty streams with identical inode number, + we want to extract all such data streams too. + + So we place items with identical inode to groups: + all items in group will have same MainIndex_ForInode, + that is index of last item in group with (Size != 0). + Another (non last) items in group have (Size == 0). + If there are another hard links with same inode number + after (Size != 0) item, we place them to another next group(s). + + Check it: maybe we should use single group for items + with identical inode instead, and ignore some extra data streams ? + */ - _isArc = true; - _stream = stream; + for (unsigned i = 0; i < indices.Size();) + { + unsigned k; + { + const CItem &item_Base = _items[indices[i]]; + + if (item_Base.IsDir()) + { + i++; + continue; + } + + if (i != 0) + { + const CItem &item_Prev = _items[indices[i - 1]]; + if (!item_Prev.IsDir()) + if (item_Base.IsSame_inode_Dev(item_Prev)) + _moreThanOneHardLinks_Error = true; + } + + if (item_Base.Size != 0) + { + if (item_Base.NumLinks != 1) + _numLinks_Error = true; + i++; + continue; + } + + for (k = i + 1; k < indices.Size();) + { + const CItem &item = _items[indices[k]]; + if (item.IsDir()) + break; + if (!item.IsSame_inode_Dev(item_Base)) + break; + k++; + if (item.Size != 0) + break; + } + } + + const unsigned numLinks = k - i; + for (;;) + { + CItem &item = _items[indices[i]]; + if (item.NumLinks != numLinks) + _numLinks_Error = true; + if (++i == k) + break; + // if (item.Size == 0) + item.MainIndex_ForInode = indices[k - 1]; + } + } } + + _isArc = true; + _stream = stream; + return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() + +Z7_COM7F_IMF(CHandler::Close()) { _items.Clear(); _stream.Release(); _phySize = 0; - _Type = k_Type_BinLe; + _type = k_Type_BinLe; _isArc = false; + _moreThanOneHardLinks_Error = false; + _numLinks_Error = false; + _pad_Error = false; + _symLink_Error = false; _error = k_ErrorType_OK; return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -631,24 +881,25 @@ { case kpidPath: { - UString res; - bool needConvert = true; - #ifdef _WIN32 - // if ( - ConvertUTF8ToUnicode(item.Name, res); - // ) - needConvert = false; - #endif - if (needConvert) - res = MultiByteToUnicodeString(item.Name, CP_OEMCP); - prop = NItemName::GetOsPath(res); +#ifdef _WIN32 + UString u; + ConvertUTF8ToUnicode(item.Name, u); +#else + const UString u = MultiByteToUnicodeString(item.Name, CP_OEMCP); +#endif + prop = NItemName::GetOsPath(u); break; } case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: + prop = (UInt64)_items[item.MainIndex_ForInode].Size; + break; + case kpidPackSize: - prop = (UInt64)item.Size; + prop = (UInt64)item.GetPackSize(); break; + case kpidMTime: { if (item.MTime != 0) @@ -656,64 +907,111 @@ break; } case kpidPosixAttrib: prop = item.Mode; break; + case kpidINode: prop = item.inode; break; + case kpidStreamId: + if (!item.IsDir()) + prop = (UInt32)item.MainIndex_ForInode; + break; + case kpidDevMajor: prop = (UInt32)item.DevMajor; break; + case kpidDevMinor: prop = (UInt32)item.DevMinor; break; + + case kpidUserId: prop = item.UID; break; + case kpidGroupId: prop = item.GID; break; + + case kpidSymLink: + if (item.Is_SymLink() && item.Data.Size() != 0) + { + AString s; + s.SetFrom_CalcLen((const char *)(const void *)(const Byte *)item.Data, (unsigned)item.Data.Size()); + if (s.Len() == item.Data.Size()) + { +#ifdef _WIN32 + UString u; + ConvertUTF8ToUnicode(item.Name, u); +#else + const UString u = MultiByteToUnicodeString(s, CP_OEMCP); +#endif + prop = u; + } + } + break; + case kpidLinks: prop = item.NumLinks; break; - /* - case kpidinode: prop = item.inode; break; - case kpidiChkSum: prop = item.ChkSum; break; - */ + case kpidDeviceMajor: + // if (item.RDevMajor != 0) + prop = (UInt32)item.RDevMajor; + break; + case kpidDeviceMinor: + // if (item.RDevMinor != 0) + prop = (UInt32)item.RDevMinor; + break; + case kpidChecksum: + if (item.IsCrcFormat()) + prop = item.ChkSum; + break; + case kpidOffset: prop = item.GetDataPosition(); break; } prop.Detach(value); return S_OK; COM_TRY_END } -class COutStreamWithSum: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSum + , ISequentialOutStream +) CMyComPtr _stream; - UInt64 _size; - UInt32 _crc; + UInt32 _checksum; bool _calculate; public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } - void Init(bool calculate = true) + void Init(bool calculate) { - _size = 0; _calculate = calculate; - _crc = 0; + _checksum = 0; } - void EnableCalc(bool calculate) { _calculate = calculate; } - void InitCRC() { _crc = 0; } - UInt64 GetSize() const { return _size; } - UInt32 GetCRC() const { return _crc; } + UInt32 GetChecksum() const { return _checksum; } }; -STDMETHODIMP COutStreamWithSum::Write(const void *data, UInt32 size, UInt32 *processedSize) + +Z7_COM7F_IMF(COutStreamWithSum::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) result = _stream->Write(data, size, &size); + if (processedSize) + *processedSize = size; if (_calculate) { - UInt32 crc = 0; - for (UInt32 i = 0; i < size; i++) - crc += (UInt32)(((const Byte *)data)[i]); - _crc += crc; + const Byte *p = (const Byte *)data; + const Byte *lim = p + size; + UInt32 sum = _checksum; + if (size >= 4) + { + lim -= 4 - 1; + do + { + sum += p[0] + p[1] + p[2] + p[3]; + p += 4; + } + while (p < lim); + lim += 4 - 1; + } + if (p != lim) { sum += *p++; + if (p != lim) { sum += *p++; + if (p != lim) { sum += *p++; }}} + _checksum = sum; } - if (processedSize) - *processedSize = size; return result; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -721,71 +1019,78 @@ UInt64 totalSize = 0; UInt32 i; for (i = 0; i < numItems; i++) - totalSize += _items[allFilesMode ? i : indices[i]].Size; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + { + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; + totalSize += item.Size; + } + RINOK(extractCallback->SetTotal(totalSize)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + CMyComPtr2_Create outStreamSum; - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - COutStreamWithSum *outStreamSumSpec = new COutStreamWithSum; - CMyComPtr outStreamSum(outStreamSumSpec); + UInt64 total_PackSize = 0; + UInt64 total_UnpackSize = 0; - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? + lps->InSize = total_PackSize; + lps->OutSize = total_UnpackSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - currentTotalSize += item.Size; - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - if (!testMode && !outStream) - continue; - outStreamSumSpec->Init(item.IsCrcFormat()); - outStreamSumSpec->SetStream(outStream); - outStream.Release(); - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_stream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, outStreamSum, NULL, NULL, progress)); - outStreamSumSpec->ReleaseStream(); + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; + { + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + + total_PackSize += item2.GetPackSize(); + total_UnpackSize += item.Size; + + if (item2.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + if (!testMode && !outStream) + continue; + outStreamSum->Init(item.IsCrcFormat()); + outStreamSum->SetStream(outStream); + RINOK(extractCallback->PrepareOperation(askMode)) + } + RINOK(InStream_SeekSet(_stream, item.GetDataPosition())) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, outStreamSum, NULL, NULL, lps)) + outStreamSum->ReleaseStream(); Int32 res = NExtract::NOperationResult::kDataError; - if (copyCoderSpec->TotalSize == item.Size) + if (copyCoder->TotalSize == item.Size) { res = NExtract::NOperationResult::kOK; - if (item.IsCrcFormat() && item.ChkSum != outStreamSumSpec->GetCRC()) + if (item.IsCrcFormat() && item.ChkSum != outStreamSum->GetChecksum()) res = NExtract::NOperationResult::kCRCError; } - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - const CItem &item = _items[index]; + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream); COM_TRY_END } @@ -796,7 +1101,7 @@ 2, kMagicBin1, kMagicBin0 }; REGISTER_ARC_I( - "Cpio", "cpio", 0, 0xED, + "Cpio", "cpio", NULL, 0xED, k_Signature, 0, NArcInfoFlags::kMultiSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/CramfsHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CramfsHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/CramfsHandler.cpp 2016-05-14 11:47:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/CramfsHandler.cpp 2023-03-26 12:00:00.000000000 +0000 @@ -25,9 +25,8 @@ namespace NArchive { namespace NCramfs { -#define SIGNATURE { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' } - -static const Byte kSignature[] = SIGNATURE; +static const Byte kSignature[] = + { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' }; static const UInt32 kArcSizeMax = (256 + 16) << 20; static const UInt32 kNumFilesMax = (1 << 19); @@ -114,7 +113,7 @@ if (be) return (p[8] & 0xFC); else - return (p[8] & 0x3F) << 2; + return ((UInt32)p[8] & (UInt32)0x3F) << 2; } static UInt32 GetOffset(const Byte *p, bool be) @@ -145,7 +144,7 @@ bool Parse(const Byte *p) { - if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0) + if (memcmp(p + 16, kSignature, Z7_ARRAY_SIZE(kSignature)) != 0) return false; switch (GetUi32(p)) { @@ -169,11 +168,11 @@ unsigned GetMethod() const { return (unsigned)(Flags >> k_Flags_Method_Shift) & k_Flags_Method_Mask; } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CRecordVector _items; CMyComPtr _stream; Byte *_data; @@ -205,8 +204,8 @@ HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level); HRESULT Open2(IInStream *inStream); - AString GetPath(int index) const; - bool GetPackSize(int index, UInt32 &res) const; + AString GetPath(unsigned index) const; + bool GetPackSize(unsigned index, UInt32 &res) const; void Free(); UInt32 GetNumBlocks(UInt32 size) const @@ -221,11 +220,8 @@ } public: - CHandler(): _data(0) {} + CHandler(): _data(NULL) {} ~CHandler() { Free(); } - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); }; @@ -291,7 +287,7 @@ unsigned endIndex = _items.Size(); for (unsigned i = startIndex; i < endIndex; i++) { - RINOK(OpenDir(i, _items[i].Offset, level + 1)); + RINOK(OpenDir((int)i, _items[i].Offset, level + 1)) } return S_OK; } @@ -299,7 +295,7 @@ HRESULT CHandler::Open2(IInStream *inStream) { Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)) if (!_h.Parse(buf)) return S_FALSE; _method = k_Flags_Method_ZLIB; @@ -319,18 +315,18 @@ else { UInt64 size; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &size)); + RINOK(InStream_GetSize_SeekToEnd(inStream, size)) if (size > kArcSizeMax) size = kArcSizeMax; _h.Size = (UInt32)size; - RINOK(inStream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, kHeaderSize)) } _data = (Byte *)MidAlloc(_h.Size); - if (_data == 0) + if (!_data) return E_OUTOFMEMORY; memcpy(_data, buf, kHeaderSize); size_t processed = _h.Size - kHeaderSize; - RINOK(ReadStream(inStream, _data + kHeaderSize, &processed)); + RINOK(ReadStream(inStream, _data + kHeaderSize, &processed)) if (processed < kNodeSize) return S_FALSE; _size = kHeaderSize + (UInt32)processed; @@ -340,7 +336,7 @@ _errorFlags = kpv_ErrorFlags_UnexpectedEnd; else { - SetUi32(_data + 0x20, 0); + SetUi32(_data + 0x20, 0) if (CrcCalc(_data, _h.Size) != _h.Crc) { _errorFlags = kpv_ErrorFlags_HeadersError; @@ -351,7 +347,7 @@ _items.ClearAndReserve(_h.NumFiles - 1); } - RINOK(OpenDir(-1, kHeaderSize, 0)); + RINOK(OpenDir(-1, kHeaderSize, 0)) if (!_h.IsVer2()) { @@ -389,22 +385,23 @@ return S_OK; } -AString CHandler::GetPath(int index) const +AString CHandler::GetPath(unsigned index) const { unsigned len = 0; - int indexMem = index; - do + unsigned indexMem = index; + for (;;) { const CItem &item = _items[index]; - index = item.Parent; const Byte *p = _data + item.Offset; unsigned size = GetNameLen(p, _h.be); p += kNodeSize; unsigned i; for (i = 0; i < size && p[i]; i++); len += i + 1; + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; } - while (index >= 0); len--; AString path; @@ -413,7 +410,6 @@ for (;;) { const CItem &item = _items[index]; - index = item.Parent; const Byte *p = _data + item.Offset; unsigned size = GetNameLen(p, _h.be); p += kNodeSize; @@ -421,41 +417,42 @@ for (i = 0; i < size && p[i]; i++); dest -= i; memcpy(dest, p, i); - if (index < 0) + index = (unsigned)item.Parent; + if (item.Parent < 0) break; *(--dest) = CHAR_PATH_SEPARATOR; } return path; } -bool CHandler::GetPackSize(int index, UInt32 &res) const +bool CHandler::GetPackSize(unsigned index, UInt32 &res) const { res = 0; const CItem &item = _items[index]; const Byte *p = _data + item.Offset; - bool be = _h.be; - UInt32 offset = GetOffset(p, be); + const bool be = _h.be; + const UInt32 offset = GetOffset(p, be); if (offset < kHeaderSize) return false; - UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); + const UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); if (numBlocks == 0) return true; - UInt32 start = offset + numBlocks * 4; + const UInt32 start = offset + numBlocks * 4; if (start > _size) return false; - UInt32 end = Get32(_data + start - 4); + const UInt32 end = Get32(_data + start - 4); if (end < start) return false; res = end - start; return true; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)) { COM_TRY_BEGIN { Close(); - RINOK(Open2(stream)); + RINOK(Open2(stream)) _isArc = true; _stream = stream; } @@ -466,10 +463,10 @@ void CHandler::Free() { MidFree(_data); - _data = 0; + _data = NULL; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _phySize = 0; @@ -481,13 +478,13 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -523,7 +520,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -554,7 +551,7 @@ class CCramfsInStream: public CCachedInStream { - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) Z7_override; public: CHandler *Handler; }; @@ -626,16 +623,16 @@ } _inStreamSpec->Init(_data + start, inSize); _outStreamSpec->Init(dest, blockSize); - RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL)); + RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL)) return (inSize == _zlibDecoderSpec->GetInputProcessedSize() && _outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -665,20 +662,20 @@ { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) const Byte *p = _data + item.Offset; if (IsDir(p, be)) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } UInt32 curSize = GetSize(p, be); @@ -689,7 +686,7 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) UInt32 offset = GetOffset(p, be); if (offset < kHeaderSize) @@ -705,7 +702,7 @@ res = NExtract::NOperationResult::kUnsupportedMethod; else { - RINOK(hres); + RINOK(hres) { hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); if (hres == S_OK) @@ -720,14 +717,14 @@ } } } - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN @@ -778,7 +775,7 @@ } REGISTER_ARC_I( - "CramFS", "cramfs", 0, 0xD3, + "CramFS", "cramfs", NULL, 0xD3, kSignature, 16, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/DeflateProps.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DeflateProps.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/DeflateProps.h 2011-01-27 10:53:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DeflateProps.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ // DeflateProps.h -#ifndef __DEFLATE_PROPS_H -#define __DEFLATE_PROPS_H +#ifndef ZIP7_INC_DEFLATE_PROPS_H +#define ZIP7_INC_DEFLATE_PROPS_H #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/DllExports.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/DllExports.cpp 2015-03-06 10:54:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports.cpp 2023-06-15 04:00:00.000000000 +0000 @@ -2,10 +2,11 @@ #include "StdAfx.h" -#if defined(_7ZIP_LARGE_PAGES) +#if defined(Z7_LARGE_PAGES) #include "../../../C/Alloc.h" #endif +#include "../../Common/MyWindows.h" #include "../../Common/MyInitGuid.h" #include "../../Common/ComTry.h" @@ -20,22 +21,23 @@ #include "IArchive.h" +static HINSTANCE g_hInstance; #define NT_CHECK_FAIL_ACTION return FALSE; -extern "C" -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/); +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { g_hInstance = hInstance; - NT_CHECK; + NT_CHECK } return TRUE; } -DEFINE_GUID(CLSID_CArchiveHandler, +Z7_DEFINE_GUID(CLSID_CArchiveHandler, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -50,7 +52,7 @@ STDAPI SetLargePageMode() { - #if defined(_7ZIP_LARGE_PAGES) + #if defined(Z7_LARGE_PAGES) SetLargePageSize(); #endif return S_OK; @@ -64,7 +66,7 @@ return S_OK; } -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS CExternalCodecs g_ExternalCodecs; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/DllExports2.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports2.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/DllExports2.cpp 2022-04-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DllExports2.cpp 2023-03-23 18:00:00.000000000 +0000 @@ -3,10 +3,9 @@ #include "StdAfx.h" #include "../../Common/MyWindows.h" - #include "../../Common/MyInitGuid.h" -#if defined(_7ZIP_LARGE_PAGES) +#if defined(Z7_LARGE_PAGES) #include "../../../C/Alloc.h" #endif @@ -29,6 +28,7 @@ #define NT_CHECK_FAIL_ACTION return FALSE; #endif +static HINSTANCE g_hInstance; extern "C" @@ -53,7 +53,7 @@ { // OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH"); g_hInstance = (HINSTANCE)hInstance; - NT_CHECK; + NT_CHECK } /* if (dwReason == DLL_PROCESS_DETACH) @@ -80,7 +80,7 @@ #endif // _WIN32 -DEFINE_GUID(CLSID_CArchiveHandler, +Z7_DEFINE_GUID(CLSID_CArchiveHandler, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -94,7 +94,7 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { // COM_TRY_BEGIN - *outObject = 0; + *outObject = NULL; if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter) @@ -108,7 +108,7 @@ STDAPI SetLargePageMode(); STDAPI SetLargePageMode() { - #if defined(_7ZIP_LARGE_PAGES) + #if defined(Z7_LARGE_PAGES) #ifdef _WIN32 SetLargePageSize(); #endif @@ -143,7 +143,7 @@ } */ -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS CExternalCodecs g_ExternalCodecs; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/DmgHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DmgHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/DmgHandler.cpp 2022-07-15 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/DmgHandler.cpp 2025-06-16 09:00:00.000000000 +0000 @@ -2,10 +2,13 @@ #include "StdAfx.h" +#include "../../../C/Alloc.h" #include "../../../C/CpuArch.h" +#include "../../Common/AutoPtr.h" #include "../../Common/ComTry.h" #include "../../Common/IntToString.h" +#include "../../Common/MyBuffer2.h" #include "../../Common/MyXml.h" #include "../../Common/UTFConvert.h" @@ -20,32 +23,67 @@ #include "../Compress/BZip2Decoder.h" #include "../Compress/CopyCoder.h" #include "../Compress/LzfseDecoder.h" +#include "../Compress/XzDecoder.h" #include "../Compress/ZlibDecoder.h" #include "Common/OutStreamWithCRC.h" // #define DMG_SHOW_RAW -// #include -#define PRF(x) // x +// #define SHOW_DEBUG_INFO + +/* for debug only: we can use block cache also for METHOD_COPY blocks. + It can reduce the number of Stream->Read() requests. + But it can increase memory usage. + Note: METHOD_COPY blocks are not fused usually. + But if METHOD_COPY blocks is fused in some dmg example, + block size can exceed k_Chunk_Size_MAX. + So we don't use cache for METHOD_COPY block, if (block_size > k_Chunk_Size_MAX) +*/ +// for debug only: +// #define Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + +#ifdef SHOW_DEBUG_INFO +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + #define Get16(p) GetBe16(p) #define Get32(p) GetBe32(p) #define Get64(p) GetBe64(p) +#define Get32a(p) GetBe32a(p) +#define Get64a(p) GetBe64a(p) + Byte *Base64ToBin(Byte *dest, const char *src); namespace NArchive { namespace NDmg { +// allocation limits for compressed blocks for GetStream() interface: +static const unsigned k_NumChunks_MAX = 128; +static const size_t k_Chunk_Size_MAX = (size_t)1 << 28; +// 256 MB cache for 32-bit: +// 4 GB cache for 64-bit: +static const size_t k_Chunks_TotalSize_MAX = (size_t)1 << (sizeof(size_t) + 24); + +// 2 GB limit for 32-bit: +// 4 GB limit for 64-bit: +// that limit can be increased for 64-bit mode, if there are such dmg files +static const size_t k_XmlSize_MAX = + ((size_t)1 << (sizeof(size_t) / 4 + 30)) - 256; -static const UInt32 METHOD_ZERO_0 = 0; +static const UInt32 METHOD_ZERO_0 = 0; // sparse static const UInt32 METHOD_COPY = 1; -static const UInt32 METHOD_ZERO_2 = 2; // without file CRC calculation +static const UInt32 METHOD_ZERO_2 = 2; // sparse : without file CRC calculation static const UInt32 METHOD_ADC = 0x80000004; static const UInt32 METHOD_ZLIB = 0x80000005; static const UInt32 METHOD_BZIP2 = 0x80000006; static const UInt32 METHOD_LZFSE = 0x80000007; +static const UInt32 METHOD_XZ = 0x80000008; static const UInt32 METHOD_COMMENT = 0x7FFFFFFE; // is used to comment "+beg" and "+end" in extra field. static const UInt32 METHOD_END = 0xFFFFFFFF; @@ -54,20 +92,41 @@ { UInt32 Type; UInt64 UnpPos; - UInt64 UnpSize; + // UInt64 UnpSize; UInt64 PackPos; UInt64 PackSize; - UInt64 GetNextPackOffset() const { return PackPos + PackSize; } - UInt64 GetNextUnpPos() const { return UnpPos + UnpSize; } + bool NeedCrc() const { return Type != METHOD_ZERO_2; } + bool IsZeroMethod() const + { + return (Type & ~(UInt32)METHOD_ZERO_2) == 0; + // return Type == METHOD_ZERO_0 || Type == METHOD_ZERO_2; + } + + bool IsClusteredMethod() const + { + // most of dmg files have non-fused COPY_METHOD blocks. + // so we don't exclude COPY_METHOD blocks when we try to detect size of cluster. + return !IsZeroMethod(); // include COPY_METHOD blocks. + // Type > METHOD_ZERO_2; // for debug: exclude COPY_METHOD blocks. + } - bool IsZeroMethod() const { return Type == METHOD_ZERO_0 || Type == METHOD_ZERO_2; } - bool ThereAreDataInBlock() const { return Type != METHOD_COMMENT && Type != METHOD_END; } + bool NeedAllocateBuffer() const + { + return +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + !IsZeroMethod(); +#else + Type > METHOD_ZERO_2; + // !IsZeroMethod() && Type != METHOD_COPY; +#endif + } + // we don't store non-data blocks now + // bool ThereAreDataInBlock() const { return Type != METHOD_COMMENT && Type != METHOD_END; } }; static const UInt32 kCheckSumType_CRC = 2; - -static const size_t kChecksumSize_Max = 0x80; +static const unsigned kChecksumSize_Max = 0x80; struct CChecksum { @@ -78,6 +137,11 @@ bool IsCrc32() const { return Type == kCheckSumType_CRC && NumBits == 32; } UInt32 GetCrc32() const { return Get32(Data); } void Parse(const Byte *p); + + void PrintType(AString &s) const; + void Print(AString &s) const; + void Print_with_Name(AString &s) const; + void AddToComment(AString &s, const char *name) const; }; void CChecksum::Parse(const Byte *p) @@ -85,18 +149,109 @@ Type = Get32(p); NumBits = Get32(p + 4); memcpy(Data, p + 8, kChecksumSize_Max); -}; +} + + +void CChecksum::PrintType(AString &s) const +{ + if (NumBits == 0) + return; + if (IsCrc32()) + s += "CRC"; + else + { + s += "Checksum"; + s.Add_UInt32(Type); + s.Add_Minus(); + s.Add_UInt32(NumBits); + } +} + +void CChecksum::Print(AString &s) const +{ + if (NumBits == 0) + return; + char temp[kChecksumSize_Max * 2 + 2]; + /* + if (IsCrc32()) + ConvertUInt32ToHex8Digits(GetCrc32(), temp); + else + */ + { + UInt32 numBits = kChecksumSize_Max * 8; + if (numBits > NumBits) + numBits = NumBits; + const unsigned numBytes = (numBits + 7) >> 3; + if (numBytes <= 8) + ConvertDataToHex_Upper(temp, Data, numBytes); + else + ConvertDataToHex_Lower(temp, Data, numBytes); + } + s += temp; +} + +void CChecksum::Print_with_Name(AString &s) const +{ + if (NumBits == 0) + return; + PrintType(s); + s += ": "; + Print(s); +} + +static void AddToComment_Prop(AString &s, const char *name, const char *val) +{ + s += name; + s += ": "; + s += val; + s.Add_LF(); +} + +void CChecksum::AddToComment(AString &s, const char *name) const +{ + AString s2; + Print_with_Name(s2); + if (!s2.IsEmpty()) + AddToComment_Prop(s, name, s2); +} + struct CFile { UInt64 Size; + CRecordVector Blocks; UInt64 PackSize; - UInt64 StartPos; + UInt64 StartPackPos; + UInt64 BlockSize_MAX; + UInt64 StartUnpackSector; // unpack sector position of this file from all files + UInt64 NumUnpackSectors; + Int32 Descriptor; + bool IsCorrect; + bool FullFileChecksum; AString Name; - CRecordVector Blocks; + // AString Id; CChecksum Checksum; - bool FullFileChecksum; + UInt64 GetUnpackSize_of_Block(unsigned blockIndex) const + { + return (blockIndex == Blocks.Size() - 1 ? + Size : Blocks[blockIndex + 1].UnpPos) - Blocks[blockIndex].UnpPos; + } + + CFile(): + Size(0), + PackSize(0), + StartPackPos(0), + BlockSize_MAX(0), + StartUnpackSector(0), + NumUnpackSectors(0), + Descriptor(0), + IsCorrect(false), + FullFileChecksum(false) + { + Checksum.Type = 0; + Checksum.NumBits = 0; + } HRESULT Parse(const Byte *p, UInt32 size); }; @@ -109,93 +264,127 @@ #endif +static void AddToComment_UInt64(AString &s, UInt64 v, const char *name) +{ + s += name; + s += ": "; + s.Add_UInt64(v); + s.Add_LF(); +} + struct CForkPair { UInt64 Offset; UInt64 Len; + // (p) is aligned for 8-bytes void Parse(const Byte *p) { - Offset = Get64(p); - Len = Get64(p + 8); + Offset = Get64a(p); + Len = Get64a(p + 8); + } + + bool GetEndPos(UInt64 &endPos) + { + endPos = Offset + Len; + return endPos >= Offset; } bool UpdateTop(UInt64 limit, UInt64 &top) { if (Offset > limit || Len > limit - Offset) return false; - UInt64 top2 = Offset + Len; + const UInt64 top2 = Offset + Len; if (top <= top2) top = top2; return true; } -}; + void Print(AString &s, const char *name) const; +}; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp +void CForkPair::Print(AString &s, const char *name) const { - CMyComPtr _inStream; - CObjectVector _files; + if (Offset != 0 || Len != 0) + { + s += name; s.Add_Minus(); AddToComment_UInt64(s, Offset, "offset"); + s += name; s.Add_Minus(); AddToComment_UInt64(s, Len, "length"); + } +} + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) bool _masterCrcError; bool _headersError; + bool _dataForkError; + bool _rsrcMode_wasUsed; - UInt32 _dataStartOffset; + CMyComPtr _inStream; + CObjectVector _files; + + // UInt32 _dataStartOffset; UInt64 _startPos; UInt64 _phySize; AString _name; - - #ifdef DMG_SHOW_RAW + + CForkPair _dataForkPair; + CForkPair rsrcPair, xmlPair, blobPair; + + // UInt64 _runningDataForkOffset; + // UInt32 _segmentNumber; + // UInt32 _segmentCount; + UInt64 _numSectors; // total unpacked number of sectors + Byte _segmentGUID[16]; + + CChecksum _dataForkChecksum; + CChecksum _masterChecksum; + +#ifdef DMG_SHOW_RAW CObjectVector _extras; - #endif +#endif HRESULT ReadData(IInStream *stream, const CForkPair &pair, CByteBuffer &buf); bool ParseBlob(const CByteBuffer &data); - HRESULT Open2(IInStream *stream); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback); HRESULT Extract(IInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; -// that limit can be increased, if there are such dmg files -static const size_t kXmlSizeMax = 0xFFFF0000; // 4 GB - 64 KB; struct CMethods { CRecordVector Types; - CRecordVector ChecksumTypes; void Update(const CFile &file); - void GetString(AString &s) const; + void AddToString(AString &s) const; }; void CMethods::Update(const CFile &file) { - ChecksumTypes.AddToUniqueSorted(file.Checksum.Type); FOR_VECTOR (i, file.Blocks) + { + if (Types.Size() >= (1 << 8)) + break; Types.AddToUniqueSorted(file.Blocks[i].Type); + } } -void CMethods::GetString(AString &res) const +void CMethods::AddToString(AString &res) const { - res.Empty(); - - unsigned i; - - for (i = 0; i < Types.Size(); i++) + FOR_VECTOR (i, Types) { const UInt32 type = Types[i]; + /* if (type == METHOD_COMMENT || type == METHOD_END) continue; + */ char buf[16]; const char *s; switch (type) { + // case METHOD_COMMENT: s = "Comment"; break; case METHOD_ZERO_0: s = "Zero0"; break; case METHOD_ZERO_2: s = "Zero2"; break; case METHOD_COPY: s = "Copy"; break; @@ -203,25 +392,15 @@ case METHOD_ZLIB: s = "ZLIB"; break; case METHOD_BZIP2: s = "BZip2"; break; case METHOD_LZFSE: s = "LZFSE"; break; - default: ConvertUInt32ToString(type, buf); s = buf; + case METHOD_XZ: s = "XZ"; break; + default: ConvertUInt32ToHex(type, buf); s = buf; } res.Add_OptSpaced(s); } - - for (i = 0; i < ChecksumTypes.Size(); i++) - { - res.Add_Space_if_NotEmpty(); - UInt32 type = ChecksumTypes[i]; - switch (type) - { - case kCheckSumType_CRC: res += "CRC"; break; - default: - res += "Check"; - res.Add_UInt32(type); - } - } } + + struct CAppleName { bool IsFs; @@ -235,6 +414,7 @@ { true, "hfsx", "Apple_HFSX" }, { true, "ufs", "Apple_UFS" }, { true, "apfs", "Apple_APFS" }, + { true, "iso", "Apple_ISO" }, // efi_sys partition is FAT32, but it's not main file. So we use (IsFs = false) { false, "efi_sys", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, @@ -243,22 +423,68 @@ { false, "ddm", "DDM" }, { false, NULL, "Apple_partition_map" }, { false, NULL, " GPT " }, + /* " GPT " is substring of full name entry in dmg that contains + some small metadata GPT entry. It's not real FS entry: + "Primary GPT Header", + "Primary GPT Table" + "Backup GPT Header", + "Backup GPT Table", + */ { false, NULL, "MBR" }, { false, NULL, "Driver" }, { false, NULL, "Patches" } }; -static const unsigned kNumAppleNames = ARRAY_SIZE(k_Names); +static const unsigned kNumAppleNames = Z7_ARRAY_SIZE(k_Names); + +const char *Find_Apple_FS_Ext(const AString &name); +const char *Find_Apple_FS_Ext(const AString &name) +{ + for (unsigned i = 0; i < kNumAppleNames; i++) + { + const CAppleName &a = k_Names[i]; + if (a.Ext) + if (name.IsEqualTo(a.AppleName)) + return a.Ext; + } + return NULL; +} + + +bool Is_Apple_FS_Or_Unknown(const AString &name); +bool Is_Apple_FS_Or_Unknown(const AString &name) +{ + for (unsigned i = 0; i < kNumAppleNames; i++) + { + const CAppleName &a = k_Names[i]; + // if (name.Find(a.AppleName) >= 0) + if (strstr(name, a.AppleName)) + return a.IsFs; + } + return true; +} + + + +// define it for debug only: +// #define Z7_DMG_SINGLE_FILE_MODE static const Byte kProps[] = { kpidPath, kpidSize, kpidPackSize, - kpidCRC, kpidComment, - kpidMethod + kpidMethod, + kpidNumBlocks, + kpidClusterSize, + kpidChecksum, + kpidCRC, + kpidId // kpidOffset +#ifdef Z7_DMG_SINGLE_FILE_MODE + , kpidPosition +#endif }; IMP_IInArchive_Props @@ -267,10 +493,12 @@ { kpidMethod, kpidNumBlocks, + kpidClusterSize, kpidComment }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -279,10 +507,33 @@ case kpidMethod: { CMethods m; - FOR_VECTOR (i, _files) - m.Update(_files[i]); + CRecordVector ChecksumTypes; + { + FOR_VECTOR (i, _files) + { + const CFile &file = _files[i]; + m.Update(file); + if (ChecksumTypes.Size() < (1 << 8)) + ChecksumTypes.AddToUniqueSorted(file.Checksum.Type); + } + } AString s; - m.GetString(s); + m.AddToString(s); + + FOR_VECTOR (i, ChecksumTypes) + { + const UInt32 type = ChecksumTypes[i]; + switch (type) + { + case kCheckSumType_CRC: + s.Add_OptSpaced("CRC"); + break; + default: + s.Add_OptSpaced("Checksum"); + s.Add_UInt32(type); + } + } + if (!s.IsEmpty()) prop = s; break; @@ -295,37 +546,35 @@ prop = numBlocks; break; } + case kpidClusterSize: + { + UInt64 blockSize_MAX = 0; + FOR_VECTOR (i, _files) + { + const UInt64 a = _files[i].BlockSize_MAX; + if (blockSize_MAX < a) + blockSize_MAX = a; + } + prop = blockSize_MAX; + break; + } case kpidMainSubfile: { int mainIndex = -1; - unsigned numFS = 0; - unsigned numUnknown = 0; FOR_VECTOR (i, _files) { - const AString &name = _files[i].Name; - unsigned n; - for (n = 0; n < kNumAppleNames; n++) - { - const CAppleName &appleName = k_Names[n]; - // if (name.Find(appleName.AppleName) >= 0) - if (strstr(name, appleName.AppleName)) + if (Is_Apple_FS_Or_Unknown(_files[i].Name)) + { + if (mainIndex != -1) { - if (appleName.IsFs) - { - numFS++; - mainIndex = i; - } + mainIndex = -1; break; } - } - if (n == kNumAppleNames) - { - mainIndex = i; - numUnknown++; + mainIndex = (int)i; } } - if (numFS + numUnknown == 1) - prop = (UInt32)mainIndex; + if (mainIndex != -1) + prop = (UInt32)(Int32)mainIndex; break; } case kpidWarning: @@ -336,7 +585,8 @@ case kpidWarningFlags: { UInt32 v = 0; - if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (_dataForkError) v |= kpv_ErrorFlags_CrcError; if (v != 0) prop = v; break; @@ -346,15 +596,39 @@ case kpidPhySize: prop = _phySize; break; case kpidComment: - if (!_name.IsEmpty() && _name.Len() < 256) - prop = _name; - break; + { + AString s; + if (!_name.IsEmpty()) + AddToComment_Prop(s, "Name", _name); + AddToComment_UInt64(s, _numSectors << 9, "unpack-size"); + { + char temp[sizeof(_segmentGUID) * 2 + 2]; + ConvertDataToHex_Lower(temp, _segmentGUID, sizeof(_segmentGUID)); + AddToComment_Prop(s, "ID", temp); + } + _masterChecksum.AddToComment(s, "master-checksum"); + _dataForkChecksum.AddToComment(s, "pack-checksum"); + { + /* + if (_dataStartOffset != 0) + AddToComment_UInt64(s, _dataStartOffset, "payload-start-offset"); + */ + // if (_dataForkPair.Offset != 0) + _dataForkPair.Print(s, "pack"); + rsrcPair.Print(s, "rsrc"); + xmlPair.Print(s, "xml"); + blobPair.Print(s, "blob"); + } + if (_rsrcMode_wasUsed) + s += "RSRC_MODE\n"; + if (!s.IsEmpty()) + prop = s; + } + break; case kpidName: - if (!_name.IsEmpty() && _name.Len() < 256) - { + if (!_name.IsEmpty()) prop = _name + ".dmg"; - } break; } prop.Detach(value); @@ -364,39 +638,64 @@ IMP_IInArchive_ArcProps + + +static const UInt64 kSectorNumber_LIMIT = (UInt64)1 << (63 - 9); + HRESULT CFile::Parse(const Byte *p, UInt32 size) { - const UInt32 kHeadSize = 0xCC; + // CFile was initialized to default values: 0 in size variables and (IsCorrect == false) + const unsigned kHeadSize = 0xCC; if (size < kHeadSize) return S_FALSE; if (Get32(p) != 0x6D697368) // "mish" signature return S_FALSE; if (Get32(p + 4) != 1) // version return S_FALSE; - // UInt64 firstSectorNumber = Get64(p + 8); - UInt64 numSectors = Get64(p + 0x10); - - StartPos = Get64(p + 0x18); - - // UInt32 decompressedBufRequested = Get32(p + 0x20); // ??? - // UInt32 blocksDescriptor = Get32(p + 0x24); // number starting from -1? + + StartUnpackSector = Get64(p + 8); + NumUnpackSectors = Get64(p + 0x10); + StartPackPos = Get64(p + 0x18); + +#ifdef SHOW_DEBUG_INFO + /* the number of sectors that must be allocated. + == 0x208 for 256KB clusters + == 0x808 for 1MB clusters + == 0x1001 for 1MB clusters in some example + */ + const UInt32 decompressedBufRequested = Get32(p + 0x20); +#endif + + // Descriptor is file index. usually started from -1 + // in one dmg it was started from 0 + Descriptor = (Int32)Get32(p + 0x24); // char Reserved1[24]; Checksum.Parse(p + 0x40); - PRF(printf("\n\nChecksum Type = %2d", Checksum.Type)); - - UInt32 numBlocks = Get32(p + 0xC8); - if (numBlocks > ((UInt32)1 << 28)) - return S_FALSE; - - const UInt32 kRecordSize = 40; - if (numBlocks * kRecordSize + kHeadSize != size) + PRF(printf("\n" " Checksum Type = %2u" + "\n StartUnpackSector = %8x" + "\n NumUnpackSectors = %8x" + "\n StartPos = %8x" + "\n decompressedBufRequested=%8x" + "\n blocksDescriptor=%8x" + , (unsigned)Checksum.Type + , (unsigned)StartUnpackSector + , (unsigned)NumUnpackSectors + , (unsigned)StartPackPos + , (unsigned)decompressedBufRequested + , (unsigned)Descriptor + );) + + const UInt32 numBlocks = Get32(p + 0xC8); + const unsigned kRecordSize = 40; + if ((UInt64)numBlocks * kRecordSize + kHeadSize != size) return S_FALSE; - PackSize = 0; - Size = 0; Blocks.ClearAndReserve(numBlocks); FullFileChecksum = true; + /* IsCorrect = false; by default + So we return S_OK, if we can ignore some error in headers. + */ p += kHeadSize; UInt32 i; @@ -405,69 +704,109 @@ { CBlock b; b.Type = Get32(p); - b.UnpPos = Get64(p + 0x08) << 9; - b.UnpSize = Get64(p + 0x10) << 9; + { + const UInt64 a = Get64(p + 0x08); + if (a >= kSectorNumber_LIMIT) + return S_OK; + b.UnpPos = a << 9; + } + UInt64 unpSize; + { + const UInt64 a = Get64(p + 0x10); + if (a >= kSectorNumber_LIMIT) + return S_OK; + unpSize = a << 9; + } + const UInt64 newSize = b.UnpPos + unpSize; + if (newSize >= ((UInt64)1 << 63)) + return S_OK; + b.PackPos = Get64(p + 0x18); b.PackSize = Get64(p + 0x20); - // b.PackPos can be 0 for some types. So we don't check it - if (!Blocks.IsEmpty()) - if (b.UnpPos != Blocks.Back().GetNextUnpPos()) - return S_FALSE; + if (b.UnpPos != Size) + return S_OK; - PRF(printf("\nType=%8x m[1]=%8x uPos=%8x uSize=%7x pPos=%8x pSize=%7x", - b.Type, Get32(p + 4), (UInt32)b.UnpPos, (UInt32)b.UnpSize, (UInt32)b.PackPos, (UInt32)b.PackSize)); + PRF(printf("\nType=%8x comment=%8x uPos=%8x uSize=%7x pPos=%8x pSize=%7x", + (unsigned)b.Type, Get32(p + 4), (unsigned)b.UnpPos, (unsigned)unpSize, (unsigned)b.PackPos, (unsigned)b.PackSize)); if (b.Type == METHOD_COMMENT) + { + // some files contain 2 comment block records: + // record[0] : Type=METHOD_COMMENT, comment_field = "+beg" + // record[num-2] : Type=METHOD_COMMENT, comment_field = "+end" + // we skip these useless records. continue; + } if (b.Type == METHOD_END) break; - PackSize += b.PackSize; - - if (b.UnpSize != 0) + + // we add only blocks that have non empty unpacked data: + if (unpSize != 0) { - if (b.Type == METHOD_ZERO_2) + const UInt64 k_max_pos = (UInt64)1 << 63; + if (b.PackPos >= k_max_pos || + b.PackSize >= k_max_pos - b.PackPos) + return S_OK; + + /* we don't count non-ZERO blocks here, because + ZERO blocks in dmg files are not limited by some cluster size. + note: COPY blocks also sometimes are fused to larger blocks. + */ + if (b.IsClusteredMethod()) + if (BlockSize_MAX < unpSize) + BlockSize_MAX = unpSize; + + PackSize += b.PackSize; + if (!b.NeedCrc()) FullFileChecksum = false; Blocks.AddInReserved(b); + Size = newSize; } } - + + PRF(printf("\n");) + if (i != numBlocks - 1) - return S_FALSE; - if (!Blocks.IsEmpty()) - Size = Blocks.Back().GetNextUnpPos(); - if (Size != (numSectors << 9)) - return S_FALSE; - + { + // return S_FALSE; + return S_OK; + } + + if ((Size >> 9) == NumUnpackSectors) + IsCorrect = true; return S_OK; } -static int FindKeyPair(const CXmlItem &item, const char *key, const char *nextTag) + +static const CXmlItem *FindKeyPair(const CXmlItem &item, const char *key, const char *nextTag) { for (unsigned i = 0; i + 1 < item.SubItems.Size(); i++) { const CXmlItem &si = item.SubItems[i]; - if (si.IsTagged("key") && si.GetSubString() == key && item.SubItems[i + 1].IsTagged(nextTag)) - return i + 1; + if (si.IsTagged("key") && si.GetSubString().IsEqualTo(key)) + { + const CXmlItem *si_1 = &item.SubItems[i + 1]; + if (si_1->IsTagged(nextTag)) + return si_1; + } } - return -1; + return NULL; } static const AString *GetStringFromKeyPair(const CXmlItem &item, const char *key, const char *nextTag) { - int index = FindKeyPair(item, key, nextTag); - if (index >= 0) - return item.SubItems[index].GetSubStringPtr(); + const CXmlItem *si_1 = FindKeyPair(item, key, nextTag); + if (si_1) + return si_1->GetSubStringPtr(); return NULL; } -static const unsigned HEADER_SIZE = 0x200; - static const Byte k_Signature[] = { 'k','o','l','y', 0, 0, 0, 4, 0, 0, 2, 0 }; static inline bool IsKoly(const Byte *p) { - return memcmp(p, k_Signature, ARRAY_SIZE(k_Signature)) == 0; + return memcmp(p, k_Signature, Z7_ARRAY_SIZE(k_Signature)) == 0; /* if (Get32(p) != 0x6B6F6C79) // "koly" signature return false; @@ -486,152 +825,180 @@ if (size != pair.Len) return E_OUTOFMEMORY; buf.Alloc(size); - RINOK(stream->Seek(_startPos + pair.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, _startPos + pair.Offset)) return ReadStream_FALSE(stream, buf, size); } + bool CHandler::ParseBlob(const CByteBuffer &data) { - if (data.Size() < 12) + const unsigned kHeaderSize = 3 * 4; + if (data.Size() < kHeaderSize) return false; - const Byte *p = (const Byte *)data; - if (Get32(p) != 0xFADE0CC0) + const Byte * const p = (const Byte *)data; + if (Get32a(p) != 0xfade0cc0) // CSMAGIC_EMBEDDED_SIGNATURE return true; - const UInt32 size = Get32(p + 4); + const UInt32 size = Get32a(p + 4); if (size != data.Size()) return false; - const UInt32 num = Get32(p + 8); - if (num > (size - 12) / 8) + const UInt32 num = Get32a(p + 8); + if (num > (size - kHeaderSize) / 8) return false; - for (UInt32 i = 0; i < num; i++) + const UInt32 limit = num * 8 + kHeaderSize; + for (size_t i = kHeaderSize; i < limit; i += 8) { - // UInt32 type = Get32(p + i * 8 + 12); - UInt32 offset = Get32(p + i * 8 + 12 + 4); - if (size - offset < 8) + // type == 0 == CSSLOT_CODEDIRECTORY for CSMAGIC_CODEDIRECTORY item + // UInt32 type = Get32(p + i); + const UInt32 offset = Get32a(p + i + 4); + if (offset < limit || offset > size - 8) return false; - const Byte *p2 = (const Byte *)data + offset; + // offset is not aligned for 4 here !!! + const Byte * const p2 = p + offset; const UInt32 magic = Get32(p2); const UInt32 len = Get32(p2 + 4); if (size - offset < len || len < 8) return false; - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW CExtraFile &extra = _extras.AddNew(); extra.Name = "_blob_"; extra.Data.CopyFrom(p2, len); - #endif +#endif - if (magic == 0xFADE0C02) + if (magic == 0xfade0c02) // CSMAGIC_CODEDIRECTORY { - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW extra.Name += "codedir"; - #endif +#endif if (len < 11 * 4) return false; - UInt32 idOffset = Get32(p2 + 0x14); + const UInt32 idOffset = Get32(p2 + 5 * 4); if (idOffset >= len) return false; UInt32 len2 = len - idOffset; - if (len2 < (1 << 10)) - _name.SetFrom_CalcLen((const char *)(p2 + idOffset), len2); + const UInt32 kNameLenMax = 1 << 8; + if (len2 > kNameLenMax) + len2 = kNameLenMax; + _name.SetFrom_CalcLen((const char *)(p2 + idOffset), len2); + /* + // #define kSecCodeSignatureHashSHA1 1 + // #define kSecCodeSignatureHashSHA256 2 + const UInt32 hashOffset = Get32(p2 + 4 * 4); + const UInt32 nSpecialSlots = Get32(p2 + 6 * 4); + const UInt32 nCodeSlots = Get32(p2 + 7 * 4); + const unsigned hashSize = p2[36]; + const unsigned hashType = p2[37]; + // const unsigned unused = p2[38]; + const unsigned pageSize = p2[39]; + */ } - #ifdef DMG_SHOW_RAW - else if (magic == 0xFADE0C01) - extra.Name += "requirements"; - else if (magic == 0xFADE0B01) - extra.Name += "signed"; +#ifdef DMG_SHOW_RAW + else if (magic == 0xfade0c01) extra.Name += "requirements"; + else if (magic == 0xfade0b01) extra.Name += "signed"; else { char temp[16]; ConvertUInt32ToHex8Digits(magic, temp); extra.Name += temp; } - #endif +#endif } return true; } -HRESULT CHandler::Open2(IInStream *stream) + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) { /* - usual dmg contains Koly Header at the end: - - rare case dmg contains Koly Header at the start. + - rare case old dmg contains Koly Header at the begin. */ - _dataStartOffset = 0; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); - - UInt64 fileSize = 0; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(stream->Seek(_startPos, STREAM_SEEK_SET, NULL)); - - Byte buf[HEADER_SIZE]; - RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); + // _dataStartOffset = 0; + UInt64 fileSize; + RINOK(InStream_GetPos_GetSize(stream, _startPos, fileSize)) + + const unsigned HEADER_SIZE = 0x200; + UInt64 buf[HEADER_SIZE / sizeof(UInt64)]; + RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)) UInt64 headerPos; - bool startKolyMode = false; + bool front_Koly_Mode = false; - if (IsKoly(buf)) + /* + _dataForkChecksum.Offset == 0 for koly-at-the-end + _dataForkChecksum.Offset == 512 for koly-at-the-start + so we can use (_dataForkChecksum.Offset) to detect "koly-at-the-start" mode + */ + + if (IsKoly((const Byte *)(const void *)buf)) { // it can be normal koly-at-the-end or koly-at-the-start headerPos = _startPos; + /* if (_startPos <= (1 << 8)) { - // we want to support startKolyMode, even if there is + // we want to support front_Koly_Mode, even if there is // some data before dmg file, like 128 bytes MacBin header _dataStartOffset = HEADER_SIZE; - startKolyMode = true; + front_Koly_Mode = true; } + */ } else { - // we check only koly-at-the-end + /* we try to open in backward mode only for first attempt + when (_startPos == 0) */ + if (_startPos != 0) + return S_FALSE; headerPos = fileSize; if (headerPos < HEADER_SIZE) return S_FALSE; headerPos -= HEADER_SIZE; - RINOK(stream->Seek(headerPos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); - if (!IsKoly(buf)) + RINOK(InStream_SeekSet(stream, headerPos)) + RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)) + if (!IsKoly((const Byte *)(const void *)buf)) return S_FALSE; } - // UInt32 flags = Get32(buf + 12); - // UInt64 runningDataForkOffset = Get64(buf + 0x10); - - CForkPair dataForkPair, rsrcPair, xmlPair, blobPair; - - dataForkPair.Parse(buf + 0x18); - rsrcPair.Parse(buf + 0x28); - xmlPair.Parse(buf + 0xD8); - blobPair.Parse(buf + 0x128); - - // UInt32 segmentNumber = Get32(buf + 0x38); - // UInt32 segmentCount = Get32(buf + 0x3C); - // Byte segmentGUID[16]; - // CChecksum dataForkChecksum; - // dataForkChecksum.Parse(buf + 0x50); + // UInt32 flags = Get32a((const Byte *)(const void *)buf + 12); + // _runningDataForkOffset = Get64a((const Byte *)(const void *)buf + 0x10); + _dataForkPair.Parse((const Byte *)(const void *)buf + 0x18); + rsrcPair.Parse((const Byte *)(const void *)buf + 0x28); + // _segmentNumber = Get32a(buf + 0x38); // 0 or 1 + // _segmentCount = Get32a(buf + 0x3C); // 0 (if not set) or 1 + memcpy(_segmentGUID, (const Byte *)(const void *)buf + 0x40, 16); + _dataForkChecksum.Parse((const Byte *)(const void *)buf + 0x50); + xmlPair.Parse((const Byte *)(const void *)buf + 0xD8); + // Byte resereved[] + blobPair.Parse((const Byte *)(const void *)buf + 0x128); + _masterChecksum.Parse((const Byte *)(const void *)buf + 0x160); + // UInt32 imageVariant = Get32a((const Byte *)(const void *)buf + 0x1E8); imageVariant = imageVariant; + _numSectors = Get64((const Byte *)(const void *)buf + 0x1EC); // it's not aligned for 8-bytes + // Byte resereved[12]; + + if (_dataForkPair.Offset == HEADER_SIZE + && headerPos + HEADER_SIZE < fileSize) + front_Koly_Mode = true; + const UInt64 limit = front_Koly_Mode ? fileSize : headerPos; UInt64 top = 0; - UInt64 limit = startKolyMode ? fileSize : headerPos; - - if (!dataForkPair.UpdateTop(limit, top)) return S_FALSE; + if (!_dataForkPair.UpdateTop(limit, top)) return S_FALSE; if (!xmlPair.UpdateTop(limit, top)) return S_FALSE; if (!rsrcPair.UpdateTop(limit, top)) return S_FALSE; /* Some old dmg files contain garbage data in blobPair field. So we need to ignore such garbage case; And we still need to detect offset of start of archive for "parser" mode. */ + const bool useBlob = blobPair.UpdateTop(limit, top); - bool useBlob = blobPair.UpdateTop(limit, top); - - - if (startKolyMode) + if (front_Koly_Mode) _phySize = top; else { @@ -646,71 +1013,78 @@ - archive with offset. So we try to read XML with absolute offset to select from these two ways. */ - CForkPair xmlPair2 = xmlPair; - const char *sz = " len) - xmlPair2.Len = len; - CByteBuffer buf2; - if (xmlPair2.Len < len + CForkPair xmlPair2 = xmlPair; + const char *sz = " len) + xmlPair2.Len = len; + CByteBuffer buf2; + if (xmlPair2.Len < len || ReadData(stream, xmlPair2, buf2) != S_OK || memcmp(buf2, sz, len) != 0) - { - // if absolute offset is not OK, probably it's archive with offset - _startPos = headerPos - top; - _phySize = top + HEADER_SIZE; - } + { + // if absolute offset is not OK, probably it's archive with offset + _startPos = headerPos - top; + _phySize = top + HEADER_SIZE; + } } } - // Byte reserved[0x78] - - if (useBlob && blobPair.Len != 0) + if (useBlob + && blobPair.Len != 0 + && blobPair.Len <= (1u << 24)) // we don't want parsing of big blobs { - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW CExtraFile &extra = _extras.AddNew(); extra.Name = "_blob.bin"; CByteBuffer &blobBuf = extra.Data; - #else +#else CByteBuffer blobBuf; - #endif - RINOK(ReadData(stream, blobPair, blobBuf)); +#endif + RINOK(ReadData(stream, blobPair, blobBuf)) if (!ParseBlob(blobBuf)) _headersError = true; } - CChecksum masterChecksum; - masterChecksum.Parse(buf + 0x160); - - // UInt32 imageVariant = Get32(buf + 0x1E8); - // UInt64 numSectors = Get64(buf + 0x1EC); - // Byte reserved[0x12] + UInt64 openTotal = 0; + UInt64 openCur = 0; + if (_dataForkChecksum.IsCrc32()) + openTotal = _dataForkPair.Len; const UInt32 RSRC_HEAD_SIZE = 0x100; - // We don't know the size of the field "offset" in rsrc. - // We suppose that it uses 24 bits. So we use Rsrc, only if the rsrcLen < (1 << 24). - bool useRsrc = (rsrcPair.Len > RSRC_HEAD_SIZE && rsrcPair.Len < ((UInt32)1 << 24)); - // useRsrc = false; + /* we have 2 ways to read files and blocks metadata: + via Xml or via Rsrc. + But some images have no Rsrc fork. + Is it possible that there is no Xml? + Rsrc method will not work for big files. */ + // v23.02: we use xml mode by default + // if (rsrcPair.Len >= RSRC_HEAD_SIZE && rsrcPair.Len <= ((UInt32)1 << 24)) // for debug + if (xmlPair.Len == 0) + { + // We don't know the size of the field "offset" in Rsrc. + // We suppose that it uses 24 bits. So we use Rsrc, only if the rsrcPair.Len <= (1 << 24). + const bool canUseRsrc = (rsrcPair.Len >= RSRC_HEAD_SIZE && rsrcPair.Len <= ((UInt32)1 << 24)); + if (!canUseRsrc) + return S_FALSE; - if (useRsrc) - { - #ifdef DMG_SHOW_RAW + _rsrcMode_wasUsed = true; +#ifdef DMG_SHOW_RAW CExtraFile &extra = _extras.AddNew(); extra.Name = "rsrc.bin"; CByteBuffer &rsrcBuf = extra.Data; - #else +#else CByteBuffer rsrcBuf; - #endif +#endif - RINOK(ReadData(stream, rsrcPair, rsrcBuf)); + RINOK(ReadData(stream, rsrcPair, rsrcBuf)) const Byte *p = rsrcBuf; - UInt32 headSize = Get32(p + 0); - UInt32 footerOffset = Get32(p + 4); - UInt32 mainDataSize = Get32(p + 8); - UInt32 footerSize = Get32(p + 12); + const UInt32 headSize = Get32a(p + 0); + const UInt32 footerOffset = Get32a(p + 4); + const UInt32 mainDataSize = Get32a(p + 8); + const UInt32 footerSize = Get32a(p + 12); if (headSize != RSRC_HEAD_SIZE || footerOffset >= rsrcPair.Len || mainDataSize >= rsrcPair.Len @@ -718,59 +1092,59 @@ || footerOffset != headSize + mainDataSize) return S_FALSE; - const UInt32 footerEnd = footerOffset + footerSize; - if (footerEnd != rsrcPair.Len) { - // there is rare case dmg example, where there are 4 additional bytes - UInt64 rem = rsrcPair.Len - footerOffset; - if (rem < footerSize + const UInt32 footerEnd = footerOffset + footerSize; + if (footerEnd != rsrcPair.Len) + { + // there is rare case dmg example, where there are 4 additional bytes + const UInt64 rem = rsrcPair.Len - footerOffset; + if (rem < footerSize || rem - footerSize != 4 || Get32(p + footerEnd) != 0) - return S_FALSE; + return S_FALSE; + } } - if (footerSize < 16) + if (footerSize < 0x1e) return S_FALSE; if (memcmp(p, p + footerOffset, 16) != 0) return S_FALSE; p += footerOffset; - if ((UInt32)Get16(p + 0x18) != 0x1C) + if ((UInt32)Get16(p + 0x18) != 0x1c) return S_FALSE; - const UInt32 namesOffset = Get16(p + 0x1A); + const UInt32 namesOffset = Get16(p + 0x1a); if (namesOffset > footerSize) return S_FALSE; - UInt32 numItems = (UInt32)Get16(p + 0x1C) + 1; - if (numItems * 8 + 0x1E > namesOffset) + const UInt32 numItems = (UInt32)Get16(p + 0x1c) + 1; + if (numItems * 8 + 0x1e > namesOffset) return S_FALSE; for (UInt32 i = 0; i < numItems; i++) { - const Byte *p2 = p + 0x1E + i * 8; - + const Byte *p2 = p + 0x1e + (size_t)i * 8; const UInt32 typeId = Get32(p2); - - #ifndef DMG_SHOW_RAW - if (typeId != 0x626C6B78) // blkx + const UInt32 k_typeId_blkx = 0x626c6b78; // blkx +#ifndef DMG_SHOW_RAW + if (typeId != k_typeId_blkx) continue; - #endif - +#endif const UInt32 numFiles = (UInt32)Get16(p2 + 4) + 1; const UInt32 offs = Get16(p2 + 6); - if (0x1C + offs + 12 * numFiles > namesOffset) + if (0x1c + offs + 12 * numFiles > namesOffset) return S_FALSE; for (UInt32 k = 0; k < numFiles; k++) { - const Byte *p3 = p + 0x1C + offs + k * 12; + const Byte *p3 = p + 0x1c + offs + k * 12; // UInt32 id = Get16(p3); const UInt32 namePos = Get16(p3 + 2); - // Byte attributes = p3[4]; // = 0x50 for blkx + // Byte attributes = p3[4]; // = 0x50 for blkx #define (ATTRIBUTE_HDIUTIL) // we don't know how many bits we can use. So we use 24 bits only UInt32 blockOffset = Get32(p3 + 4); - blockOffset &= (((UInt32)1 << 24) - 1); + blockOffset &= ((UInt32)1 << 24) - 1; // UInt32 unknown2 = Get32(p3 + 8); // ??? if (blockOffset + 4 >= mainDataSize) return S_FALSE; @@ -781,38 +1155,38 @@ AString name; - if (namePos != 0xFFFF) + if (namePos != 0xffff) { - UInt32 namesBlockSize = footerSize - namesOffset; + const UInt32 namesBlockSize = footerSize - namesOffset; if (namePos >= namesBlockSize) return S_FALSE; const Byte *namePtr = p + namesOffset + namePos; - UInt32 nameLen = *namePtr; + const UInt32 nameLen = *namePtr; if (namesBlockSize - namePos <= nameLen) return S_FALSE; for (UInt32 r = 1; r <= nameLen; r++) { - Byte c = namePtr[r]; + const Byte c = namePtr[r]; if (c < 0x20 || c >= 0x80) break; name += (char)c; } } - if (typeId == 0x626C6B78) // blkx + if (typeId == k_typeId_blkx) { CFile &file = _files.AddNew(); file.Name = name; - RINOK(file.Parse(pBlock + 4, blockSize)); + RINOK(file.Parse(pBlock + 4, blockSize)) + if (!file.IsCorrect) + _headersError = true; } - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW { AString name2; - name2.Add_UInt32(i); name2 += '_'; - { char temp[4 + 1] = { 0 }; memcpy(temp, p2, 4); @@ -821,69 +1195,80 @@ name2.Trim(); name2 += '_'; name2.Add_UInt32(k); - if (!name.IsEmpty()) { name2 += '_'; name2 += name; } - - CExtraFile &extra = _extras.AddNew(); - extra.Name = name2; - extra.Data.CopyFrom(pBlock + 4, blockSize); + CExtraFile &extra2 = _extras.AddNew(); + extra2.Name = name2; + extra2.Data.CopyFrom(pBlock + 4, blockSize); } - #endif +#endif } } } else { - if (xmlPair.Len >= kXmlSizeMax || xmlPair.Len == 0) + if (xmlPair.Len > k_XmlSize_MAX) return S_FALSE; - size_t size = (size_t)xmlPair.Len; - if (size != xmlPair.Len) - return S_FALSE; - - RINOK(stream->Seek(_startPos + xmlPair.Offset, STREAM_SEEK_SET, NULL)); - + // if (!canUseXml) return S_FALSE; + const size_t size = (size_t)xmlPair.Len; + // if (size + 1 <= xmlPair.Len) return S_FALSE; // optional check + RINOK(InStream_SeekSet(stream, _startPos + xmlPair.Offset)) CXml xml; { - CObjArray xmlStr(size + 1); - RINOK(ReadStream_FALSE(stream, xmlStr, size)); + openTotal += size; + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetTotal(NULL, &openTotal)) + } + size_t pos = 0; + CAlignedBuffer1 xmlStr(size + 1); + for (;;) + { + const size_t k_OpenStep = 1 << 24; + const size_t cur = MyMin(k_OpenStep, size - pos); + RINOK(ReadStream_FALSE(stream, xmlStr + pos, cur)) + pos += cur; + openCur += cur; + if (pos == size) + break; + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetCompleted(NULL, &openCur)) + } + } xmlStr[size] = 0; - // if (strlen(xmlStr) != size) return S_FALSE; - if (!xml.Parse(xmlStr)) + // if (strlen((const char *)(const void *)(const Byte *)xmlStr) != size) return S_FALSE; + if (!xml.Parse((char *)(void *)(Byte *)xmlStr)) return S_FALSE; - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW CExtraFile &extra = _extras.AddNew(); extra.Name = "a.xml"; - extra.Data.CopyFrom((const Byte *)(const char *)xmlStr, size); - #endif + extra.Data.CopyFrom(xmlStr, size); +#endif } - if (xml.Root.Name != "plist") + if (!xml.Root.Name.IsEqualTo("plist")) return S_FALSE; - int dictIndex = xml.Root.FindSubTag("dict"); - if (dictIndex < 0) + const CXmlItem *dictItem = xml.Root.FindSubTag_GetPtr("dict"); + if (!dictItem) return S_FALSE; - const CXmlItem &dictItem = xml.Root.SubItems[dictIndex]; - int rfDictIndex = FindKeyPair(dictItem, "resource-fork", "dict"); - if (rfDictIndex < 0) + const CXmlItem *rfDictItem = FindKeyPair(*dictItem, "resource-fork", "dict"); + if (!rfDictItem) return S_FALSE; - const CXmlItem &rfDictItem = dictItem.SubItems[rfDictIndex]; - int arrIndex = FindKeyPair(rfDictItem, "blkx", "array"); - if (arrIndex < 0) + const CXmlItem *arrItem = FindKeyPair(*rfDictItem, "blkx", "array"); + if (!arrItem) return S_FALSE; - const CXmlItem &arrItem = rfDictItem.SubItems[arrIndex]; - - FOR_VECTOR (i, arrItem.SubItems) + FOR_VECTOR (i, arrItem->SubItems) { - const CXmlItem &item = arrItem.SubItems[i]; + const CXmlItem &item = arrItem->SubItems[i]; if (!item.IsTagged("dict")) continue; @@ -902,25 +1287,38 @@ destLen = (unsigned)(endPtr - (const Byte *)rawBuf); } - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW CExtraFile &extra = _extras.AddNew(); extra.Name.Add_UInt32(_files.Size()); extra.Data.CopyFrom(rawBuf, destLen); - #endif +#endif } CFile &file = _files.AddNew(); { + /* xml code removes front space for such string: + (Apple_Free : 3) + maybe we shoud fix xml code and return full string with space. + */ const AString *name = GetStringFromKeyPair(item, "Name", "string"); if (!name || name->IsEmpty()) name = GetStringFromKeyPair(item, "CFName", "string"); if (name) file.Name = *name; } - RINOK(file.Parse(rawBuf, destLen)); + /* + { + const AString *s = GetStringFromKeyPair(item, "ID", "string"); + if (s) + file.Id = *s; + } + */ + RINOK(file.Parse(rawBuf, destLen)) + if (!file.IsCorrect) + _headersError = true; } } - if (masterChecksum.IsCrc32()) + if (_masterChecksum.IsCrc32()) { UInt32 crc = CRC_INIT_VAL; unsigned i; @@ -929,54 +1327,127 @@ const CChecksum &cs = _files[i].Checksum; if ((cs.NumBits & 0x7) != 0) break; - UInt32 len = cs.NumBits >> 3; + const UInt32 len = cs.NumBits >> 3; if (len > kChecksumSize_Max) break; crc = CrcUpdate(crc, cs.Data, (size_t)len); } if (i == _files.Size()) - _masterCrcError = (CRC_GET_DIGEST(crc) != masterChecksum.GetCrc32()); + _masterCrcError = (CRC_GET_DIGEST(crc) != _masterChecksum.GetCrc32()); + } + + { + UInt64 sec = 0; + FOR_VECTOR (i, _files) + { + const CFile &file = _files[i]; + /* + if (file.Descriptor != (Int32)i - 1) + _headersError = true; + */ + if (file.StartUnpackSector != sec) + _headersError = true; + if (file.NumUnpackSectors >= kSectorNumber_LIMIT) + _headersError = true; + sec += file.NumUnpackSectors; + if (sec >= kSectorNumber_LIMIT) + _headersError = true; + } + if (sec != _numSectors) + _headersError = true; + } + + // data checksum calculation can be slow for big dmg file + if (_dataForkChecksum.IsCrc32()) + { + UInt64 endPos; + if (!_dataForkPair.GetEndPos(endPos) + || _dataForkPair.Offset >= ((UInt64)1 << 63)) + _headersError = true; + else + { + const UInt64 seekPos = _startPos + _dataForkPair.Offset; + if (seekPos > fileSize + || endPos > fileSize - _startPos) + { + _headersError = true; + // kpv_ErrorFlags_UnexpectedEnd + } + else + { + const size_t kBufSize = 1 << 15; + CAlignedBuffer1 buf2(kBufSize); + RINOK(InStream_SeekSet(stream, seekPos)) + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetTotal(NULL, &openTotal)) + } + UInt32 crc = CRC_INIT_VAL; + UInt64 pos = 0; + for (;;) + { + const UInt64 rem = _dataForkPair.Len - pos; + size_t cur = kBufSize; + if (cur > rem) + cur = (UInt32)rem; + if (cur == 0) + break; + RINOK(ReadStream_FALSE(stream, buf2, cur)) + crc = CrcUpdate(crc, buf2, cur); + pos += cur; + openCur += cur; + if ((pos & ((1 << 24) - 1)) == 0 && openArchiveCallback) + { + RINOK(openArchiveCallback->SetCompleted(NULL, &openCur)) + } + } + if (_dataForkChecksum.GetCrc32() != CRC_GET_DIGEST(crc)) + _dataForkError = true; + } + } } return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN - { - Close(); - if (Open2(stream) != S_OK) - return S_FALSE; - _inStream = stream; - } + Close(); + RINOK(Open2(stream, openArchiveCallback)) + _inStream = stream; return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { - _phySize = 0; - _inStream.Release(); - _files.Clear(); _masterCrcError = false; _headersError = false; + _dataForkError = false; + _rsrcMode_wasUsed = false; + _phySize = 0; + _startPos = 0; _name.Empty(); - #ifdef DMG_SHOW_RAW + _inStream.Release(); + _files.Clear(); +#ifdef DMG_SHOW_RAW _extras.Clear(); - #endif +#endif return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _files.Size() - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW + _extras.Size() - #endif - ; +#endif + ; return S_OK; } @@ -984,12 +1455,12 @@ #define RAW_PREFIX "raw" STRING_PATH_SEPARATOR #endif -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW if (index >= _files.Size()) { const CExtraFile &extra = _extras[index - _files.Size()]; @@ -1005,7 +1476,7 @@ } } else - #endif +#endif { const CFile &item = _files[index]; switch (propID) @@ -1018,21 +1489,44 @@ prop = item.Checksum.GetCrc32(); break; } + case kpidChecksum: + { + AString s; + item.Checksum.Print(s); + if (!s.IsEmpty()) + prop = s; + break; + } /* case kpidOffset: { - prop = item.StartPos; + prop = item.StartPackPos; break; } */ + case kpidNumBlocks: + prop = (UInt32)item.Blocks.Size(); + break; + case kpidClusterSize: + prop = item.BlockSize_MAX; + break; + case kpidMethod: { + AString s; + if (!item.IsCorrect) + s.Add_OptSpaced("CORRUPTED"); CMethods m; m.Update(item); - AString s; - m.GetString(s); + m.AddToString(s); + { + AString s2; + item.Checksum.PrintType(s2); + if (!s2.IsEmpty()) + s.Add_OptSpaced(s2); + } if (!s.IsEmpty()) prop = s; break; @@ -1040,6 +1534,9 @@ case kpidPath: { +#ifdef Z7_DMG_SINGLE_FILE_MODE + prop = "a.img"; +#else UString name; name.Add_UInt32(index); unsigned num = 10; @@ -1054,7 +1551,7 @@ if (pos1 >= 0) { pos1++; - int pos2 = item.Name.Find(')', pos1); + const int pos2 = item.Name.Find(')', pos1); if (pos2 >= 0) { subName.SetFrom(item.Name.Ptr(pos1), pos2 - pos1); @@ -1068,21 +1565,12 @@ subName.Trim(); if (!subName.IsEmpty()) { - for (unsigned n = 0; n < kNumAppleNames; n++) - { - const CAppleName &appleName = k_Names[n]; - if (appleName.Ext) - { - if (subName == appleName.AppleName) - { - subName = appleName.Ext; - break; - } - } - } + const char *ext = Find_Apple_FS_Ext(subName); + if (ext) + subName = ext; UString name2; ConvertUTF8ToUnicode(subName, name2); - name += '.'; + name.Add_Dot(); name += name2; } else @@ -1094,6 +1582,8 @@ name += name2; } prop = name; +#endif + break; } @@ -1104,6 +1594,24 @@ prop = name; break; } + case kpidId: + { + prop.Set_Int32((Int32)item.Descriptor); + /* + if (!item.Id.IsEmpty()) + { + UString s; + ConvertUTF8ToUnicode(item.Id, s); + prop = s; + } + */ + break; + } +#ifdef Z7_DMG_SINGLE_FILE_MODE + case kpidPosition: + prop = item.StartUnpackSector << 9; + break; +#endif } } prop.Detach(value); @@ -1111,22 +1619,13 @@ COM_TRY_END } -class CAdcDecoder: - public ICompressCoder, - public CMyUnknownImp + +class CAdcDecoder { CLzOutWindow m_OutWindowStream; CInBuffer m_InStream; - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InStream.ReleaseStream(); - } - */ - - class CCoderReleaser + class CCoderReleaser Z7_final { CAdcDecoder *m_Coder; public: @@ -1136,28 +1635,28 @@ { if (NeedFlush) m_Coder->m_OutWindowStream.Flush(); - // m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; public: - MY_UNKNOWN_IMP - - STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); + HRESULT Code(ISequentialInStream * const inStream, + ISequentialOutStream *outStream, + const UInt64 * const inSize, + const UInt64 * const outSize, + ICompressProgressInfo * const progress); }; -STDMETHODIMP CAdcDecoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) + +HRESULT CAdcDecoder::Code(ISequentialInStream * const inStream, + ISequentialOutStream *outStream, + const UInt64 * const inSize, + const UInt64 * const outSizePtr, + ICompressProgressInfo * const progress) { - if (!m_OutWindowStream.Create(1 << 18)) + try { + + if (!m_OutWindowStream.Create(1 << 18)) // at least (1 << 16) is required here return E_OUTOFMEMORY; if (!m_InStream.Create(1 << 18)) return E_OUTOFMEMORY; @@ -1169,73 +1668,72 @@ CCoderReleaser coderReleaser(this); - const UInt32 kStep = (1 << 20); + const UInt32 kStep = 1 << 22; UInt64 nextLimit = kStep; - + const UInt64 outSize = *outSizePtr; UInt64 pos = 0; - while (pos < *outSize) + /* match sequences and literal sequences do not cross 64KB range + in some dmg archive examples. But is it so for any Adc stream? */ + + while (pos < outSize) { - if (pos > nextLimit && progress) + if (pos >= nextLimit && progress) { - UInt64 packSize = m_InStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); nextLimit += kStep; + const UInt64 packSize = m_InStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) } Byte b; if (!m_InStream.ReadByte(b)) return S_FALSE; - UInt64 rem = *outSize - pos; + const UInt64 rem = outSize - pos; if (b & 0x80) { - unsigned num = (b & 0x7F) + 1; + unsigned num = (unsigned)b - 0x80 + 1; if (num > rem) return S_FALSE; - for (unsigned i = 0; i < num; i++) + pos += num; + do { if (!m_InStream.ReadByte(b)) return S_FALSE; m_OutWindowStream.PutByte(b); } - pos += num; + while (--num); continue; } Byte b1; if (!m_InStream.ReadByte(b1)) return S_FALSE; - UInt32 len, distance; + UInt32 len, dist; if (b & 0x40) { - len = ((UInt32)b & 0x3F) + 4; + len = (UInt32)b - 0x40 + 4; Byte b2; if (!m_InStream.ReadByte(b2)) return S_FALSE; - distance = ((UInt32)b1 << 8) + b2; + dist = ((UInt32)b1 << 8) + b2; } else { - b &= 0x3F; len = ((UInt32)b >> 2) + 3; - distance = (((UInt32)b & 3) << 8) + b1; + dist = (((UInt32)b & 3) << 8) + b1; } - if (distance >= pos || len > rem) + if (/* dist >= pos || */ len > rem) + return S_FALSE; + if (!m_OutWindowStream.CopyBlock(dist, len)) return S_FALSE; - m_OutWindowStream.CopyBlock(distance, len); pos += len; } if (*inSize != m_InStream.GetProcessedSize()) return S_FALSE; coderReleaser.NeedFlush = false; return m_OutWindowStream.Flush(); -} -STDMETHODIMP CAdcDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + } catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CLzOutWindowException &e) { return e.ErrorCode; } catch(...) { return S_FALSE; } @@ -1243,17 +1741,66 @@ +struct CDecoders +{ + CMyComPtr2 zlib; + CMyComPtr2 bzip2; + CMyComPtr2 lzfse; + CMyUniquePtr xz; + CMyUniquePtr adc; + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const CBlock &block, const UInt64 *unpSize, ICompressProgressInfo *progress); +}; +HRESULT CDecoders::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const CBlock &block, const UInt64 *unpSize, ICompressProgressInfo *progress) +{ + HRESULT hres; + UInt64 processed; + switch (block.Type) + { + case METHOD_ADC: + adc.Create_if_Empty(); + return adc->Code(inStream, outStream, &block.PackSize, unpSize, progress); + case METHOD_LZFSE: + lzfse.Create_if_Empty(); + return lzfse.Interface()->Code(inStream, outStream, &block.PackSize, unpSize, progress); + case METHOD_ZLIB: + zlib.Create_if_Empty(); + hres = zlib.Interface()->Code(inStream, outStream, NULL, unpSize, progress); + processed = zlib->GetInputProcessedSize(); + break; + case METHOD_BZIP2: + bzip2.Create_if_Empty(); + hres = bzip2.Interface()->Code(inStream, outStream, NULL, unpSize, progress); + processed = bzip2->GetInputProcessedSize(); + break; + case METHOD_XZ: + xz.Create_if_Empty(); + hres = xz->Decode(inStream, outStream, unpSize, true, progress); + processed = xz->Stat.InSize; + break; + default: + return E_NOTIMPL; + } + if (hres == S_OK && processed != block.PackSize) + hres = S_FALSE; + return hres; +} -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) - numItems = _files.Size(); + numItems = _files.Size() +#ifdef DMG_SHOW_RAW + + _extras.Size() +#endif + ; if (numItems == 0) return S_OK; UInt64 totalSize = 0; @@ -1261,289 +1808,260 @@ for (i = 0; i < numItems; i++) { - UInt32 index = (allFilesMode ? i : indices[i]); - #ifdef DMG_SHOW_RAW + const UInt32 index = allFilesMode ? i : indices[i]; +#ifdef DMG_SHOW_RAW if (index >= _files.Size()) totalSize += _extras[index - _files.Size()].Data.Size(); else - #endif +#endif totalSize += _files[index].Size; } - extractCallback->SetTotal(totalSize); - - UInt64 currentPackTotal = 0; - UInt64 currentUnpTotal = 0; - UInt64 currentPackSize = 0; - UInt64 currentUnpSize = 0; + RINOK(extractCallback->SetTotal(totalSize)) - const UInt32 kZeroBufSize = (1 << 14); - CByteBuffer zeroBuf(kZeroBufSize); + const size_t kZeroBufSize = 1 << 14; + CAlignedBuffer1 zeroBuf(kZeroBufSize); memset(zeroBuf, 0, kZeroBufSize); - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - CMyComPtr bzip2Coder = bzip2CoderSpec; - - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - CAdcDecoder *adcCoderSpec = new CAdcDecoder(); - CMyComPtr adcCoder = adcCoderSpec; - - NCompress::NLzfse::CDecoder *lzfseCoderSpec = new NCompress::NLzfse::CDecoder(); - CMyComPtr lzfseCoder = lzfseCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CDecoders decoders; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_inStream); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) - { - lps->InSize = currentPackTotal; - lps->OutSize = currentUnpTotal; - currentPackSize = 0; - currentUnpSize = 0; - RINOK(lps->SetCur()); + UInt64 total_PackSize = 0; + UInt64 total_UnpackSize = 0; + UInt64 cur_PackSize = 0; + UInt64 cur_UnpackSize = 0; + + for (i = 0;; i++, + total_PackSize += cur_PackSize, + total_UnpackSize += cur_UnpackSize) + { + lps->InSize = total_PackSize; + lps->OutSize = total_UnpackSize; + cur_PackSize = 0; + cur_UnpackSize = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + return S_OK; + + Int32 opRes = NExtract::NOperationResult::kOK; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - - COutStreamWithCRC *outCrcStreamSpec = new COutStreamWithCRC; - CMyComPtr outCrcStream = outCrcStreamSpec; - outCrcStreamSpec->SetStream(realOutStream); - bool needCrc = false; - outCrcStreamSpec->Init(needCrc); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(outCrcStream); - - realOutStream.Release(); + RINOK(extractCallback->PrepareOperation(askMode)) - Int32 opRes = NExtract::NOperationResult::kOK; - #ifdef DMG_SHOW_RAW +#ifdef DMG_SHOW_RAW if (index >= _files.Size()) { const CByteBuffer &buf = _extras[index - _files.Size()].Data; - outStreamSpec->Init(buf.Size()); - RINOK(WriteStream(outStream, buf, buf.Size())); - currentPackSize = currentUnpSize = buf.Size(); + if (realOutStream) + RINOK(WriteStream(realOutStream, buf, buf.Size())) + cur_PackSize = cur_UnpackSize = buf.Size(); } else - #endif +#endif { const CFile &item = _files[index]; - currentPackSize = item.PackSize; - currentUnpSize = item.Size; - - needCrc = item.Checksum.IsCrc32(); + cur_PackSize = item.PackSize; + cur_UnpackSize = item.Size; - UInt64 unpPos = 0; - UInt64 packPos = 0; + if (!item.IsCorrect) + opRes = NExtract::NOperationResult::kHeadersError; + else { - FOR_VECTOR (j, item.Blocks) + CMyComPtr2_Create outCrcStream; + outCrcStream->SetStream(realOutStream); + // realOutStream.Release(); + const bool needCrc = item.Checksum.IsCrc32(); + outCrcStream->Init(needCrc); + + CMyComPtr2_Create outStream; + outStream->SetStream(outCrcStream); + + UInt64 unpPos = 0; + UInt64 packPos = 0; + + FOR_VECTOR (blockIndex, item.Blocks) { - lps->InSize = currentPackTotal + packPos; - lps->OutSize = currentUnpTotal + unpPos; - RINOK(lps->SetCur()); + lps->InSize = total_PackSize + packPos; + lps->OutSize = total_UnpackSize + unpPos; + RINOK(lps->SetCur()) - const CBlock &block = item.Blocks[j]; - if (!block.ThereAreDataInBlock()) - continue; + const CBlock &block = item.Blocks[blockIndex]; + // if (!block.ThereAreDataInBlock()) continue; packPos += block.PackSize; if (block.UnpPos != unpPos) { - opRes = NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kHeadersError; break; } - RINOK(_inStream->Seek(_startPos + _dataStartOffset + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); - streamSpec->Init(block.PackSize); - bool realMethod = true; - outStreamSpec->Init(block.UnpSize); - HRESULT res = S_OK; - - outCrcStreamSpec->EnableCalc(needCrc); + RINOK(InStream_SeekSet(_inStream, _startPos + _dataForkPair.Offset + item.StartPackPos + block.PackPos)) + inStream->Init(block.PackSize); - switch (block.Type) - { - case METHOD_ZERO_0: - case METHOD_ZERO_2: - realMethod = false; - if (block.PackSize != 0) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - outCrcStreamSpec->EnableCalc(block.Type == METHOD_ZERO_0); - break; + const UInt64 unpSize = item.GetUnpackSize_of_Block(blockIndex); - case METHOD_COPY: - if (block.UnpSize != block.PackSize) - { - opRes = NExtract::NOperationResult::kUnsupportedMethod; - break; - } - res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - break; - - case METHOD_ADC: - { - res = adcCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, progress); - break; - } - - case METHOD_ZLIB: - { - res = zlibCoder->Code(inStream, outStream, NULL, NULL, progress); - if (res == S_OK) - if (zlibCoderSpec->GetInputProcessedSize() != block.PackSize) - opRes = NExtract::NOperationResult::kDataError; - break; - } + outStream->Init(unpSize); + HRESULT res = S_OK; - case METHOD_BZIP2: - { - res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress); - if (res == S_OK) - if (bzip2CoderSpec->GetInputProcessedSize() != block.PackSize) - opRes = NExtract::NOperationResult::kDataError; - break; - } + outCrcStream->EnableCalc(needCrc && block.NeedCrc()); - case METHOD_LZFSE: - { - res = lzfseCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, progress); - break; - } - - default: + if (block.IsZeroMethod()) + { + if (block.PackSize != 0) opRes = NExtract::NOperationResult::kUnsupportedMethod; - break; } + else if (block.Type == METHOD_COPY) + { + if (unpSize != block.PackSize) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + res = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + } + else + res = decoders.Code(inStream, outStream, block, &unpSize, lps); if (res != S_OK) { if (res != S_FALSE) - return res; + { + if (res != E_NOTIMPL) + return res; + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } if (opRes == NExtract::NOperationResult::kOK) opRes = NExtract::NOperationResult::kDataError; } - unpPos += block.UnpSize; + unpPos += unpSize; - if (!outStreamSpec->IsFinishedOK()) + if (!outStream->IsFinishedOK()) { - if (realMethod && opRes == NExtract::NOperationResult::kOK) + if (!block.IsZeroMethod() && opRes == NExtract::NOperationResult::kOK) opRes = NExtract::NOperationResult::kDataError; - while (outStreamSpec->GetRem() != 0) + for (unsigned k = 0;;) { - UInt64 rem = outStreamSpec->GetRem(); - UInt32 size = (UInt32)MyMin(rem, (UInt64)kZeroBufSize); - RINOK(WriteStream(outStream, zeroBuf, size)); + const UInt64 rem = outStream->GetRem(); + if (rem == 0) + break; + size_t size = kZeroBufSize; + if (size > rem) + size = (size_t)rem; + RINOK(WriteStream(outStream, zeroBuf, size)) + k++; + if ((k & 0xfff) == 0) + { + lps->OutSize = total_UnpackSize + unpPos - outStream->GetRem(); + RINOK(lps->SetCur()) + } } } } - } - - if (needCrc && opRes == NExtract::NOperationResult::kOK) - { - if (outCrcStreamSpec->GetCRC() != item.Checksum.GetCrc32()) - opRes = NExtract::NOperationResult::kCRCError; + if (needCrc && opRes == NExtract::NOperationResult::kOK) + { + if (outCrcStream->GetCRC() != item.Checksum.GetCrc32()) + opRes = NExtract::NOperationResult::kCRCError; + } } } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + } + RINOK(extractCallback->SetOperationResult(opRes)) } - return S_OK; COM_TRY_END } + + + struct CChunk { int BlockIndex; UInt64 AccessMark; - CByteBuffer Buf; + Byte *Buf; + size_t BufSize; + + void Free() + { + z7_AlignedFree(Buf); + Buf = NULL; + BufSize = 0; + } + void Alloc(size_t size) + { + Buf = (Byte *)z7_AlignedAlloc(size); + } }; -class CInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CInStream +) + bool _errorMode; UInt64 _virtPos; int _latestChunk; int _latestBlock; UInt64 _accessMark; - CObjectVector _chunks; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec; - CMyComPtr bzip2Coder; - - NCompress::NZlib::CDecoder *zlibCoderSpec; - CMyComPtr zlibCoder; - - CAdcDecoder *adcCoderSpec; - CMyComPtr adcCoder; - - NCompress::NLzfse::CDecoder *lzfseCoderSpec; - CMyComPtr lzfseCoder; - - CBufPtrSeqOutStream *outStreamSpec; - CMyComPtr outStream; - - CLimitedSequentialInStream *limitedStreamSpec; - CMyComPtr inStream; + UInt64 _chunks_TotalSize; + CRecordVector _chunks; public: CMyComPtr Stream; - UInt64 Size; const CFile *File; + UInt64 Size; +private: UInt64 _startPos; - HRESULT InitAndSeek(UInt64 startPos) + ~CInStream(); + CMyComPtr2 outStream; + CMyComPtr2 inStream; + CDecoders decoders; +public: + + // HRESULT + void Init(UInt64 startPos) { + _errorMode = false; _startPos = startPos; _virtPos = 0; _latestChunk = -1; _latestBlock = -1; _accessMark = 0; + _chunks_TotalSize = 0; - limitedStreamSpec = new CLimitedSequentialInStream; - inStream = limitedStreamSpec; - limitedStreamSpec->SetStream(Stream); + inStream.Create_if_Empty(); + inStream->SetStream(Stream); - outStreamSpec = new CBufPtrSeqOutStream; - outStream = outStreamSpec; - return S_OK; + outStream.Create_if_Empty(); + // return S_OK; } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; +CInStream::~CInStream() +{ + unsigned i = _chunks.Size(); + while (i) + _chunks[--i].Free(); +} + static unsigned FindBlock(const CRecordVector &blocks, UInt64 pos) { unsigned left = 0, right = blocks.Size(); for (;;) { - unsigned mid = (left + right) / 2; + const unsigned mid = (left + right) / 2; if (mid == left) return left; if (pos < blocks[mid].UnpPos) @@ -1553,9 +2071,13 @@ } } -STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { - COM_TRY_BEGIN + // COM_TRY_BEGIN + try { + + if (_errorMode) + return E_OUTOFMEMORY; if (processedSize) *processedSize = 0; @@ -1564,160 +2086,176 @@ if (_virtPos >= Size) return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL; { - UInt64 rem = Size - _virtPos; + const UInt64 rem = Size - _virtPos; if (size > rem) size = (UInt32)rem; } if (_latestBlock >= 0) { - const CBlock &block = File->Blocks[_latestBlock]; - if (_virtPos < block.UnpPos || (_virtPos - block.UnpPos) >= block.UnpSize) + const CBlock &block = File->Blocks[(unsigned)_latestBlock]; + if (_virtPos < block.UnpPos || + _virtPos - block.UnpPos >= File->GetUnpackSize_of_Block((unsigned)_latestBlock)) _latestBlock = -1; } if (_latestBlock < 0) { _latestChunk = -1; - unsigned blockIndex = FindBlock(File->Blocks, _virtPos); + const unsigned blockIndex = FindBlock(File->Blocks, _virtPos); const CBlock &block = File->Blocks[blockIndex]; + const UInt64 unpSize = File->GetUnpackSize_of_Block(blockIndex); - if (!block.IsZeroMethod() && block.Type != METHOD_COPY) + if (block.NeedAllocateBuffer() + && unpSize <= k_Chunk_Size_MAX) { - unsigned i; - for (i = 0; i < _chunks.Size(); i++) - if (_chunks[i].BlockIndex == (int)blockIndex) - break; - + unsigned i = 0; + { + unsigned numChunks = _chunks.Size(); + if (numChunks) + { + const CChunk *chunk = _chunks.ConstData(); + do + { + if (chunk->BlockIndex == (int)blockIndex) + break; + chunk++; + } + while (--numChunks); + i = _chunks.Size() - numChunks; + } + } if (i != _chunks.Size()) - _latestChunk = i; + _latestChunk = (int)i; else { - const unsigned kNumChunksMax = 128; unsigned chunkIndex; - - if (_chunks.Size() != kNumChunksMax) - chunkIndex = _chunks.Add(CChunk()); - else + for (;;) { + if (_chunks.IsEmpty() || + (_chunks.Size() < k_NumChunks_MAX + && _chunks_TotalSize + unpSize <= k_Chunks_TotalSize_MAX)) + { + CChunk chunk; + chunk.Buf = NULL; + chunk.BufSize = 0; + chunk.BlockIndex = -1; + chunk.AccessMark = 0; + chunkIndex = _chunks.Add(chunk); + break; + } chunkIndex = 0; - for (i = 0; i < _chunks.Size(); i++) - if (_chunks[i].AccessMark < _chunks[chunkIndex].AccessMark) - chunkIndex = i; + if (_chunks.Size() == 1) + break; + { + const CChunk *chunks = _chunks.ConstData(); + UInt64 accessMark_min = chunks[chunkIndex].AccessMark; + const unsigned numChunks = _chunks.Size(); + for (i = 1; i < numChunks; i++) + { + if (chunks[i].AccessMark < accessMark_min) + { + chunkIndex = i; + accessMark_min = chunks[i].AccessMark; + } + } + } + { + CChunk &chunk = _chunks[chunkIndex]; + const UInt64 newTotalSize = _chunks_TotalSize - chunk.BufSize; + if (newTotalSize + unpSize <= k_Chunks_TotalSize_MAX) + break; + _chunks_TotalSize = newTotalSize; + chunk.Free(); + } + // we have called chunk.Free() before, because + // _chunks.Delete() doesn't call chunk.Free(). + _chunks.Delete(chunkIndex); + PRF(printf("\n++num_chunks=%u, _chunks_TotalSize = %u\n", (unsigned)_chunks.Size(), (unsigned)_chunks_TotalSize);) } CChunk &chunk = _chunks[chunkIndex]; chunk.BlockIndex = -1; chunk.AccessMark = 0; - if (chunk.Buf.Size() < block.UnpSize) + if (chunk.BufSize < unpSize) { - chunk.Buf.Free(); - if (block.UnpSize > ((UInt32)1 << 31)) - return E_FAIL; - chunk.Buf.Alloc((size_t)block.UnpSize); + _chunks_TotalSize -= chunk.BufSize; + chunk.Free(); + // if (unpSize > k_Chunk_Size_MAX) return E_FAIL; + chunk.Alloc((size_t)unpSize); + if (!chunk.Buf) + return E_OUTOFMEMORY; + chunk.BufSize = (size_t)unpSize; + _chunks_TotalSize += chunk.BufSize; } - outStreamSpec->Init(chunk.Buf, (size_t)block.UnpSize); - - RINOK(Stream->Seek(_startPos + File->StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(Stream, _startPos + File->StartPackPos + block.PackPos)) - limitedStreamSpec->Init(block.PackSize); - HRESULT res = S_OK; - - switch (block.Type) + inStream->Init(block.PackSize); +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + if (block.Type == METHOD_COPY) { - case METHOD_COPY: - if (block.PackSize != block.UnpSize) - return E_FAIL; - res = ReadStream_FAIL(inStream, chunk.Buf, (size_t)block.UnpSize); - break; - - case METHOD_ADC: - if (!adcCoder) - { - adcCoderSpec = new CAdcDecoder(); - adcCoder = adcCoderSpec; - } - res = adcCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, NULL); - break; - - case METHOD_ZLIB: - if (!zlibCoder) - { - zlibCoderSpec = new NCompress::NZlib::CDecoder(); - zlibCoder = zlibCoderSpec; - } - res = zlibCoder->Code(inStream, outStream, NULL, NULL, NULL); - if (res == S_OK && zlibCoderSpec->GetInputProcessedSize() != block.PackSize) - res = S_FALSE; - break; - - case METHOD_BZIP2: - if (!bzip2Coder) - { - bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - bzip2Coder = bzip2CoderSpec; - } - res = bzip2Coder->Code(inStream, outStream, NULL, NULL, NULL); - if (res == S_OK && bzip2CoderSpec->GetInputProcessedSize() != block.PackSize) - res = S_FALSE; - break; - - case METHOD_LZFSE: - if (!lzfseCoder) - { - lzfseCoderSpec = new NCompress::NLzfse::CDecoder(); - lzfseCoder = lzfseCoderSpec; - } - res = lzfseCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, NULL); - break; - - default: + if (block.PackSize != unpSize) return E_FAIL; + RINOK(ReadStream_FAIL(inStream, chunk.Buf, (size_t)unpSize)) } - - if (res != S_OK) - return res; - if (block.Type != METHOD_COPY && outStreamSpec->GetPos() != block.UnpSize) - return E_FAIL; - chunk.BlockIndex = blockIndex; - _latestChunk = chunkIndex; + else +#endif + { + outStream->Init(chunk.Buf, (size_t)unpSize); + RINOK(decoders.Code(inStream, outStream, block, &unpSize, NULL)) + if (outStream->GetPos() != unpSize) + return E_FAIL; + } + chunk.BlockIndex = (int)blockIndex; + _latestChunk = (int)chunkIndex; } _chunks[_latestChunk].AccessMark = _accessMark++; } - _latestBlock = blockIndex; + _latestBlock = (int)blockIndex; } - const CBlock &block = File->Blocks[_latestBlock]; + const CBlock &block = File->Blocks[(unsigned)_latestBlock]; const UInt64 offset = _virtPos - block.UnpPos; - const UInt64 rem = block.UnpSize - offset; - if (size > rem) - size = (UInt32)rem; - + { + const UInt64 rem = File->GetUnpackSize_of_Block((unsigned)_latestBlock) - offset; + if (size > rem) + size = (UInt32)rem; + if (size == 0) // it's unexpected case. but we check it. + return S_OK; + } HRESULT res = S_OK; - if (block.Type == METHOD_COPY) + if (block.IsZeroMethod()) + memset(data, 0, size); + else if (_latestChunk >= 0) + memcpy(data, _chunks[_latestChunk].Buf + (size_t)offset, size); + else { - RINOK(Stream->Seek(_startPos + File->StartPos + block.PackPos + offset, STREAM_SEEK_SET, NULL)); + if (block.Type != METHOD_COPY) + return E_FAIL; + RINOK(InStream_SeekSet(Stream, _startPos + File->StartPackPos + block.PackPos + offset)) res = Stream->Read(data, size, &size); } - else if (block.IsZeroMethod()) - memset(data, 0, size); - else if (size != 0) - memcpy(data, _chunks[_latestChunk].Buf + (size_t)offset, size); _virtPos += size; if (processedSize) *processedSize = size; - return res; - COM_TRY_END + // COM_TRY_END + } + catch(...) + { + _errorMode = true; + return E_OUTOFMEMORY; + } } + -STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -1728,39 +2266,49 @@ } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - #ifdef DMG_SHOW_RAW - if (index >= (UInt32)_files.Size()) +#ifdef DMG_SHOW_RAW + if (index >= _files.Size()) return S_FALSE; - #endif +#endif - CInStream *spec = new CInStream; - CMyComPtr specStream = spec; + CMyComPtr2 spec; + spec.Create_if_Empty(); spec->File = &_files[index]; const CFile &file = *spec->File; + + if (!file.IsCorrect) + return S_FALSE; FOR_VECTOR (i, file.Blocks) { const CBlock &block = file.Blocks[i]; + if (!block.NeedAllocateBuffer()) + continue; + switch (block.Type) { - case METHOD_ZERO_0: - case METHOD_ZERO_2: +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS case METHOD_COPY: + break; +#endif case METHOD_ADC: case METHOD_ZLIB: case METHOD_BZIP2: case METHOD_LZFSE: - case METHOD_END: + case METHOD_XZ: + // case METHOD_END: + if (file.GetUnpackSize_of_Block(i) > k_Chunk_Size_MAX) + return S_FALSE; break; default: return S_FALSE; @@ -1769,15 +2317,16 @@ spec->Stream = _inStream; spec->Size = spec->File->Size; - RINOK(spec->InitAndSeek(_startPos + _dataStartOffset)); - *stream = specStream.Detach(); + // RINOK( + spec->Init(_startPos + _dataForkPair.Offset); + *stream = spec.Detach(); return S_OK; COM_TRY_END } REGISTER_ARC_I( - "Dmg", "dmg", 0, 0xE4, + "Dmg", "dmg", NULL, 0xE4, k_Signature, 0, NArcInfoFlags::kBackwardOpen | diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ElfHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ElfHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ElfHandler.cpp 2021-01-26 09:45:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ElfHandler.cpp 2024-06-28 07:00:00.000000000 +0000 @@ -17,11 +17,13 @@ #include "../Compress/CopyCoder.h" +// #define Z7_ELF_SHOW_DETAILS + using namespace NWindows; -static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); } -static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } -static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); } +static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16a(p); return GetUi16a(p); } +static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32a(p); return GetUi32a(p); } +static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64a(p); return GetUi64a(p); } #define G16(offs, v) v = Get16(p + (offs), be) #define G32(offs, v) v = Get32(p + (offs), be) @@ -31,14 +33,51 @@ namespace NElf { /* - ELF Structure for most files (real order can be different): - Header - Program (segment) header table (used at runtime) - Segment1 (Section ... Section) - Segment2 - ... - SegmentN - Section header table (the data for linking and relocation) +ELF Structure example: +{ + Header + Program header table (is used at runtime) (list of segment metadata records) + { + Segment (Read) + Segment : PT_PHDR : header table itself + Segment : PT_INTERP + Segment : PT_NOTE + .rela.dyn (RELA, ALLOC) + Segment (Execute/Read) + .text section (PROGBITS, SHF_ALLOC | SHF_EXECINSTR) + Segment (Read) + .rodata (PROGBITS, SHF_ALLOC | SHF_WRITE) + Segment : PT_GNU_EH_FRAME + .eh_frame_hdr + .eh_frame + .gcc_except_table + ... + Segment (Write/Read) (VaSize > Size) + Segment (Read) : PT_GNU_RELRO + Segment (Write/Read) + .data + .bss (Size == 0) (VSize != 0) + } + .comment (VA == 0) + .shstrtab (VA == 0) + Section header table (the data for linking and relocation) +} + + Last top level segment contains .bss section that requires additional VA space. + So (VaSize > Size) for that segment. + + Segments can be unsorted (by offset) in table. + Top level segments has Type=PT_LOAD : "Loadable segment". + Top level segments usually are aligned for page size (4 KB). + Another segments (non PT_LOAD segments) are inside PT_LOAD segments. + + (VA-offset == 0) is possible for some sections and segments at the beginning of file. + (VA-offset == 4KB*N) for most sections and segments where (Size != 0), + (VA-offset != 4KB*N) for .bss section (last section), because (Size == 0), + and that section is not mapped from image file. + Some files contain additional "virtual" 4 KB page in VA space after + end of data of top level segments (PT_LOAD) before new top level segments. + So (VA-offset) value can increase by 4 KB step. */ #define ELF_CLASS_32 1 @@ -47,14 +86,14 @@ #define ELF_DATA_2LSB 1 #define ELF_DATA_2MSB 2 -static const UInt32 kHeaderSize32 = 0x34; -static const UInt32 kHeaderSize64 = 0x40; +static const unsigned kHeaderSize32 = 0x34; +static const unsigned kHeaderSize64 = 0x40; -static const UInt32 kSegmentSize32 = 0x20; -static const UInt32 kSegmentSize64 = 0x38; +static const unsigned kSegmentSize32 = 0x20; +static const unsigned kSegmentSize64 = 0x38; -static const UInt32 kSectionSize32 = 0x28; -static const UInt32 kSectionSize64 = 0x40; +static const unsigned kSectionSize32 = 0x28; +static const unsigned kSectionSize64 = 0x40; struct CHeader { @@ -78,9 +117,9 @@ UInt16 NumSections; UInt16 NamesSectIndex; - bool Parse(const Byte *buf); + bool Parse(const Byte *p); - UInt64 GetHeadersSize() const { return (UInt64)HeaderSize + + UInt32 GetHeadersSize() const { return (UInt32)HeaderSize + (UInt32)NumSegments * SegmentEntrySize + (UInt32)NumSections * SectionEntrySize; } }; @@ -104,7 +143,7 @@ if (p[6] != 1) // Version return false; Os = p[7]; - AbiVer = p[8]; + // AbiVer = p[8]; for (int i = 9; i < 16; i++) if (p[i] != 0) return false; @@ -117,16 +156,21 @@ if (Mode64) { // G64(0x18, EntryVa); - G64(0x20, ProgOffset); + G64(0x20, ProgOffset); // == kHeaderSize64 == 0x40 usually G64(0x28, SectOffset); p += 0x30; + // we expect that fields are aligned + if (ProgOffset & 7) return false; + if (SectOffset & 7) return false; } else { // G32(0x18, EntryVa); - G32(0x1C, ProgOffset); + G32(0x1C, ProgOffset); // == kHeaderSize32 == 0x34 usually G32(0x20, SectOffset); p += 0x24; + if (ProgOffset & 3) return false; + if (SectOffset & 3) return false; } G32(0, Flags); @@ -140,34 +184,38 @@ G16(12, NumSections); G16(14, NamesSectIndex); - if (ProgOffset < HeaderSize && (ProgOffset != 0 || NumSegments != 0)) return false; - if (SectOffset < HeaderSize && (SectOffset != 0 || NumSections != 0)) return false; + if (ProgOffset < HeaderSize && (ProgOffset || NumSegments)) return false; + if (SectOffset < HeaderSize && (SectOffset || NumSections)) return false; - if (SegmentEntrySize == 0) { if (NumSegments != 0) return false; } + if (SegmentEntrySize == 0) { if (NumSegments) return false; } else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false; - if (SectionEntrySize == 0) { if (NumSections != 0) return false; } + if (SectionEntrySize == 0) { if (NumSections) return false; } else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false; return true; } -// The program header table itself. -#define PT_PHDR 6 +#define PT_PHDR 6 // The program header table itself. +#define PT_GNU_STACK 0x6474e551 -static const char * const g_SegnmentTypes[] = +static const CUInt32PCharPair g_SegnmentTypes[] = { - "Unused" - , "Loadable segment" - , "Dynamic linking tables" - , "Program interpreter path name" - , "Note section" - , "SHLIB" - , "Program header table" - , "TLS" + { 0, "Unused" }, + { 1, "Loadable segment" }, + { 2, "Dynamic linking tables" }, + { 3, "Program interpreter path name" }, + { 4, "Note section" }, + { 5, "SHLIB" }, + { 6, "Program header table" }, + { 7, "TLS" }, + { 0x6474e550, "GNU_EH_FRAME" }, + { PT_GNU_STACK, "GNU_STACK" }, + { 0x6474e552, "GNU_RELRO" } }; + static const char * const g_SegmentFlags[] = { "Execute" @@ -181,16 +229,18 @@ UInt32 Flags; UInt64 Offset; UInt64 Va; - // UInt64 Pa; - UInt64 Size; - UInt64 VSize; - UInt64 Align; - + UInt64 Size; // size in file + UInt64 VSize; // size in memory +#ifdef Z7_ELF_SHOW_DETAILS + UInt64 Pa; // usually == Va, or == 0 + UInt64 Align; // if (Align != 0), condition must be met: + // (VSize % Align == Offset % Alig) +#endif void UpdateTotalSize(UInt64 &totalSize) { - UInt64 t = Offset + Size; + const UInt64 t = Offset + Size; if (totalSize < t) - totalSize = t; + totalSize = t; } void Parse(const Byte *p, bool mode64, bool be); }; @@ -203,20 +253,24 @@ G32(4, Flags); G64(8, Offset); G64(0x10, Va); - // G64(0x18, Pa); G64(0x20, Size); G64(0x28, VSize); +#ifdef Z7_ELF_SHOW_DETAILS + G64(0x18, Pa); G64(0x30, Align); +#endif } else { G32(4, Offset); G32(8, Va); - // G32(0x0C, Pa); G32(0x10, Size); G32(0x14, VSize); G32(0x18, Flags); +#ifdef Z7_ELF_SHOW_DETAILS + G32(0x0C, Pa); G32(0x1C, Align); +#endif } } @@ -271,6 +325,7 @@ { 16, "PREINIT_ARRAY" }, { 17, "GROUP" }, { 18, "SYMTAB_SHNDX" }, + { 0x6ffffff5, "GNU_ATTRIBUTES" }, { 0x6ffffff6, "GNU_HASH" }, { 0x6ffffffd, "GNU_verdef" }, @@ -284,6 +339,8 @@ { 0x70000005, "ARM_OVERLAYSECTION" } }; + +// SHF_ flags static const CUInt32PCharPair g_SectionFlags[] = { { 0, "WRITE" }, @@ -297,7 +354,7 @@ { 8, "OS_NONCONFORMING" }, { 9, "GROUP" }, { 10, "TLS" }, - { 11, "CP_SECTION" }, + { 11, "COMPRESSED" }, { 12, "DP_SECTION" }, { 13, "XCORE_SHF_CP_SECTION" }, { 28, "64_LARGE" }, @@ -320,9 +377,9 @@ void UpdateTotalSize(UInt64 &totalSize) { - UInt64 t = Offset + GetSize(); + const UInt64 t = Offset + GetSize(); if (totalSize < t) - totalSize = t; + totalSize = t; } bool Parse(const Byte *p, bool mode64, bool be); }; @@ -406,7 +463,7 @@ , "TRW RH-32" , "Motorola RCE" , "ARM" - , "Alpha" + , "Alpha-STD" , "Hitachi SH" , "SPARC-V9" , "Siemens Tricore" @@ -571,8 +628,9 @@ static const CUInt32PCharPair g_MachinePairs[] = { { 243, "RISC-V" }, - { 47787, "Xilinx MicroBlaze" } - // { 0x9026, "Alpha" } + { 258, "LoongArch" }, + { 0x9026, "Alpha" }, // EM_ALPHA_EXP, obsolete, (used by NetBSD/alpha) (written in the absence of an ABI) + { 0xbaab, "Xilinx MicroBlaze" } }; static const CUInt32PCharPair g_OS[] = @@ -594,6 +652,8 @@ { 14, "HP NSK" }, { 15, "AROS" }, { 16, "FenixOS" }, + { 17, "CloudABI" }, + { 18, "OpenVOS" }, { 64, "Bare-metal TMS320C6000" }, { 65, "Linux TMS320C6000" }, { 97, "ARM" }, @@ -602,6 +662,7 @@ #define k_Machine_MIPS 8 #define k_Machine_ARM 40 +#define k_Machine_RISCV 243 /* #define EF_ARM_ABIMASK 0xFF000000 @@ -635,6 +696,15 @@ { 27, "MDMX" } }; +static const char * const g_RISCV_Flags[] = +{ + "RVC", + NULL, + NULL, + "RVE", + "TSO" +}; + // #define ET_NONE 0 #define ET_REL 1 @@ -654,11 +724,9 @@ -class CHandler: - public IInArchive, - public IArchiveAllowTail, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveAllowTail +) CRecordVector _segments; CRecordVector _sections; CByteBuffer _namesData; @@ -667,37 +735,39 @@ CHeader _header; bool _headersError; bool _allowTail; + bool _stackFlags_Defined; + UInt32 _stackFlags; void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const; HRESULT Open2(IInStream *stream); public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(AllowTail)(Int32 allowTail); - CHandler(): _allowTail(false) {} }; void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const { if (index >= _sections.Size()) - return; - const CSection §ion = _sections[index]; - UInt32 offset = section.Name; - if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */) - { - if (showNULL) - prop = "NULL"; - return; - } - const Byte *p = _namesData; - size_t size = _namesData.Size(); - for (size_t i = offset; i < size; i++) - if (p[i] == 0) + prop = index; // it's possible for some file, but maybe it's ERROR case + else + { + const CSection §ion = _sections[index]; + const UInt32 offset = section.Name; + if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */) { - prop = (const char *)(p + offset); + if (showNULL) + prop = "NULL"; return; } + const Byte *p = _namesData; + const size_t size = _namesData.Size(); + for (size_t i = offset; i < size; i++) + if (p[i] == 0) + { + prop = (const char *)(p + offset); + return; + } + prop = "ERROR"; + } } static const Byte kArcProps[] = @@ -707,13 +777,21 @@ kpidBigEndian, kpidHostOS, kpidCharacts, + kpidComment, kpidHeadersSize }; enum { kpidLinkSection = kpidUserDefined, - kpidInfoSection + kpidInfoSection, + kpidEntrySize +#ifdef Z7_ELF_SHOW_DETAILS + // , kpidAlign + , kpidPa + , kpidDelta + , kpidOffsetEnd +#endif }; static const CStatProp kProps[] = @@ -725,6 +803,14 @@ { NULL, kpidVa, VT_UI8 }, { NULL, kpidType, VT_BSTR }, { NULL, kpidCharacts, VT_BSTR } +#ifdef Z7_ELF_SHOW_DETAILS + // , { "Align", kpidAlign, VT_UI8 } + , { NULL, kpidClusterSize, VT_UI8 } + , { "PA", kpidPa, VT_UI8 } + , { "End offset", kpidOffsetEnd, VT_UI8 } + , { "Delta (VA-Offset)", kpidDelta, VT_UI8 } +#endif + , { "Entry Size", kpidEntrySize, VT_UI8} , { "Link Section", kpidLinkSection, VT_BSTR} , { "Info Section", kpidInfoSection, VT_BSTR} }; @@ -732,7 +818,7 @@ IMP_IInArchive_Props_WITH_NAME IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -747,42 +833,82 @@ case kpidCpu: { AString s; - if (_header.Machine < ARRAY_SIZE(g_Machines)) + if (_header.Machine < Z7_ARRAY_SIZE(g_Machines)) { const char *name = g_Machines[_header.Machine]; if (name) s = name; } if (s.IsEmpty()) - s = TypePairToString(g_MachinePairs, ARRAY_SIZE(g_MachinePairs), _header.Machine); + s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine); UInt32 flags = _header.Flags; - if (flags != 0) + if (flags) { s.Add_Space(); if (_header.Machine == k_Machine_ARM) { - s += FlagsToString(g_ARM_Flags, ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1)); + s += FlagsToString(g_ARM_Flags, Z7_ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1)); s += " ABI:"; s.Add_UInt32(flags >> 24); } else if (_header.Machine == k_Machine_MIPS) { - UInt32 ver = flags >> 28; - s += "v"; + const UInt32 ver = flags >> 28; + s.Add_Char('v'); s.Add_UInt32(ver); - flags &= (((UInt32)1 << 28) - 1); - - UInt32 abi = (flags >> 12) & 7; - if (abi != 0) + flags &= ((UInt32)1 << 28) - 1; + const UInt32 abi = (flags >> 12) & 7; + if (abi) { s += " ABI:"; s.Add_UInt32(abi); } flags &= ~((UInt32)7 << 12); - s.Add_Space(); - s += FlagsToString(g_MIPS_Flags, ARRAY_SIZE(g_MIPS_Flags), flags); + s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags); } + else if (_header.Machine == k_Machine_RISCV) + { + s += "FLOAT_"; + const UInt32 fl = (flags >> 1) & 3; + /* + static const char * const g_RISCV_Flags_Float[] = + { "SOFT", "SINGLE", "DOUBLE", "QUAD" }; + s += g_RISCV_Flags_Float[fl]; + */ + if (fl) + s.Add_UInt32(16u << fl); + else + s += "SOFT"; + s.Add_Space(); + flags &= ~(UInt32)6; + s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags); + } +#if 0 +#define k_Machine_LOONGARCH 258 + else if (_header.Machine == k_Machine_LOONGARCH) + { + s += "ABI:"; + s.Add_UInt32((flags >> 6) & 3); + s.Add_Dot(); + s.Add_UInt32((flags >> 3) & 7); + s.Add_Dot(); +#if 1 + s.Add_UInt32(flags & 7); +#else + static const char k_LoongArch_Float_Type[8] = { '0', 's', 'f', 'd', '4' ,'5', '6', '7' }; + s.Add_Char(k_LoongArch_Float_Type[flags & 7]); +#endif + flags &= ~(UInt32)0xff; + if (flags) + { + s.Add_Colon(); + char sz[16]; + ConvertUInt32ToHex(flags, sz); + s += sz; + } + } +#endif else { char sz[16]; @@ -796,6 +922,40 @@ case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break; case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; + case kpidComment: + { + AString s; + if (_stackFlags_Defined) + { + s += "STACK: "; + s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags); + s.Add_LF(); + /* + if (_header.EntryVa) + { + s += "Entry point: 0x"; + char temp[16 + 4]; + ConvertUInt64ToHex(_header.EntryVa, temp); + s += temp; + s.Add_LF(); + } + */ + } + if (_header.NumSegments) + { + s += "Segments: "; + s.Add_UInt32(_header.NumSegments); + s.Add_LF(); + } + if (_header.NumSections) + { + s += "Sections: "; + s.Add_UInt32(_header.NumSections); + s.Add_LF(); + } + prop = s; + break; + } case kpidExtension: { const char *s = NULL; @@ -822,7 +982,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -840,12 +1000,17 @@ } case kpidOffset: prop = item.Offset; break; case kpidVa: prop = item.Va; break; +#ifdef Z7_ELF_SHOW_DETAILS + case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break; + case kpidOffsetEnd: prop = item.Offset + item.Size; break; + case kpidPa: prop = item.Pa; break; + case kpidClusterSize: prop = item.Align; break; +#endif case kpidSize: case kpidPackSize: prop = (UInt64)item.Size; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break; - case kpidType: TYPE_TO_PROP(g_SegnmentTypes, item.Type, prop); break; + case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break; case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break; - } } else @@ -857,13 +1022,19 @@ case kpidPath: GetSectionName(index, prop, true); break; case kpidOffset: prop = item.Offset; break; case kpidVa: prop = item.Va; break; +#ifdef Z7_ELF_SHOW_DETAILS + case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break; + case kpidOffsetEnd: prop = item.Offset + item.GetSize(); break; +#endif case kpidSize: case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break; case kpidVirtualSize: prop = item.GetSize(); break; case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break; case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break; + // case kpidAlign: prop = item.Align; break; case kpidLinkSection: GetSectionName(item.Link, prop, false); break; case kpidInfoSection: GetSectionName(item.Info, prop, false); break; + case kpidEntrySize: prop = (UInt64)item.EntSize; break; } } prop.Detach(value); @@ -873,71 +1044,79 @@ HRESULT CHandler::Open2(IInStream *stream) { - const UInt32 kStartSize = kHeaderSize64; - Byte h[kStartSize]; - RINOK(ReadStream_FALSE(stream, h, kStartSize)); - if (h[0] != 0x7F || h[1] != 'E' || h[2] != 'L' || h[3] != 'F') - return S_FALSE; - if (!_header.Parse(h)) - return S_FALSE; + { + const UInt32 kStartSize = kHeaderSize64; + UInt64 h64[kStartSize / 8]; + RINOK(ReadStream_FALSE(stream, h64, kStartSize)) + const Byte *h = (const Byte *)(const void *)h64; + if (GetUi32a(h) != 0x464c457f) + return S_FALSE; + if (!_header.Parse(h)) + return S_FALSE; + } _totalSize = _header.HeaderSize; bool addSegments = false; bool addSections = false; - - if (_header.NumSections > 1) + // first section usually is NULL (with zero offsets and zero sizes). + if (_header.NumSegments == 0 || _header.NumSections > 1) addSections = true; else addSegments = true; +#ifdef Z7_ELF_SHOW_DETAILS + addSections = true; + addSegments = true; +#endif - if (_header.NumSegments != 0) + if (_header.NumSegments) { if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE; - RINOK(stream->Seek(_header.ProgOffset, STREAM_SEEK_SET, NULL)); - size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments; - + RINOK(InStream_SeekSet(stream, _header.ProgOffset)) + const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments; CByteArr buf(size); - - RINOK(ReadStream_FALSE(stream, buf, size)); - - UInt64 total = _header.ProgOffset + size; - if (_totalSize < total) - _totalSize = total; - - const Byte *p = buf; - + RINOK(ReadStream_FALSE(stream, buf, size)) + { + const UInt64 total = _header.ProgOffset + size; + if (_totalSize < total) + _totalSize = total; + } if (addSegments) _segments.ClearAndReserve(_header.NumSegments); + const Byte *p = buf; for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize) { CSegment seg; seg.Parse(p, _header.Mode64, _header.Be); seg.UpdateTotalSize(_totalSize); - if (addSegments) - if (seg.Type != PT_PHDR) - _segments.AddInReserved(seg); + if (seg.Type == PT_GNU_STACK && !_stackFlags_Defined) + { + _stackFlags = seg.Flags; + _stackFlags_Defined = true; + } + if (addSegments + // we don't show program header table segment + && seg.Type != PT_PHDR + ) + _segments.AddInReserved(seg); } } - if (_header.NumSections != 0) + if (_header.NumSections) { if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE; - RINOK(stream->Seek(_header.SectOffset, STREAM_SEEK_SET, NULL)); - size_t size = (size_t)_header.SectionEntrySize * _header.NumSections; - + RINOK(InStream_SeekSet(stream, _header.SectOffset)) + const size_t size = (size_t)_header.SectionEntrySize * _header.NumSections; CByteArr buf(size); - - RINOK(ReadStream_FALSE(stream, buf, size)); - - UInt64 total = _header.SectOffset + size; - if (_totalSize < total) - _totalSize = total; - - const Byte *p = buf; - + RINOK(ReadStream_FALSE(stream, buf, size)) + { + const UInt64 total = _header.SectOffset + size; + if (_totalSize < total) + _totalSize = total; + } if (addSections) _sections.ClearAndReserve(_header.NumSections); + const Byte *p = buf; for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize) { CSection sect; @@ -957,19 +1136,18 @@ if (_header.NamesSectIndex < _sections.Size()) { const CSection § = _sections[_header.NamesSectIndex]; - UInt64 size = sect.GetSize(); - if (size != 0 - && size < ((UInt64)1 << 31) - && (Int64)sect.Offset >= 0) + const UInt64 size = sect.GetSize(); + if (size && size < ((UInt64)1 << 31) + && (Int64)sect.Offset >= 0) { _namesData.Alloc((size_t)size); - RINOK(stream->Seek(sect.Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size)); + RINOK(InStream_SeekSet(stream, sect.Offset)) + RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size)) } } - /* - // we will not delete NULL sections, since we have links to section via indexes + // we cannot delete "NULL" sections, + // because we have links to sections array via indexes for (int i = _sections.Size() - 1; i >= 0; i--) if (_sections[i].Type == SHT_NULL) _items.Delete(i); @@ -979,7 +1157,7 @@ if (!_allowTail) { UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) if (fileSize > _totalSize) return S_FALSE; } @@ -987,22 +1165,23 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - RINOK(Open2(inStream)); + RINOK(Open2(inStream)) _inStream = inStream; return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _headersError = false; + _stackFlags_Defined = false; _inStream.Release(); _segments.Clear(); @@ -1011,17 +1190,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _segments.Size() + _sections.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _segments.Size() + _sections.Size(); if (numItems == 0) @@ -1030,35 +1209,32 @@ UInt32 i; for (i = 0; i < numItems; i++) { - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; totalSize += (index < _segments.Size()) ? _segments[index].Size : _sections[index - _segments.Size()].GetSize(); } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) - UInt64 currentTotalSize = 0; + totalSize = 0; UInt64 currentItemSize; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_inStream); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? + for (i = 0;; i++, totalSize += currentItemSize) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; UInt64 offset; if (index < _segments.Size()) { @@ -1072,26 +1248,25 @@ currentItemSize = item.GetSize(); offset = item.Offset; } - - CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? + { + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_inStream, offset)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + } + RINOK(extractCallback->SetOperationResult(copyCoder->TotalSize == currentItemSize ? NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) { _allowTail = IntToBool(allowTail); return S_OK; @@ -1100,7 +1275,7 @@ static const Byte k_Signature[] = { 0x7F, 'E', 'L', 'F' }; REGISTER_ARC_I( - "ELF", "elf", 0, 0xDE, + "ELF", "elf", NULL, 0xDE, k_Signature, 0, NArcInfoFlags::kPreArc, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ExtHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ExtHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ExtHandler.cpp 2022-04-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ExtHandler.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -20,6 +20,7 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" #include "../../Common/MyLinux.h" #include "../../Common/StringConvert.h" #include "../../Common/UTFConvert.h" @@ -240,15 +241,6 @@ }; -static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } - -static inline void PrintHex(unsigned v, char *s) -{ - s[0] = GetHex((v >> 4) & 0xF); - s[1] = GetHex(v & 0xF); -} - - enum { k_Type_UNKNOWN, @@ -353,7 +345,7 @@ { for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == num) - return i; + return (int)i; return -1; } @@ -371,8 +363,8 @@ if (GetUi16(p + 0x38) != 0xEF53) return false; - LE_32 (0x18, BlockBits); - LE_32 (0x1C, ClusterBits); + LE_32 (0x18, BlockBits) + LE_32 (0x1C, ClusterBits) if (ClusterBits != 0 && BlockBits != ClusterBits) return false; @@ -381,22 +373,22 @@ return false; BlockBits += 10; - LE_32 (0x00, NumInodes); - LE_32 (0x04, NumBlocks); + LE_32 (0x00, NumInodes) + LE_32 (0x04, NumBlocks) // LE_32 (0x08, NumBlocksSuper); - LE_32 (0x0C, NumFreeBlocks); - LE_32 (0x10, NumFreeInodes); + LE_32 (0x0C, NumFreeBlocks) + LE_32 (0x10, NumFreeInodes) if (NumInodes < 2 || NumInodes <= NumFreeInodes) return false; UInt32 FirstDataBlock; - LE_32 (0x14, FirstDataBlock); + LE_32 (0x14, FirstDataBlock) if (FirstDataBlock != (unsigned)(BlockBits == 10 ? 1 : 0)) return false; - LE_32 (0x20, BlocksPerGroup); - LE_32 (0x24, ClustersPerGroup); + LE_32 (0x20, BlocksPerGroup) + LE_32 (0x24, ClustersPerGroup) if (BlocksPerGroup != ClustersPerGroup) return false; @@ -408,13 +400,13 @@ // return false; } - LE_32 (0x28, InodesPerGroup); + LE_32 (0x28, InodesPerGroup) if (InodesPerGroup < 1 || InodesPerGroup > NumInodes) return false; - LE_32 (0x2C, MountTime); - LE_32 (0x30, WriteTime); + LE_32 (0x2C, MountTime) + LE_32 (0x30, WriteTime) // LE_16 (0x34, NumMounts); // LE_16 (0x36, NumMountsMax); @@ -423,10 +415,10 @@ // LE_16 (0x3C, Errors); // LE_16 (0x3E, MinorRevLevel); - LE_32 (0x40, LastCheckTime); + LE_32 (0x40, LastCheckTime) // LE_32 (0x44, CheckInterval); - LE_32 (0x48, CreatorOs); - LE_32 (0x4C, RevLevel); + LE_32 (0x48, CreatorOs) + LE_32 (0x4C, RevLevel) // LE_16 (0x50, DefResUid); // LE_16 (0x52, DefResGid); @@ -436,8 +428,8 @@ if (!IsOldRev()) { - LE_32 (0x54, FirstInode); - LE_16 (0x58, InodeSize); + LE_32 (0x54, FirstInode) + LE_16 (0x58, InodeSize) if (FirstInode < k_INODE_GOOD_OLD_FIRST) return false; if (InodeSize > ((UInt32)1 << BlockBits) @@ -446,10 +438,10 @@ return false; } - LE_16 (0x5A, BlockGroupNr); - LE_32 (0x5C, FeatureCompat); - LE_32 (0x60, FeatureIncompat); - LE_32 (0x64, FeatureRoCompat); + LE_16 (0x5A, BlockGroupNr) + LE_32 (0x5C, FeatureCompat) + LE_32 (0x60, FeatureIncompat) + LE_32 (0x64, FeatureRoCompat) memcpy(Uuid, p + 0x68, sizeof(Uuid)); memcpy(VolName, p + 0x78, sizeof(VolName)); @@ -457,24 +449,24 @@ // LE_32 (0xC8, BitmapAlgo); - LE_32 (0xE0, JournalInode); + LE_32 (0xE0, JournalInode) - LE_16 (0xFE, GdSize); + LE_16 (0xFE, GdSize) - LE_32 (0x108, CTime); + LE_32 (0x108, CTime) if (Is64Bit()) { - HI_32(0x150, NumBlocks); + HI_32(0x150, NumBlocks) // HI_32(0x154, NumBlocksSuper); - HI_32(0x158, NumFreeBlocks); + HI_32(0x158, NumFreeBlocks) } if (NumBlocks >= (UInt64)1 << (63 - BlockBits)) return false; - LE_16(0x15C, MinExtraISize); + LE_16(0x15C, MinExtraISize) // LE_16(0x15E, WantExtraISize); // LE_32(0x160, Flags); // LE_16(0x164, RaidStride); @@ -484,7 +476,7 @@ // LogGroupsPerFlex = p[0x174]; // ChecksumType = p[0x175]; - LE_64 (0x178, WrittenKB); + LE_64 (0x178, WrittenKB) // LE_32(0x194, ErrorCount); // LE_32(0x198, ErrorTime); @@ -525,32 +517,32 @@ void CGroupDescriptor::Parse(const Byte *p, unsigned size) { - LE_32 (0x00, BlockBitmap); - LE_32 (0x04, InodeBitmap); - LE_32 (0x08, InodeTable); - LE_16 (0x0C, NumFreeBlocks); - LE_16 (0x0E, NumFreeInodes); - LE_16 (0x10, DirCount); - LE_16 (0x12, Flags); - LE_32 (0x14, ExcludeBitmap); - LE_16 (0x18, BlockBitmap_Checksum); - LE_16 (0x1A, InodeBitmap_Checksum); - LE_16 (0x1C, UnusedCount); - LE_16 (0x1E, Checksum); + LE_32 (0x00, BlockBitmap) + LE_32 (0x04, InodeBitmap) + LE_32 (0x08, InodeTable) + LE_16 (0x0C, NumFreeBlocks) + LE_16 (0x0E, NumFreeInodes) + LE_16 (0x10, DirCount) + LE_16 (0x12, Flags) + LE_32 (0x14, ExcludeBitmap) + LE_16 (0x18, BlockBitmap_Checksum) + LE_16 (0x1A, InodeBitmap_Checksum) + LE_16 (0x1C, UnusedCount) + LE_16 (0x1E, Checksum) if (size >= 64) { p += 0x20; - HI_32 (0x00, BlockBitmap); - HI_32 (0x04, InodeBitmap); - HI_32 (0x08, InodeTable); - HI_16 (0x0C, NumFreeBlocks); - HI_16 (0x0E, NumFreeInodes); - HI_16 (0x10, DirCount); - HI_16 (0x12, UnusedCount); // instead of Flags - HI_32 (0x14, ExcludeBitmap); - HI_16 (0x18, BlockBitmap_Checksum); - HI_16 (0x1A, InodeBitmap_Checksum); + HI_32 (0x00, BlockBitmap) + HI_32 (0x04, InodeBitmap) + HI_32 (0x08, InodeTable) + HI_16 (0x0C, NumFreeBlocks) + HI_16 (0x0E, NumFreeInodes) + HI_16 (0x10, DirCount) + HI_16 (0x12, UnusedCount) // instead of Flags + HI_32 (0x14, ExcludeBitmap) + HI_16 (0x18, BlockBitmap_Checksum) + HI_16 (0x1A, InodeBitmap_Checksum) // HI_16 (0x1C, Reserved); } } @@ -567,9 +559,9 @@ bool Parse(const Byte *p) { - LE_16 (0x02, NumEntries); - LE_16 (0x04, MaxEntries); - LE_16 (0x06, Depth); + LE_16 (0x02, NumEntries) + LE_16 (0x04, MaxEntries) + LE_16 (0x06, Depth) // LE_32 (0x08, Generation); return Get16(p) == 0xF30A; // magic } @@ -582,8 +574,8 @@ void Parse(const Byte *p) { - LE_32 (0x00, VirtBlock); - LE_32 (0x04, PhyLeaf); + LE_32 (0x00, VirtBlock) + LE_32 (0x04, PhyLeaf) PhyLeaf |= (((UInt64)Get16(p + 8)) << 32); // unused 16-bit field (at offset 0x0A) can be not zero in some cases. Why? } @@ -601,17 +593,17 @@ void Parse(const Byte *p) { - LE_32 (0x00, VirtBlock); - LE_16 (0x04, Len); + LE_32 (0x00, VirtBlock) + LE_16 (0x04, Len) IsInited = true; if (Len > (UInt32)0x8000) { IsInited = false; Len = (UInt16)(Len - (UInt32)0x8000); } - LE_32 (0x08, PhyStart); + LE_32 (0x08, PhyStart) UInt16 hi; - LE_16 (0x06, hi); + LE_16 (0x06, hi) PhyStart |= ((UInt64)hi << 32); } }; @@ -627,7 +619,7 @@ struct CNode { Int32 ParentNode; // in _refs[], -1 if not dir - int ItemIndex; // in _items[] + int ItemIndex; // in _items[] , (set as >=0 only for if (IsDir()) int SymLinkIndex; // in _symLinks[] int DirIndex; // in _dirs[] @@ -655,7 +647,7 @@ ParentNode(-1), ItemIndex(-1), SymLinkIndex(-1), - DirIndex(0), + DirIndex(-1), NumLinksCalced(0) {} @@ -679,18 +671,18 @@ ChangeTime.Extra = 0; // DTime.Extra = 0; - LE_16 (0x00, Mode); - LE_16 (0x02, Uid); - LE_32 (0x04, FileSize); - LE_32 (0x08, ATime.Val); - LE_32 (0x0C, ChangeTime.Val); - LE_32 (0x10, MTime.Val); + LE_16 (0x00, Mode) + LE_16 (0x02, Uid) + LE_32 (0x04, FileSize) + LE_32 (0x08, ATime.Val) + LE_32 (0x0C, ChangeTime.Val) + LE_32 (0x10, MTime.Val) // LE_32 (0x14, DTime.Val); - LE_16 (0x18, Gid); - LE_16 (0x1A, NumLinks); + LE_16 (0x18, Gid) + LE_16 (0x1A, NumLinks) - LE_32 (0x1C, NumBlocks); - LE_32 (0x20, Flags); + LE_32 (0x1C, NumBlocks) + LE_32 (0x20, Flags) // LE_32 (0x24, Union osd1); memcpy(Block, p + 0x28, kNodeBlockFieldSize); @@ -700,7 +692,7 @@ { UInt32 highSize; - LE_32 (0x6C, highSize); // In ext2/3 this field was named i_dir_acl + LE_32 (0x6C, highSize) // In ext2/3 this field was named i_dir_acl if (IsRegular()) // do we need that check ? FileSize |= ((UInt64)highSize << 32); @@ -718,11 +710,11 @@ // ext4: UInt32 numBlocksHigh; - LE_16 (0x74, numBlocksHigh); + LE_16 (0x74, numBlocksHigh) NumBlocks |= (UInt64)numBlocksHigh << 32; - HI_16 (0x74 + 4, Uid); - HI_16 (0x74 + 6, Gid); + HI_16 (0x74 + 4, Uid) + HI_16 (0x74 + 6, Gid) /* UInt32 checksum; LE_16 (0x74 + 8, checksum); @@ -737,19 +729,19 @@ // InodeSize is power of 2, so the following check is not required: // if (_h.InodeSize < 128 + 2) return false; UInt16 extra_isize; - LE_16 (0x80, extra_isize); + LE_16 (0x80, extra_isize) if (128 + extra_isize > _h.InodeSize) return false; if (extra_isize >= 0x1C) { // UInt16 checksumUpper; // LE_16 (0x82, checksumUpper); - LE_32 (0x84, ChangeTime.Extra); - LE_32 (0x88, MTime.Extra); - LE_32 (0x8C, ATime.Extra); - LE_32 (0x90, CTime.Val); - LE_32 (0x94, CTime.Extra); - // LE_32 (0x98, VersionHi); + LE_32 (0x84, ChangeTime.Extra) + LE_32 (0x88, MTime.Extra) + LE_32 (0x8C, ATime.Extra) + LE_32 (0x90, CTime.Val) + LE_32 (0x94, CTime.Extra) + // LE_32 (0x98, VersionHi) } } @@ -786,7 +778,6 @@ bool IsDir() const { return Type == k_Type_DIR; } // bool IsNotDir() const { return Type != k_Type_DIR && Type != k_Type_UNKNOWN; } - }; @@ -794,14 +785,12 @@ static const unsigned kNumTreeLevelsMax = 6; // must be >= 3 -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_2( + IArchiveGetRawProps, + IInArchiveGetStream +) CObjectVector _items; - CIntVector _refs; + CIntVector _refs; // iNode -> (index in _nodes). if (_refs[iNode] < 0), that node is not filled CRecordVector _nodes; CObjectVector _dirs; // each CUIntVector contains indexes in _items[] only for dir items; AStringVector _symLinks; @@ -871,16 +860,6 @@ void GetPath(unsigned index, AString &s) const; bool GetPackSize(unsigned index, UInt64 &res) const; - -public: - CHandler() {} - ~CHandler() {} - - MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; @@ -892,7 +871,7 @@ PRF(printf("\n\n========= node = %5d size = %5d", (unsigned)iNodeDir, (unsigned)size)); CNode &nodeDir = _nodes[_refs[iNodeDir]]; - nodeDir.DirIndex = _dirs.Size(); + nodeDir.DirIndex = (int)_dirs.Size(); CUIntVector &dir = _dirs.AddNew(); int parentNode = -1; @@ -905,11 +884,11 @@ if (size < 8) return S_FALSE; UInt32 iNode; - LE_32 (0x00, iNode); + LE_32 (0x00, iNode) unsigned recLen; - LE_16 (0x04, recLen); - unsigned nameLen = p[6]; - Byte type = p[7]; + LE_16 (0x04, recLen) + const unsigned nameLen = p[6]; + const Byte type = p[7]; if (recLen > size) return S_FALSE; @@ -926,7 +905,7 @@ else if (type != 0) return S_FALSE; - item.ParentNode = iNodeDir; + item.ParentNode = (int)iNodeDir; item.Node = iNode; item.Name.SetFrom_CalcLen((const char *)(p + 8), nameLen); @@ -958,14 +937,14 @@ continue; } - int nodeIndex = _refs[iNode]; + const int nodeIndex = _refs[iNode]; if (nodeIndex < 0) return S_FALSE; CNode &node = _nodes[nodeIndex]; if (_h.IsThereFileType() && type != 0) { - if (type >= ARRAY_SIZE(k_TypeToMode)) + if (type >= Z7_ARRAY_SIZE(k_TypeToMode)) return S_FALSE; if (k_TypeToMode[type] != (node.Mode & MY_LIN_S_IFMT)) return S_FALSE; @@ -996,10 +975,10 @@ if (iNode == iNodeDir && iNode != k_INODE_ROOT) return S_FALSE; - parentNode = iNode; + parentNode = (int)iNode; if (nodeDir.ParentNode < 0) - nodeDir.ParentNode = iNode; + nodeDir.ParentNode = (int)iNode; else if ((unsigned)nodeDir.ParentNode != iNode) return S_FALSE; @@ -1016,12 +995,12 @@ if (node.IsDir()) { if (node.ParentNode < 0) - node.ParentNode = iNodeDir; + node.ParentNode = (int)iNodeDir; else if ((unsigned)node.ParentNode != iNodeDir) return S_FALSE; const unsigned itemIndex = _items.Size(); dir.Add(itemIndex); - node.ItemIndex = itemIndex; + node.ItemIndex = (int)itemIndex; } _items.Add(item); @@ -1034,6 +1013,13 @@ } +static int CompareItemsNames(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + return strcmp(items[*p1].Name, items[*p2].Name); +} + + int CHandler::FindTargetItem_for_SymLink(unsigned iNode, const AString &path) const { unsigned pos = 0; @@ -1054,7 +1040,7 @@ while (pos != path.Len()) { const CNode &node = _nodes[_refs[iNode]]; - int slash = path.Find('/', pos); + const int slash = path.Find('/', pos); if (slash < 0) { @@ -1063,8 +1049,8 @@ } else { - s.SetFrom(path.Ptr(pos), slash - pos); - pos = slash + 1; + s.SetFrom(path.Ptr(pos), (unsigned)slash - pos); + pos = (unsigned)slash + 1; } if (s[0] == '.') @@ -1077,7 +1063,7 @@ return -1; if (iNode == k_INODE_ROOT) return -1; - iNode = node.ParentNode; + iNode = (unsigned)node.ParentNode; continue; } } @@ -1087,6 +1073,7 @@ const CUIntVector &dir = _dirs[node.DirIndex]; + /* for (unsigned i = 0;; i++) { if (i >= dir.Size()) @@ -1098,6 +1085,26 @@ break; } } + */ + + unsigned left = 0, right = dir.Size(); + for (;;) + { + if (left == right) + return -1; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const CItem &item = _items[dir[mid]]; + const int comp = strcmp(s, item.Name); + if (comp == 0) + { + iNode = item.Node; + break; + } + if (comp < 0) + right = mid; + else + left = mid + 1; + } } return _nodes[_refs[iNode]].ItemIndex; @@ -1110,7 +1117,7 @@ return S_FALSE; if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block) return S_FALSE; - RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, (UInt64)block << _h.BlockBits)) _totalRead += size; return ReadStream_FALSE(inStream, data, size); } @@ -1123,7 +1130,7 @@ { { Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)) if (!_h.Parse(buf + kHeaderDataOffset)) return S_FALSE; if (_h.BlockGroupNr != 0) @@ -1135,7 +1142,7 @@ unsigned numGroups; { - UInt64 numGroups64 = _h.GetNumGroups(); + const UInt64 numGroups64 = _h.GetNumGroups(); if (numGroups64 > (UInt32)1 << 31) return S_FALSE; numGroups = (unsigned)numGroups64; @@ -1154,11 +1161,11 @@ if (_openCallback) { - RINOK(_openCallback->SetTotal(NULL, &_phySize)); + RINOK(_openCallback->SetTotal(NULL, &_phySize)) } UInt64 fileSize = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) CRecordVector groups; @@ -1166,18 +1173,18 @@ // ---------- Read groups ---------- CByteBuffer gdBuf; - size_t gdBufSize = (size_t)numGroups << gdBits; + const size_t gdBufSize = (size_t)numGroups << gdBits; if ((gdBufSize >> gdBits) != numGroups) return S_FALSE; gdBuf.Alloc(gdBufSize); - RINOK(SeekAndRead(inStream, (_h.BlockBits <= 10 ? 2 : 1), gdBuf, gdBufSize)); + RINOK(SeekAndRead(inStream, (_h.BlockBits <= 10 ? 2 : 1), gdBuf, gdBufSize)) for (unsigned i = 0; i < numGroups; i++) { CGroupDescriptor gd; const Byte *p = gdBuf + ((size_t)i << gdBits); - unsigned gd_Size = (unsigned)1 << gdBits; + const unsigned gd_Size = (unsigned)1 << gdBits; gd.Parse(p, gd_Size); if (_h.UseMetadataChecksum()) @@ -1188,7 +1195,7 @@ { UInt32 crc = Crc16Calc(_h.Uuid, sizeof(_h.Uuid)); Byte i_le[4]; - SetUi32(i_le, i); + SetUi32(i_le, i) crc = Crc16Update(crc, i_le, 4); crc = Crc16Update(crc, p, 32 - 2); if (gd_Size != 32) @@ -1250,8 +1257,8 @@ PRF(printf("\n\ng%6d block = %6x\n", gi, (unsigned)gd.InodeTable)); - RINOK(SeekAndRead(inStream, gd.InodeBitmap, nodesMap, blockSize)); - RINOK(SeekAndRead(inStream, gd.InodeTable, nodesData, nodesDataSize)); + RINOK(SeekAndRead(inStream, gd.InodeBitmap, nodesMap, blockSize)) + RINOK(SeekAndRead(inStream, gd.InodeTable, nodesData, nodesDataSize)) unsigned numEmpty_in_Map = 0; @@ -1300,7 +1307,7 @@ _refs.Add(-1); } - _refs.Add(_nodes.Add(node)); + _refs.Add((int)_nodes.Add(node)); } @@ -1336,7 +1343,7 @@ FOR_VECTOR (i, _refs) { - int nodeIndex = _refs[i]; + const int nodeIndex = _refs[i]; { if (nodeIndex < 0) continue; @@ -1344,7 +1351,7 @@ if (!node.IsDir()) continue; } - RINOK(ExtractNode(nodeIndex, dataBuf)); + RINOK(ExtractNode((unsigned)nodeIndex, dataBuf)) if (dataBuf.Size() == 0) { // _headersError = true; @@ -1352,12 +1359,12 @@ } else { - RINOK(ParseDir(dataBuf, dataBuf.Size(), i)); + RINOK(ParseDir(dataBuf, dataBuf.Size(), i)) } - RINOK(CheckProgress()); + RINOK(CheckProgress()) } - int ref = _refs[k_INODE_ROOT]; + const int ref = _refs[k_INODE_ROOT]; if (ref < 0 || _nodes[ref].ParentNode != k_INODE_ROOT) return S_FALSE; } @@ -1423,7 +1430,7 @@ for (;;) { - int nodeIndex = _refs[c]; + const int nodeIndex = _refs[c]; if (nodeIndex < 0) return S_FALSE; CNode &node = _nodes[nodeIndex]; @@ -1435,12 +1442,12 @@ break; } - UsedByNode[c] = i; + UsedByNode[c] = (int)i; if (node.ParentNode < 0 || node.ParentNode == k_INODE_ROOT) break; if ((unsigned)node.ParentNode == i) return S_FALSE; - c = node.ParentNode; + c = (unsigned)node.ParentNode; } } } @@ -1454,7 +1461,7 @@ unsigned i; for (i = 0; i < _refs.Size(); i++) { - int nodeIndex = _refs[i]; + const int nodeIndex = _refs[i]; if (nodeIndex < 0) continue; CNode &node = _nodes[nodeIndex]; @@ -1462,32 +1469,37 @@ continue; if (node.FileSize > ((UInt32)1 << 14)) continue; - if (ExtractNode(nodeIndex, data) == S_OK && data.Size() != 0) + if (ExtractNode((unsigned)nodeIndex, data) == S_OK && data.Size() != 0) { s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); if (s.Len() == data.Size()) - node.SymLinkIndex = _symLinks.Add(s); - RINOK(CheckProgress()); + node.SymLinkIndex = (int)_symLinks.Add(s); + RINOK(CheckProgress()) } } + for (i = 0; i < _dirs.Size(); i++) + { + _dirs[i].Sort(CompareItemsNames, (void *)&_items); + } + unsigned prev = 0; unsigned complex = 0; for (i = 0; i < _items.Size(); i++) { CItem &item = _items[i]; - int sym = _nodes[_refs[item.Node]].SymLinkIndex; + const int sym = _nodes[_refs[item.Node]].SymLinkIndex; if (sym >= 0 && item.ParentNode >= 0) { - item.SymLinkItemIndex = FindTargetItem_for_SymLink(item.ParentNode, _symLinks[sym]); + item.SymLinkItemIndex = FindTargetItem_for_SymLink((unsigned)item.ParentNode, _symLinks[sym]); if (_openCallback) { complex++; if (complex - prev >= (1 << 10)) { - RINOK(CheckProgress2()); prev = complex; + RINOK(CheckProgress2()) } } } @@ -1502,7 +1514,7 @@ FOR_VECTOR (i, _refs) { - int nodeIndex = _refs[i]; + const int nodeIndex = _refs[i]; if (nodeIndex < 0) continue; const CNode &node = _nodes[nodeIndex]; @@ -1523,7 +1535,7 @@ if (i < _h.FirstInode) { - if (item.Node < ARRAY_SIZE(k_SysInode_Names)) + if (item.Node < Z7_ARRAY_SIZE(k_SysInode_Names)) item.Name = k_SysInode_Names[item.Node]; useSys = true; } @@ -1538,16 +1550,16 @@ } if (useSys) - _auxSysIndex = _auxItems.Add((AString)"[SYS]"); + _auxSysIndex = (int)_auxItems.Add((AString)"[SYS]"); if (useUnknown) - _auxUnknownIndex = _auxItems.Add((AString)"[UNKNOWN]"); + _auxUnknownIndex = (int)_auxItems.Add((AString)"[UNKNOWN]"); } return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { @@ -1590,7 +1602,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalRead = 0; _totalReadPrev = 0; @@ -1652,7 +1664,7 @@ const CNode &node = _nodes[_refs[item.ParentNode]]; if (node.ItemIndex < 0) return; - index = node.ItemIndex; + index = (unsigned)node.ItemIndex; if (s.Len() > ((UInt32)1 << 16)) { @@ -1707,7 +1719,7 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size() + _auxItems.Size(); return S_OK; @@ -1797,7 +1809,7 @@ PropVariant_SetFrom_UnixTime(prop, val); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN @@ -1840,12 +1852,10 @@ case kpidId: { - if (!IsEmptyData(_h.Uuid, 16)) + if (!IsEmptyData(_h.Uuid, sizeof(_h.Uuid))) { - char s[16 * 2 + 2]; - for (unsigned i = 0; i < 16; i++) - PrintHex(_h.Uuid[i], s + i * 2); - s[16 * 2] = 0; + char s[sizeof(_h.Uuid) * 2 + 2]; + ConvertDataToHex_Lower(s, _h.Uuid, sizeof(_h.Uuid)); prop = s; } break; @@ -1869,7 +1879,7 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_linksError) v |= kpv_ErrorFlags_HeadersError; if (_headersError) v |= kpv_ErrorFlags_HeadersError; if (!_stream && v == 0 && _isArc) @@ -1903,22 +1913,22 @@ }; */ -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { - // *numProps = ARRAY_SIZE(kRawProps); + // *numProps = Z7_ARRAY_SIZE(kRawProps); *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { // *propID = kRawProps[index]; *propID = 0; - *name = 0; + *name = NULL; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; @@ -1930,22 +1940,22 @@ if (item.ParentNode < 0) { - int aux = GetParentAux(item); + const int aux = GetParentAux(item); if (aux >= 0) - *parent = _items.Size() + aux; + *parent = _items.Size() + (unsigned)aux; } else { - int itemIndex = _nodes[_refs[item.ParentNode]].ItemIndex; + const int itemIndex = _nodes[_refs[item.ParentNode]].ItemIndex; if (itemIndex >= 0) - *parent = itemIndex; + *parent = (unsigned)itemIndex; } return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -2017,7 +2027,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -2094,7 +2104,7 @@ case kpidPosixAttrib: { /* - if (node.Type != 0 && node.Type < ARRAY_SIZE(k_TypeToMode)) + if (node.Type != 0 && node.Type < Z7_ARRAY_SIZE(k_TypeToMode)) prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; */ prop = (UInt32)(node.Mode); @@ -2137,10 +2147,8 @@ } -class CClusterInStream2: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream(CClusterInStream2 +) UInt64 _virtPos; UInt64 _physPos; UInt32 _curRem; @@ -2150,7 +2158,7 @@ CMyComPtr Stream; CRecordVector Vector; - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } HRESULT InitAndSeek() { @@ -2164,15 +2172,10 @@ } return S_OK; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; -STDMETHODIMP CClusterInStream2::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CClusterInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -2209,7 +2212,7 @@ if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } _curRem = blockSize - offsetInBlock; @@ -2229,7 +2232,7 @@ return res; } -STDMETHODIMP CClusterInStream2::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CClusterInStream2::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -2242,17 +2245,16 @@ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; if (_virtPos != (UInt64)offset) _curRem = 0; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -class CExtInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CExtInStream +) UInt64 _virtPos; UInt64 _phyPos; public: @@ -2261,21 +2263,15 @@ CMyComPtr Stream; CRecordVector Extents; - CExtInStream() {} - HRESULT StartSeek() { _virtPos = 0; _phyPos = 0; - return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, _phyPos); } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; -STDMETHODIMP CExtInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CExtInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -2328,18 +2324,18 @@ return S_OK; } - UInt64 phyBlock = extent.PhyStart + bo; - UInt64 phy = (phyBlock << BlockBits) + offset; + const UInt64 phyBlock = extent.PhyStart + bo; + const UInt64 phy = (phyBlock << BlockBits) + offset; if (phy != _phyPos) { - RINOK(Stream->Seek(phy, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(Stream, phy)) _phyPos = phy; } UInt32 realProcessSize = 0; - HRESULT res = Stream->Read(data, size, &realProcessSize); + const HRESULT res = Stream->Read(data, size, &realProcessSize); _phyPos += realProcessSize; _virtPos += realProcessSize; @@ -2350,7 +2346,7 @@ } -STDMETHODIMP CExtInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CExtInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -2361,9 +2357,9 @@ } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } @@ -2377,7 +2373,7 @@ PRF2(printf("\n level = %d, block = %7d", level, (unsigned)block)); - RINOK(SeekAndRead(_stream, block, tempBuf, blockSize)); + RINOK(SeekAndRead(_stream, block, tempBuf, blockSize)) const Byte *p = tempBuf; size_t num = (size_t)1 << (_h.BlockBits - 2); @@ -2408,7 +2404,7 @@ return S_FALSE; } - RINOK(FillFileBlocks2(val, level - 1, numBlocks, blocks)); + RINOK(FillFileBlocks2(val, level - 1, numBlocks, blocks)) continue; } @@ -2464,7 +2460,7 @@ return S_FALSE; } - RINOK(FillFileBlocks2(val, level, numBlocks, blocks)); + RINOK(FillFileBlocks2(val, level, numBlocks, blocks)) } return S_OK; @@ -2560,8 +2556,8 @@ if (!UpdateExtents(extents, e.VirtBlock)) return S_FALSE; - RINOK(SeekAndRead(_stream, e.PhyLeaf, tempBuf, blockSize)); - RINOK(FillExtents(tempBuf, blockSize, extents, eth.Depth)); + RINOK(SeekAndRead(_stream, e.PhyLeaf, tempBuf, blockSize)) + RINOK(FillExtents(tempBuf, blockSize, extents, eth.Depth)) } return S_OK; @@ -2596,7 +2592,7 @@ CMyComPtr streamTemp; - UInt64 numBlocks64 = (node.FileSize + (UInt64)(((UInt32)1 << _h.BlockBits) - 1)) >> _h.BlockBits; + const UInt64 numBlocks64 = (node.FileSize + (UInt64)(((UInt32)1 << _h.BlockBits) - 1)) >> _h.BlockBits; if (node.IsFlags_EXTENTS()) { @@ -2610,7 +2606,7 @@ streamSpec->Size = node.FileSize; streamSpec->Stream = _stream; - RINOK(FillExtents(node.Block, kNodeBlockFieldSize, streamSpec->Extents, -1)); + RINOK(FillExtents(node.Block, kNodeBlockFieldSize, streamSpec->Extents, -1)) UInt32 end = 0; if (!streamSpec->Extents.IsEmpty()) @@ -2621,7 +2617,7 @@ // return S_FALSE; } - RINOK(streamSpec->StartSeek()); + RINOK(streamSpec->StartSeek()) } else { @@ -2648,7 +2644,7 @@ } const unsigned specBits = (node.IsFlags_HUGE() ? 0 : _h.BlockBits - 9); - const UInt32 specMask = ((UInt32)1 << specBits) - 1;; + const UInt32 specMask = ((UInt32)1 << specBits) - 1; if ((node.NumBlocks & specMask) != 0) return S_FALSE; const UInt64 numBlocks64_from_header = node.NumBlocks >> specBits; @@ -2670,7 +2666,7 @@ streamSpec->Size = node.FileSize; streamSpec->Stream = _stream; - RINOK(FillFileBlocks(node.Block, numBlocks, streamSpec->Vector)); + RINOK(FillFileBlocks(node.Block, numBlocks, streamSpec->Vector)) streamSpec->InitAndSeek(); } @@ -2690,7 +2686,7 @@ if (size != node.FileSize) return S_FALSE; CMyComPtr inSeqStream; - RINOK(GetStream_Node(nodeIndex, &inSeqStream)); + RINOK(GetStream_Node(nodeIndex, &inSeqStream)) if (!inSeqStream) return S_FALSE; data.Alloc(size); @@ -2699,11 +2695,11 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size() + _auxItems.Size(); if (numItems == 0) @@ -2714,7 +2710,7 @@ for (i = 0; i < numItems; i++) { - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; if (index >= _items.Size()) continue; const CItem &item = _items[index]; @@ -2723,40 +2719,38 @@ totalSize += node.FileSize; } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 totalPackSize; totalSize = totalPackSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; for (i = 0;; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); - - if (i == numItems) + RINOK(lps->SetCur()) + if (i >= numItems) break; + int opRes; + { CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) if (index >= _items.Size()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -2765,8 +2759,8 @@ if (node.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -2778,9 +2772,9 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) - int res = NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; { CMyComPtr inSeqStream; HRESULT hres = GetStream(index, &inSeqStream); @@ -2788,30 +2782,31 @@ { if (hres == E_OUTOFMEMORY) return hres; - res = NExtract::NOperationResult::kUnsupportedMethod; + opRes = NExtract::NOperationResult::kUnsupportedMethod; } else { - RINOK(hres); + RINOK(hres) { - hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); + hres = copyCoder.Interface()->Code(inSeqStream, outStream, NULL, NULL, lps); if (hres == S_OK) { - if (copyCoderSpec->TotalSize == unpackSize) - res = NExtract::NOperationResult::kOK; + if (copyCoder->TotalSize == unpackSize) + opRes = NExtract::NOperationResult::kOK; } else if (hres == E_NOTIMPL) { - res = NExtract::NOperationResult::kUnsupportedMethod; + opRes = NExtract::NOperationResult::kUnsupportedMethod; } else if (hres != S_FALSE) { - RINOK(hres); + RINOK(hres) } } } } - RINOK(extractCallback->SetOperationResult(res)); + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -2819,12 +2814,12 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { *stream = NULL; if (index >= _items.Size()) return S_FALSE; - return GetStream_Node(_refs[_items[index].Node], stream); + return GetStream_Node((unsigned)_refs[_items[index].Node], stream); } @@ -2854,7 +2849,7 @@ static const Byte k_Signature[] = { 0x53, 0xEF }; REGISTER_ARC_I( - "Ext", "ext ext2 ext3 ext4 img", 0, 0xC7, + "Ext", "ext ext2 ext3 ext4 img", NULL, 0xC7, k_Signature, 0x438, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/FatHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FatHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/FatHandler.cpp 2022-03-28 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FatHandler.cpp 2025-02-09 09:00:00.000000000 +0000 @@ -2,13 +2,12 @@ #include "StdAfx.h" -// #include - #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" #include "../../Common/IntToString.h" #include "../../Common/MyBuffer.h" +#include "../../Common/MyBuffer2.h" #include "../../Common/MyCom.h" #include "../../Common/StringConvert.h" @@ -22,12 +21,19 @@ #include "../Compress/CopyCoder.h" -#include "Common/DummyOutStream.h" +#include "Common/ItemNameUtils.h" #define Get16(p) GetUi16(p) #define Get32(p) GetUi32(p) +#define Get16a(p) GetUi16a(p) +#define Get32a(p) GetUi32a(p) -#define PRF(x) /* x */ +#if 0 +#include +#define PRF(x) x +#else +#define PRF(x) +#endif namespace NArchive { namespace NFat { @@ -36,34 +42,34 @@ struct CHeader { - UInt32 NumSectors; - UInt16 NumReservedSectors; + Byte NumFatBits; + Byte SectorSizeLog; + Byte SectorsPerClusterLog; + Byte ClusterSizeLog; Byte NumFats; + Byte MediaType; + + bool VolFieldsDefined; + bool HeadersWarning; + + UInt32 FatSize; + UInt32 BadCluster; + + UInt16 NumReservedSectors; + UInt32 NumSectors; UInt32 NumFatSectors; UInt32 RootDirSector; UInt32 NumRootDirSectors; UInt32 DataSector; - UInt32 FatSize; - UInt32 BadCluster; - - Byte NumFatBits; - Byte SectorSizeLog; - Byte SectorsPerClusterLog; - Byte ClusterSizeLog; - UInt16 SectorsPerTrack; UInt16 NumHeads; UInt32 NumHiddenSectors; - - bool VolFieldsDefined; UInt32 VolId; // Byte VolName[11]; // Byte FileSys[8]; - // Byte OemName[5]; - Byte MediaType; // 32-bit FAT UInt16 Flags; @@ -101,15 +107,8 @@ bool Parse(const Byte *p); }; -static int GetLog(UInt32 num) -{ - for (int i = 0; i < 31; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} -static const UInt32 kHeaderSize = 512; +static const unsigned kHeaderSize = 512; API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size); API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size) @@ -122,9 +121,11 @@ bool CHeader::Parse(const Byte *p) { - if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + if (Get16(p + 0x1FE) != 0xAA55) return false; + HeadersWarning = false; + int codeOffset = 0; switch (p[0]) { @@ -134,22 +135,40 @@ } { { - UInt32 val32 = Get16(p + 11); - int s = GetLog(val32); - if (s < 9 || s > 12) - return false; - SectorSizeLog = (Byte)s; + const unsigned num = Get16(p + 11); + unsigned i = 9; + unsigned m = 1 << i; + for (;;) + { + if (m == num) + break; + m <<= 1; + if (++i > 12) + return false; + } + SectorSizeLog = (Byte)i; } { - UInt32 val32 = p[13]; - int s = GetLog(val32); - if (s < 0) + const unsigned num = p[13]; + unsigned i = 0; + unsigned m = 1 << i; + for (;;) + { + if (m == num) + break; + m <<= 1; + if (++i > 7) + return false; + } + SectorsPerClusterLog = (Byte)i; + i += SectorSizeLog; + ClusterSizeLog = (Byte)i; + // (2^15 = 32 KB is safe cluster size that is suported by all system. + // (2^16 = 64 KB is supported by some systems + // (128 KB / 256 KB) can be created by some tools, but it is not supported by many tools. + if (i > 18) // 256 KB return false; - SectorsPerClusterLog = (Byte)s; } - ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog); - if (ClusterSizeLog > 24) - return false; } NumReservedSectors = Get16(p + 14); @@ -161,10 +180,10 @@ return false; // we also support images that contain 0 in offset field. - bool isOkOffset = (codeOffset == 0) + const bool isOkOffset = (codeOffset == 0) || (codeOffset == (p[0] == 0xEB ? 2 : 3)); - UInt16 numRootDirEntries = Get16(p + 17); + const unsigned numRootDirEntries = Get16(p + 17); if (numRootDirEntries == 0) { if (codeOffset < 90 && !isOkOffset) @@ -178,18 +197,21 @@ if (codeOffset < 62 - 24 && !isOkOffset) return false; NumFatBits = 0; - UInt32 mask = (1 << (SectorSizeLog - 5)) - 1; - if ((numRootDirEntries & mask) != 0) + const unsigned mask = (1u << (SectorSizeLog - 5)) - 1; + if (numRootDirEntries & mask) return false; - NumRootDirSectors = (numRootDirEntries + mask) >> (SectorSizeLog - 5); + NumRootDirSectors = (numRootDirEntries /* + mask */) >> (SectorSizeLog - 5); } NumSectors = Get16(p + 19); if (NumSectors == 0) NumSectors = Get32(p + 32); + /* + // mkfs.fat could create fat32 image with 16-bit number of sectors. + // v23: we allow 16-bit value for number of sectors in fat32. else if (IsFat32()) return false; - + */ MediaType = p[21]; NumFatSectors = Get16(p + 22); SectorsPerTrack = Get16(p + 24); @@ -213,7 +235,7 @@ return false; RootCluster = Get32(p + 8); FsInfoSector = Get16(p + 12); - for (int i = 16; i < 28; i++) + for (unsigned i = 16; i < 28; i++) if (p[i] != 0) return false; p += 28; @@ -241,124 +263,191 @@ DataSector = RootDirSector + NumRootDirSectors; if (NumSectors < DataSector) return false; - UInt32 numDataSectors = NumSectors - DataSector; - UInt32 numClusters = numDataSectors >> SectorsPerClusterLog; + const UInt32 numDataSectors = NumSectors - DataSector; + const UInt32 numClusters = numDataSectors >> SectorsPerClusterLog; BadCluster = 0x0FFFFFF7; - if (numClusters < 0xFFF5) + // v23: we support unusual (< 0xFFF5) numClusters values in fat32 systems + if (NumFatBits != 32) { - if (NumFatBits == 32) + if (numClusters >= 0xFFF5) return false; NumFatBits = (Byte)(numClusters < 0xFF5 ? 12 : 16); - BadCluster &= ((1 << NumFatBits) - 1); + BadCluster &= (((UInt32)1 << NumFatBits) - 1); } - else if (NumFatBits != 32) - return false; FatSize = numClusters + 2; - if (FatSize > BadCluster || CalcFatSizeInSectors() > NumFatSectors) + if (FatSize > BadCluster) return false; + if (CalcFatSizeInSectors() > NumFatSectors) + { + /* some third-party program can create such FAT image, where + size of FAT table (NumFatSectors from headers) is smaller than + required value that is calculated from calculated (FatSize) value. + Another FAT unpackers probably ignore that error. + v23.02: we also ignore that error, and + we recalculate (FatSize) value from (NumFatSectors). + New (FatSize) will be smaller than original "full" (FatSize) value. + So we will have some unused clusters at the end of archive. + */ + FatSize = (UInt32)(((UInt64)NumFatSectors << (3 + SectorSizeLog)) / NumFatBits); + HeadersWarning = true; + } return true; } -struct CItem + + +class CItem { - UString UName; - char DosName[11]; + Z7_CLASS_NO_COPY(CItem) +public: + UInt32 Size; + Byte Attrib; Byte CTime2; - UInt32 CTime; - UInt32 MTime; UInt16 ADate; - Byte Attrib; + CByteBuffer LongName; // if LongName.Size() == 0 : no long name + // if LongName.Size() != 0 : it's NULL terminated UTF16-LE string. + char DosName[11]; Byte Flags; - UInt32 Size; + UInt32 MTime; + UInt32 CTime; UInt32 Cluster; Int32 Parent; + CItem() {} + // NT uses Flags to store Low Case status bool NameIsLow() const { return (Flags & 0x8) != 0; } bool ExtIsLow() const { return (Flags & 0x10) != 0; } bool IsDir() const { return (Attrib & 0x10) != 0; } - UString GetShortName() const; - UString GetName() const; - UString GetVolName() const; + void GetShortName(UString &dest) const; + void GetName(UString &name) const; }; -static unsigned CopyAndTrim(char *dest, const char *src, unsigned size, bool toLower) + +static char *CopyAndTrim(char *dest, const char *src, + unsigned size, unsigned toLower) { - memcpy(dest, src, size); - if (toLower) + do { - for (unsigned i = 0; i < size; i++) + if (src[(size_t)size - 1] != ' ') { - char c = dest[i]; - if (c >= 'A' && c <= 'Z') - dest[i] = (char)(c + 0x20); + const unsigned range = toLower ? 'Z' - 'A' + 1 : 0; + do + { + unsigned c = (Byte)*src++; + if ((unsigned)(c - 'A') < range) + c += 0x20; + *dest++ = (char)c; + } + while (--size); + break; } } - - for (unsigned i = size;;) - { - if (i == 0) - return 0; - if (dest[i - 1] != ' ') - return i; - i--; - } + while (--size); + *dest = 0; + return dest; } -static UString FatStringToUnicode(const char *s) + +static void FatStringToUnicode(UString &dest, const char *s) { - return MultiByteToUnicodeString(s, CP_OEMCP); + MultiByteToUnicodeString2(dest, AString(s), CP_OEMCP); } -UString CItem::GetShortName() const +void CItem::GetShortName(UString &shortName) const { char s[16]; - unsigned i = CopyAndTrim(s, DosName, 8, NameIsLow()); - s[i++] = '.'; - unsigned j = CopyAndTrim(s + i, DosName + 8, 3, ExtIsLow()); - if (j == 0) - i--; - s[i + j] = 0; - return FatStringToUnicode(s); + char *dest = CopyAndTrim(s, DosName, 8, NameIsLow()); + *dest++ = '.'; + char *dest2 = CopyAndTrim(dest, DosName + 8, 3, ExtIsLow()); + if (dest == dest2) + dest[-1] = 0; + FatStringToUnicode(shortName, s); } -UString CItem::GetName() const + + +// numWords != 0 +static unsigned ParseLongName(UInt16 *buf, unsigned numWords) { - if (!UName.IsEmpty()) - return UName; - return GetShortName(); + unsigned i; + for (i = 0; i < numWords; i++) + { + const unsigned c = buf[i]; + if (c == 0) + break; + if (c == 0xFFFF) + return 0; + } + if (i == 0) + return 0; + buf[i] = 0; + numWords -= i; + i++; + if (numWords > 1) + { + numWords--; + buf += i; + do + if (*buf++ != 0xFFFF) + return 0; + while (--numWords); + } + return i; // it includes NULL terminator +} + + +void CItem::GetName(UString &name) const +{ + if (LongName.Size() >= 2) + { + const Byte * const p = LongName; + const unsigned numWords = ((unsigned)LongName.Size() - 2) / 2; + wchar_t *dest = name.GetBuf(numWords); + for (unsigned i = 0; i < numWords; i++) + dest[i] = (wchar_t)Get16(p + (size_t)i * 2); + name.ReleaseBuf_SetEnd(numWords); + } + else + GetShortName(name); + if (name.IsEmpty()) // it's unexpected + name = '_'; + NItemName::NormalizeSlashes_in_FileName_for_OsPath(name); } -UString CItem::GetVolName() const + +static void GetVolName(const char dosName[11], NWindows::NCOM::CPropVariant &prop) { - if (!UName.IsEmpty()) - return UName; char s[12]; - unsigned i = CopyAndTrim(s, DosName, 11, false); - s[i] = 0; - return FatStringToUnicode(s); + CopyAndTrim(s, dosName, 11, false); + UString u; + FatStringToUnicode(u, AString(s)); + prop = u; } + struct CDatabase { - CHeader Header; CObjectVector Items; UInt32 *Fat; + CHeader Header; CMyComPtr InStream; IArchiveOpenCallback *OpenCallback; + CAlignedBuffer ByteBuf; + CByteBuffer LfnBuf; UInt32 NumFreeClusters; - bool VolItemDefined; - CItem VolItem; UInt32 NumDirClusters; - CByteBuffer ByteBuf; UInt64 NumCurUsedBytes; - UInt64 PhySize; - CDatabase(): Fat(0) {} + UInt32 Vol_MTime; + char VolLabel[11]; + bool VolItem_Defined; + + CDatabase(): Fat(NULL) {} ~CDatabase() { ClearAndClose(); } void Clear(); @@ -366,7 +455,7 @@ HRESULT OpenProgressFat(bool changeTotal = true); HRESULT OpenProgress(); - UString GetItemPath(Int32 index) const; + void GetItemPath(UInt32 index, UString &s) const; HRESULT Open(); HRESULT ReadDir(Int32 parent, UInt32 cluster, unsigned level); @@ -378,21 +467,22 @@ HRESULT SeekToCluster(UInt32 cluster) { return SeekToSector(Header.ClusterToSector(cluster)); } }; + HRESULT CDatabase::SeekToSector(UInt32 sector) { - return InStream->Seek((UInt64)sector << Header.SectorSizeLog, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(InStream, (UInt64)sector << Header.SectorSizeLog); } void CDatabase::Clear() { PhySize = 0; - VolItemDefined = false; + VolItem_Defined = false; NumDirClusters = 0; NumCurUsedBytes = 0; Items.Clear(); delete []Fat; - Fat = 0; + Fat = NULL; } void CDatabase::ClearAndClose() @@ -407,9 +497,9 @@ return S_OK; if (changeTotal) { - UInt64 numTotalBytes = (Header.CalcFatSizeInSectors() << Header.SectorSizeLog) + + const UInt64 numTotalBytes = (Header.CalcFatSizeInSectors() << Header.SectorSizeLog) + ((UInt64)(Header.FatSize - NumFreeClusters) << Header.ClusterSizeLog); - RINOK(OpenCallback->SetTotal(NULL, &numTotalBytes)); + RINOK(OpenCallback->SetTotal(NULL, &numTotalBytes)) } return OpenCallback->SetCompleted(NULL, &NumCurUsedBytes); } @@ -418,71 +508,62 @@ { if (!OpenCallback) return S_OK; - UInt64 numItems = Items.Size(); + const UInt64 numItems = Items.Size(); return OpenCallback->SetCompleted(&numItems, &NumCurUsedBytes); } -UString CDatabase::GetItemPath(Int32 index) const +void CDatabase::GetItemPath(UInt32 index, UString &s) const { - const CItem *item = &Items[index]; - UString name = item->GetName(); + UString name; for (;;) { - index = item->Parent; - if (index < 0) - return name; - item = &Items[index]; - name.InsertAtFront(WCHAR_PATH_SEPARATOR); - if (item->UName.IsEmpty()) - name.Insert(0, item->GetShortName()); - else - name.Insert(0, item->UName); + const CItem &item = Items[index]; + item.GetName(name); + if (item.Parent >= 0) + name.InsertAtFront(WCHAR_PATH_SEPARATOR); + s.Insert(0, name); + index = (UInt32)item.Parent; + if (item.Parent < 0) + break; } } -static wchar_t *AddSubStringToName(wchar_t *dest, const Byte *p, unsigned numChars) -{ - for (unsigned i = 0; i < numChars; i++) - { - wchar_t c = Get16(p + i * 2); - if (c != 0 && c != 0xFFFF) - *dest++ = c; - } - *dest = 0; - return dest; -} HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, unsigned level) { - unsigned startIndex = Items.Size(); + const unsigned startIndex = Items.Size(); if (startIndex >= (1 << 30) || level > 256) return S_FALSE; - UInt32 sectorIndex = 0; UInt32 blockSize = Header.ClusterSize(); - bool clusterMode = (Header.IsFat32() || parent >= 0); + const bool clusterMode = (Header.IsFat32() || parent >= 0); if (!clusterMode) { blockSize = Header.SectorSize(); - RINOK(SeekToSector(Header.RootDirSector)); + RINOK(SeekToSector(Header.RootDirSector)) } ByteBuf.Alloc(blockSize); - UString curName; - int checkSum = -1; - int numLongRecords = -1; + + const unsigned k_NumLfnRecords_MAX = 20; // 260 symbols limit (strict limit) + // const unsigned k_NumLfnRecords_MAX = 0x40 - 1; // 1260 symbols limit (relaxed limit) + const unsigned k_NumLfnBytes_in_Record = 13 * 2; + // we reserve 2 additional bytes for NULL terminator + LfnBuf.Alloc(k_NumLfnRecords_MAX * k_NumLfnBytes_in_Record + 2 * 1); + UInt32 curDirBytes_read = 0; + UInt32 sectorIndex = 0; + unsigned num_lfn_records = 0; + unsigned lfn_RecordIndex = 0; + int checkSum = -1; + bool is_record_error = false; + for (UInt32 pos = blockSize;; pos += 32) { if (pos == blockSize) { pos = 0; - if ((NumDirClusters & 0xFF) == 0) - { - RINOK(OpenProgress()); - } - if (clusterMode) { if (Header.IsEoc(cluster)) @@ -490,23 +571,39 @@ if (!Header.IsValidCluster(cluster)) return S_FALSE; PRF(printf("\nCluster = %4X", cluster)); - RINOK(SeekToCluster(cluster)); - UInt32 newCluster = Fat[cluster]; - if ((newCluster & kFatItemUsedByDirMask) != 0) + RINOK(SeekToCluster(cluster)) + const UInt32 newCluster = Fat[cluster]; + if (newCluster & kFatItemUsedByDirMask) return S_FALSE; Fat[cluster] |= kFatItemUsedByDirMask; cluster = newCluster; NumDirClusters++; + if ((NumDirClusters & 0xFF) == 0) + { + RINOK(OpenProgress()) + } NumCurUsedBytes += Header.ClusterSize(); } else if (sectorIndex++ >= Header.NumRootDirSectors) break; - RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)); + // if (curDirBytes_read > (1u << 28)) // do we need some relaxed limit for non-MS FATs? + if (curDirBytes_read >= (1u << 21)) // 2MB limit from FAT specification. + return S_FALSE; + RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)) + curDirBytes_read += blockSize; } - const Byte *p = ByteBuf + pos; - + if (is_record_error) + { + Header.HeadersWarning = true; + num_lfn_records = 0; + lfn_RecordIndex = 0; + checkSum = -1; + } + + const Byte * const p = ByteBuf + pos; + if (p[0] == 0) { /* @@ -516,128 +613,194 @@ */ break; } - + + is_record_error = true; + if (p[0] == 0xE5) { - if (numLongRecords > 0) - return S_FALSE; + // deleted entry + if (num_lfn_records == 0) + is_record_error = false; continue; } - - Byte attrib = p[11]; - if ((attrib & 0x3F) == 0xF) + // else { - if (p[0] > 0x7F || Get16(p + 26) != 0) - return S_FALSE; - int longIndex = p[0] & 0x3F; - if (longIndex == 0) - return S_FALSE; - bool isLast = (p[0] & 0x40) != 0; - if (numLongRecords < 0) + const Byte attrib = p[11]; + // maybe we can use more strick check : (attrib == 0xF) ? + if ((attrib & 0x3F) == 0xF) { - if (!isLast) + // long file name (LFN) entry + const unsigned longIndex = p[0] & 0x3F; + if (longIndex == 0 + || longIndex > k_NumLfnRecords_MAX + || p[0] > 0x7F + || Get16a(p + 26) != 0 // LDIR_FstClusLO + ) + { + return S_FALSE; + // break; + } + const bool isLast = (p[0] & 0x40) != 0; + if (num_lfn_records == 0) + { + if (!isLast) + continue; // orphan + num_lfn_records = longIndex; + } + else if (isLast || longIndex != lfn_RecordIndex) + { return S_FALSE; - numLongRecords = longIndex; + // break; + } + + lfn_RecordIndex = longIndex - 1; + + if (p[12] == 0) + { + Byte * const dest = LfnBuf + k_NumLfnBytes_in_Record * lfn_RecordIndex; + memcpy(dest, p + 1, 5 * 2); + memcpy(dest + 5 * 2, p + 14, 6 * 2); + memcpy(dest + 11 * 2, p + 28, 2 * 2); + if (isLast) + checkSum = p[13]; + if (checkSum == p[13]) + is_record_error = false; + // else return S_FALSE; + continue; + } + // else + checkSum = -1; // we will ignore LfnBuf in this case + continue; } - else if (isLast || numLongRecords != longIndex) - return S_FALSE; - - numLongRecords--; - if (p[12] == 0) + if (lfn_RecordIndex) { - wchar_t nameBuf[14]; - wchar_t *dest; - - dest = AddSubStringToName(nameBuf, p + 1, 5); - dest = AddSubStringToName(dest, p + 14, 6); - AddSubStringToName(dest, p + 28, 2); - curName = nameBuf + curName; - if (isLast) - checkSum = p[13]; - if (checkSum != p[13]) - return S_FALSE; + Header.HeadersWarning = true; + // return S_FALSE; } - } - else - { - if (numLongRecords > 0) - return S_FALSE; - CItem item; - memcpy(item.DosName, p, 11); + // lfn_RecordIndex = 0; - if (checkSum >= 0) + const unsigned type_in_attrib = attrib & 0x18; + if (type_in_attrib == 0x18) { - Byte sum = 0; - for (unsigned i = 0; i < 11; i++) - sum = (Byte)(((sum & 1) ? 0x80 : 0) + (sum >> 1) + (Byte)item.DosName[i]); - if (sum == checkSum) - item.UName = curName; + // invalid directory record (both flags are set: dir_flag and volume_flag) + return S_FALSE; + // break; + // continue; } - - if (item.DosName[0] == 5) - item.DosName[0] = (char)(Byte)0xE5; - item.Attrib = attrib; - item.Flags = p[12]; - item.Size = Get32(p + 28); - item.Cluster = Get16(p + 26); - if (Header.NumFatBits > 16) - item.Cluster |= ((UInt32)Get16(p + 20) << 16); - else + if (type_in_attrib == 8) // volume_flag { - // OS/2 and WinNT probably can store EA (extended atributes) in that field. + if (!VolItem_Defined && level == 0) + { + VolItem_Defined = true; + memcpy(VolLabel, p, 11); + Vol_MTime = Get32(p + 22); + is_record_error = false; + } } - - item.CTime = Get32(p + 14); - item.CTime2 = p[13]; - item.ADate = Get16(p + 18); - item.MTime = Get32(p + 22); - item.Parent = parent; - - if (attrib == 8) + else if (memcmp(p, ". ", 11) == 0 + || memcmp(p, ".. ", 11) == 0) { - VolItem = item; - VolItemDefined = true; + if (num_lfn_records == 0 && type_in_attrib == 0x10) // dir_flag + is_record_error = false; } else - if (memcmp(item.DosName, ". ", 11) != 0 && - memcmp(item.DosName, ".. ", 11) != 0) { - if (!item.IsDir()) - NumCurUsedBytes += Header.GetFilePackSize(item.Size); - Items.Add(item); - PRF(printf("\n%7d: %S", Items.Size(), GetItemPath(Items.Size() - 1))); + CItem &item = Items.AddNew(); + memcpy(item.DosName, p, 11); + if (item.DosName[0] == 5) + item.DosName[0] = (char)(Byte)0xE5; // 0xE5 is valid KANJI lead byte value. + item.Attrib = attrib; + item.Flags = p[12]; + item.Size = Get32a(p + 28); + item.Cluster = Get16a(p + 26); + if (Header.NumFatBits > 16) + item.Cluster |= ((UInt32)Get16a(p + 20) << 16); + else + { + // OS/2 and WinNT probably can store EA (extended atributes) in that field. + } + item.CTime = Get32(p + 14); + item.CTime2 = p[13]; + item.ADate = Get16a(p + 18); + item.MTime = Get32(p + 22); + item.Parent = parent; + { + if (!item.IsDir()) + NumCurUsedBytes += Header.GetFilePackSize(item.Size); + // PRF(printf("\n%7d: %S", Items.Size(), GetItemPath(Items.Size() - 1))); + PRF(printf("\n%7d" /* ": %S" */, Items.Size() /* , item.GetShortName() */ );) + } + if (num_lfn_records == 0) + is_record_error = false; + else if (checkSum >= 0 && lfn_RecordIndex == 0) + { + Byte sum = 0; + for (unsigned i = 0; i < 11; i++) + sum = (Byte)((sum << 7) + (sum >> 1) + (Byte)item.DosName[i]); + if (sum == checkSum) + { + const unsigned numWords = ParseLongName((UInt16 *)(void *)(Byte *)LfnBuf, + num_lfn_records * k_NumLfnBytes_in_Record / 2); + if (numWords > 1) + { + // numWords includes NULL terminator + item.LongName.CopyFrom(LfnBuf, numWords * 2); + is_record_error = false; + } + } + } + + if ( + // item.LongName.Size() < 20 || // for debug + item.LongName.Size() <= 2 * 1 + && memcmp(p, " ", 11) == 0) + { + char s[16 + 16]; + const size_t numChars = (size_t)(ConvertUInt32ToString( + Items.Size() - 1 - startIndex, + MyStpCpy(s, "[NONAME]-")) - s) + 1; + item.LongName.Alloc(numChars * 2); + for (size_t i = 0; i < numChars; i++) + { + SetUi16a(item.LongName + i * 2, (Byte)s[i]) + } + Header.HeadersWarning = true; + } } - numLongRecords = -1; - curName.Empty(); - checkSum = -1; + num_lfn_records = 0; } } - unsigned finishIndex = Items.Size(); + if (is_record_error) + Header.HeadersWarning = true; + + const unsigned finishIndex = Items.Size(); for (unsigned i = startIndex; i < finishIndex; i++) { const CItem &item = Items[i]; if (item.IsDir()) { - PRF(printf("\n%S", GetItemPath(i))); - RINOK(CDatabase::ReadDir(i, item.Cluster, level + 1)); + PRF(printf("\n---- %c%c%c%c%c", item.DosName[0], item.DosName[1], item.DosName[2], item.DosName[3], item.DosName[4])); + RINOK(ReadDir((int)i, item.Cluster, level + 1)) } } return S_OK; } + + HRESULT CDatabase::Open() { Clear(); - bool numFreeClustersDefined = false; + bool numFreeClusters_Defined = false; { - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); - if (!Header.Parse(buf)) + UInt32 buf32[kHeaderSize / 4]; + RINOK(ReadStream_FALSE(InStream, buf32, kHeaderSize)) + if (!Header.Parse((Byte *)(void *)buf32)) return S_FALSE; UInt64 fileSize; - RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(InStream, fileSize)) /* we comment that check to support truncated images */ /* @@ -647,61 +810,69 @@ if (Header.IsFat32()) { - SeekToSector(Header.FsInfoSector); - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); - if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) - return S_FALSE; - if (Get32(buf) == 0x41615252 && Get32(buf + 484) == 0x61417272) + if (((UInt32)Header.FsInfoSector << Header.SectorSizeLog) + kHeaderSize <= fileSize + && SeekToSector(Header.FsInfoSector) == S_OK + && ReadStream_FALSE(InStream, buf32, kHeaderSize) == S_OK + && 0xaa550000 == Get32a(buf32 + 508 / 4) + && 0x41615252 == Get32a(buf32) + && 0x61417272 == Get32a(buf32 + 484 / 4)) { - NumFreeClusters = Get32(buf + 488); - numFreeClustersDefined = (NumFreeClusters <= Header.FatSize); + NumFreeClusters = Get32a(buf32 + 488 / 4); + numFreeClusters_Defined = (NumFreeClusters <= Header.FatSize); } + else + Header.HeadersWarning = true; } } - // numFreeClustersDefined = false; // to recalculate NumFreeClusters - if (!numFreeClustersDefined) + // numFreeClusters_Defined = false; // to recalculate NumFreeClusters + if (!numFreeClusters_Defined) NumFreeClusters = 0; CByteBuffer byteBuf; Fat = new UInt32[Header.FatSize]; - RINOK(OpenProgressFat()); - RINOK(SeekToSector(Header.GetFatSector())); + RINOK(OpenProgressFat()) + RINOK(SeekToSector(Header.GetFatSector())) if (Header.NumFatBits == 32) { - const UInt32 kBufSize = (1 << 15); + const UInt32 kBufSize = 1 << 15; byteBuf.Alloc(kBufSize); - for (UInt32 i = 0; i < Header.FatSize;) + for (UInt32 i = 0;;) { UInt32 size = Header.FatSize - i; + if (size == 0) + break; const UInt32 kBufSize32 = kBufSize / 4; if (size > kBufSize32) size = kBufSize32; - UInt32 readSize = Header.SizeToSectors(size * 4) << Header.SectorSizeLog; - RINOK(ReadStream_FALSE(InStream, byteBuf, readSize)); + const UInt32 readSize = Header.SizeToSectors(size * 4) << Header.SectorSizeLog; + RINOK(ReadStream_FALSE(InStream, byteBuf, readSize)) NumCurUsedBytes += readSize; const UInt32 *src = (const UInt32 *)(const void *)(const Byte *)byteBuf; UInt32 *dest = Fat + i; - if (numFreeClustersDefined) - for (UInt32 j = 0; j < size; j++) - dest[j] = Get32(src + j) & 0x0FFFFFFF; + const UInt32 *srcLim = src + size; + if (numFreeClusters_Defined) + do + *dest++ = Get32a(src) & 0x0FFFFFFF; + while (++src != srcLim); else { UInt32 numFreeClusters = 0; - for (UInt32 j = 0; j < size; j++) + do { - UInt32 v = Get32(src + j) & 0x0FFFFFFF; + const UInt32 v = Get32a(src) & 0x0FFFFFFF; + *dest++ = v; numFreeClusters += (UInt32)(v - 1) >> 31; - dest[j] = v; } + while (++src != srcLim); NumFreeClusters += numFreeClusters; } i += size; if ((i & 0xFFFFF) == 0) { - RINOK(OpenProgressFat(!numFreeClustersDefined)); + RINOK(OpenProgressFat(!numFreeClusters_Defined)) } } } @@ -711,17 +882,17 @@ NumCurUsedBytes += kBufSize; byteBuf.Alloc(kBufSize); Byte *p = byteBuf; - RINOK(ReadStream_FALSE(InStream, p, kBufSize)); - UInt32 fatSize = Header.FatSize; + RINOK(ReadStream_FALSE(InStream, p, kBufSize)) + const UInt32 fatSize = Header.FatSize; UInt32 *fat = &Fat[0]; if (Header.NumFatBits == 16) for (UInt32 j = 0; j < fatSize; j++) - fat[j] = Get16(p + j * 2); + fat[j] = Get16a(p + j * 2); else for (UInt32 j = 0; j < fatSize; j++) fat[j] = (Get16(p + j * 3 / 2) >> ((j & 1) << 2)) & 0xFFF; - if (!numFreeClustersDefined) + if (!numFreeClusters_Defined) { UInt32 numFreeClusters = 0; for (UInt32 i = 0; i < fatSize; i++) @@ -730,7 +901,7 @@ } } - RINOK(OpenProgressFat()); + RINOK(OpenProgressFat()) if ((Fat[0] & 0xFF) != Header.MediaType) { @@ -741,28 +912,28 @@ return S_FALSE; } - RINOK(ReadDir(-1, Header.RootCluster, 0)); + RINOK(ReadDir(-1, Header.RootCluster, 0)) PhySize = Header.GetPhySize(); return S_OK; } -class CHandler: + + +Z7_class_CHandler_final: public IInArchive, + public IArchiveGetRawProps, public IInArchiveGetStream, public CMyUnknownImp, CDatabase { -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + Z7_IFACES_IMP_UNK_3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) }; -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; const CItem &item = Items[index]; CClusterInStream *streamSpec = new CClusterInStream; CMyComPtr streamTemp = streamSpec; @@ -771,7 +942,7 @@ streamSpec->BlockSizeLog = Header.ClusterSizeLog; streamSpec->Size = item.Size; - UInt32 numClusters = Header.GetNumClusters(item.Size); + const UInt32 numClusters = Header.GetNumClusters(item.Size); streamSpec->Vector.ClearAndReserve(numClusters); UInt32 cluster = item.Cluster; UInt32 size = item.Size; @@ -783,7 +954,7 @@ } else { - UInt32 clusterSize = Header.ClusterSize(); + const UInt32 clusterSize = Header.ClusterSize(); for (;; size -= clusterSize) { if (!Header.IsValidCluster(cluster)) @@ -796,12 +967,14 @@ if (!Header.IsEocAndUnused(cluster)) return S_FALSE; } - RINOK(streamSpec->InitAndSeek()); + RINOK(streamSpec->InitAndSeek()) *stream = streamTemp.Detach(); return S_OK; COM_TRY_END } + + static const Byte kProps[] = { kpidPath, @@ -813,6 +986,7 @@ kpidATime, kpidAttrib, kpidShortName + // , kpidCharacts }; enum @@ -873,7 +1047,7 @@ #define STRING_TO_PROP(s, p) StringToProp(s, sizeof(s), prop) */ -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -893,33 +1067,108 @@ case kpidPhySize: prop = PhySize; break; case kpidFreeSpace: prop = (UInt64)NumFreeClusters << Header.ClusterSizeLog; break; case kpidHeadersSize: prop = GetHeadersSize(); break; - case kpidMTime: if (VolItemDefined) PropVariant_SetFrom_DosTime(prop, VolItem.MTime); break; + case kpidMTime: if (VolItem_Defined) PropVariant_SetFrom_DosTime(prop, Vol_MTime); break; case kpidShortComment: - case kpidVolumeName: if (VolItemDefined) prop = VolItem.GetVolName(); break; + case kpidVolumeName: if (VolItem_Defined) GetVolName(VolLabel, prop); break; case kpidNumFats: if (Header.NumFats != 2) prop = Header.NumFats; break; case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; // case kpidSectorsPerTrack: prop = Header.SectorsPerTrack; break; // case kpidNumHeads: prop = Header.NumHeads; break; // case kpidOemName: STRING_TO_PROP(Header.OemName, prop); break; case kpidId: if (Header.VolFieldsDefined) prop = Header.VolId; break; + case kpidIsTree: prop = true; break; // case kpidVolName: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.VolName, prop); break; // case kpidFileSysType: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.FileSys, prop); break; // case kpidHiddenSectors: prop = Header.NumHiddenSectors; break; + case kpidWarningFlags: + { + UInt32 v = 0; + if (Header.HeadersWarning) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } } prop.Detach(value); return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */ , BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + int par = -1; + if (index < Items.Size()) + par = Items[index].Parent; + *parent = (UInt32)(Int32)par; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (index < Items.Size() + && propID == kpidName) + { + CByteBuffer &buf = Items[index].LongName; + const UInt32 size = (UInt32)buf.Size(); + if (size != 0) + { + *dataSize = size; + *propType = NPropDataType::kUtf16z; + *data = (const void *)(const Byte *)buf; + } + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; const CItem &item = Items[index]; switch (propID) { - case kpidPath: prop = GetItemPath(index); break; - case kpidShortName: prop = item.GetShortName(); break; + case kpidPath: + case kpidName: + case kpidShortName: + { + UString s; + if (propID == kpidPath) + GetItemPath(index, s); + else if (propID == kpidName) + item.GetName(s); + else + item.GetShortName(s); + prop = s; + break; + } +/* + case kpidCharacts: + { + if (item.LongName.Size()) + prop = "LFN"; + break; + } +*/ case kpidIsDir: prop = item.IsDir(); break; case kpidMTime: PropVariant_SetFrom_DosTime(prop, item.MTime); break; case kpidCTime: FatTimeToProp(item.CTime, item.CTime2, prop); break; @@ -933,7 +1182,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { @@ -957,96 +1206,107 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { ClearAndClose(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) + if (numItems == (UInt32)(Int32)-1) + { + indices = NULL; numItems = Items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; + if (numItems == 0) + return S_OK; + } + else + { + if (numItems == 0) + return S_OK; + if (!indices) + return E_INVALIDARG; + } UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) { - const CItem &item = Items[allFilesMode ? i : indices[i]]; - if (!item.IsDir()) - totalSize += item.Size; + UInt32 i = 0; + do + { + UInt32 index = i; + if (indices) + index = indices[i]; + const CItem &item = Items[index]; + if (!item.IsDir()) + totalSize += item.Size; + } + while (++i != numItems); } - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 totalPackSize; - totalSize = totalPackSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + RINOK(extractCallback->SetTotal(totalSize)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); + UInt64 totalPackSize; + totalSize = totalPackSize = 0; - for (i = 0; i < numItems; i++) + UInt32 i; + for (i = 0;; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = Items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - totalPackSize += Header.GetFilePackSize(item.Size); - totalSize += item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(); - - int res = NExtract::NOperationResult::kDataError; - CMyComPtr inStream; - HRESULT hres = GetStream(index, &inStream); - if (hres != S_FALSE) + RINOK(lps->SetCur()) + if (i == numItems) + break; + int res; { - RINOK(hres); - if (inStream) + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + UInt32 index = i; + if (indices) + index = indices[i]; + const CItem &item = Items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) { - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) - res = NExtract::NOperationResult::kOK; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + totalPackSize += Header.GetFilePackSize(item.Size); + totalSize += item.Size; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + res = NExtract::NOperationResult::kDataError; + CMyComPtr inStream; + const HRESULT hres = GetStream(index, &inStream); + if (hres != S_FALSE) + { + RINOK(hres) + if (inStream) + { + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) + res = NExtract::NOperationResult::kOK; + } } } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = Items.Size(); return S_OK; @@ -1055,7 +1315,7 @@ static const Byte k_Signature[] = { 0x55, 0xAA }; REGISTER_ARC_I( - "FAT", "fat img", 0, 0xDA, + "FAT", "fat img", NULL, 0xDA, k_Signature, 0x1FE, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/FlvHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FlvHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/FlvHandler.cpp 2021-01-26 09:45:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/FlvHandler.cpp 2023-03-26 12:00:00.000000000 +0000 @@ -64,11 +64,10 @@ bool IsAudio() const { return Type == kType_Audio; } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CMyComPtr _stream; CObjectVector _items2; CByteBuffer _metadata; @@ -77,10 +76,6 @@ HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); // AString GetComment(); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; static const Byte kProps[] = @@ -141,7 +136,7 @@ , "44 kHz" }; -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; const CItem2 &item = _items2[index]; @@ -252,7 +247,7 @@ } */ -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { // COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -271,7 +266,7 @@ { const UInt32 kHeaderSize = 13; Byte header[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, header, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, header, kHeaderSize)) if (header[0] != 'F' || header[1] != 'L' || header[2] != 'V' || @@ -358,7 +353,7 @@ item2.Props = props; item2.NumChunks = 1; item2.SameSubTypes = true; - lasts[item.Type] = _items2.Add(item2); + lasts[item.Type] = (int)_items2.Add(item2); } else { @@ -420,7 +415,7 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); @@ -441,7 +436,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; _stream.Release(); @@ -450,17 +445,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items2.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items2.Size(); if (numItems == 0) @@ -480,32 +475,32 @@ for (i = 0; i < numItems; i++) { lps->InSize = lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CItem2 &item = _items2[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) totalSize += item.Size; if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (outStream) { - RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.Size())); + RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.Size())) } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; CBufInStream *streamSpec = new CBufInStream; CMyComPtr streamTemp = streamSpec; streamSpec->Init(_items2[index].BufSpec); @@ -517,7 +512,7 @@ static const Byte k_Signature[] = { 'F', 'L', 'V', 1, }; REGISTER_ARC_I( - "FLV", "flv", 0, 0xD6, + "FLV", "flv", NULL, 0xD6, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/GptHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GptHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/GptHandler.cpp 2021-12-29 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GptHandler.cpp 2024-06-27 20:00:00.000000000 +0000 @@ -24,18 +24,19 @@ namespace NArchive { +namespace NMbr { +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize); +} + namespace NFat { API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size); } namespace NGpt { -#define SIGNATURE { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 } - static const unsigned k_SignatureSize = 12; -static const Byte k_Signature[k_SignatureSize] = SIGNATURE; - -static const UInt32 kSectorSize = 512; +static const Byte k_Signature[k_SignatureSize] = + { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }; static const CUInt32PCharPair g_PartitionFlags[] = { @@ -67,9 +68,9 @@ return true; } - UInt64 GetSize() const { return (LastLba - FirstLba + 1) * kSectorSize; } - UInt64 GetPos() const { return FirstLba * kSectorSize; } - UInt64 GetEnd() const { return (LastLba + 1) * kSectorSize; } + UInt64 GetSize(unsigned sectorSizeLog) const { return (LastLba - FirstLba + 1) << sectorSizeLog; } + UInt64 GetPos(unsigned sectorSizeLog) const { return FirstLba << sectorSizeLog; } + UInt64 GetEnd(unsigned sectorSizeLog) const { return (LastLba + 1) << sectorSizeLog; } void Parse(const Byte *p) { @@ -93,29 +94,35 @@ static const CPartType kPartTypes[] = { - // { 0x0, 0, "Unused" }, + // { 0x0, NULL, "Unused" }, - { 0x21686148, 0, "BIOS Boot" }, + { 0x21686148, NULL, "BIOS Boot" }, - { 0xC12A7328, 0, "EFI System" }, - { 0x024DEE41, 0, "MBR" }, + { 0xC12A7328, NULL, "EFI System" }, + { 0x024DEE41, NULL, "MBR" }, - { 0xE3C9E316, 0, "Windows MSR" }, - { 0xEBD0A0A2, 0, "Windows BDP" }, - { 0x5808C8AA, 0, "Windows LDM Metadata" }, - { 0xAF9B60A0, 0, "Windows LDM Data" }, - { 0xDE94BBA4, 0, "Windows Recovery" }, - // { 0x37AFFC90, 0, "IBM GPFS" }, - // { 0xE75CAF8F, 0, "Windows Storage Spaces" }, - - { 0x0FC63DAF, 0, "Linux Data" }, - { 0x0657FD6D, 0, "Linux Swap" }, - - { 0x83BD6B9D, 0, "FreeBSD Boot" }, - { 0x516E7CB4, 0, "FreeBSD Data" }, - { 0x516E7CB5, 0, "FreeBSD Swap" }, + { 0xE3C9E316, NULL, "Windows MSR" }, + { 0xEBD0A0A2, NULL, "Windows BDP" }, + { 0x5808C8AA, NULL, "Windows LDM Metadata" }, + { 0xAF9B60A0, NULL, "Windows LDM Data" }, + { 0xDE94BBA4, NULL, "Windows Recovery" }, + // { 0x37AFFC90, NULL, "IBM GPFS" }, + // { 0xE75CAF8F, NULL, "Windows Storage Spaces" }, + + { 0x0FC63DAF, NULL, "Linux Data" }, + { 0x0657FD6D, NULL, "Linux Swap" }, + { 0x44479540, NULL, "Linux root (x86)" }, + { 0x4F68BCE3, NULL, "Linux root (x86-64)" }, + { 0x69DAD710, NULL, "Linux root (ARM)" }, + { 0xB921B045, NULL, "Linux root (ARM64)" }, + { 0x993D8D3D, NULL, "Linux root (IA-64)" }, + + + { 0x83BD6B9D, NULL, "FreeBSD Boot" }, + { 0x516E7CB4, NULL, "FreeBSD Data" }, + { 0x516E7CB5, NULL, "FreeBSD Swap" }, { 0x516E7CB6, "ufs", "FreeBSD UFS" }, - { 0x516E7CB8, 0, "FreeBSD Vinum" }, + { 0x516E7CB8, NULL, "FreeBSD Vinum" }, { 0x516E7CB8, "zfs", "FreeBSD ZFS" }, { 0x48465300, "hfsx", "HFS+" }, @@ -124,10 +131,10 @@ static int FindPartType(const Byte *guid) { - UInt32 val = Get32(guid); - for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++) + const UInt32 val = Get32(guid); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPartTypes); i++) if (kPartTypes[i].Id == val) - return i; + return (int)i; return -1; } @@ -139,79 +146,86 @@ } -class CHandler: public CHandlerCont +Z7_class_CHandler_final: public CHandlerCont { + Z7_IFACE_COM7_IMP(IInArchive_Cont) + CRecordVector _items; UInt64 _totalSize; + unsigned _sectorSizeLog; Byte Guid[16]; CByteBuffer _buffer; HRESULT Open2(IInStream *stream); - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override { const CPartition &item = _items[index]; - pos = item.GetPos(); - size = item.GetSize(); + pos = item.GetPos(_sectorSizeLog); + size = item.GetSize(_sectorSizeLog); return NExtract::NOperationResult::kOK; } - -public: - INTERFACE_IInArchive_Cont(;) }; HRESULT CHandler::Open2(IInStream *stream) { - _buffer.Alloc(kSectorSize * 2); - RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2)); - + const unsigned kBufSize = 2 << 12; + _buffer.Alloc(kBufSize); + RINOK(ReadStream_FALSE(stream, _buffer, kBufSize)) const Byte *buf = _buffer; if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) return S_FALSE; - - buf += kSectorSize; - if (memcmp(buf, k_Signature, k_SignatureSize) != 0) - return S_FALSE; + { + for (unsigned sectorSizeLog = 9;; sectorSizeLog += 3) + { + if (sectorSizeLog > 12) + return S_FALSE; + if (memcmp(buf + ((size_t)1 << sectorSizeLog), k_Signature, k_SignatureSize) == 0) + { + buf += ((size_t)1 << sectorSizeLog); + _sectorSizeLog = sectorSizeLog; + break; + } + } + } + const UInt32 kSectorSize = 1u << _sectorSizeLog; { // if (Get32(buf + 8) != 0x10000) return S_FALSE; // revision - UInt32 headerSize = Get32(buf + 12); // = 0x5C usually + const UInt32 headerSize = Get32(buf + 12); // = 0x5C usually if (headerSize > kSectorSize) return S_FALSE; - UInt32 crc = Get32(buf + 0x10); - SetUi32(_buffer + kSectorSize + 0x10, 0); + const UInt32 crc = Get32(buf + 0x10); + SetUi32(_buffer + kSectorSize + 0x10, 0) if (CrcCalc(_buffer + kSectorSize, headerSize) != crc) return S_FALSE; } // UInt32 reserved = Get32(buf + 0x14); - UInt64 curLba = Get64(buf + 0x18); + const UInt64 curLba = Get64(buf + 0x18); if (curLba != 1) return S_FALSE; - UInt64 backupLba = Get64(buf + 0x20); + const UInt64 backupLba = Get64(buf + 0x20); // UInt64 firstUsableLba = Get64(buf + 0x28); // UInt64 lastUsableLba = Get64(buf + 0x30); memcpy(Guid, buf + 0x38, 16); - UInt64 tableLba = Get64(buf + 0x48); - if (tableLba < 2) + const UInt64 tableLba = Get64(buf + 0x48); + if (tableLba < 2 || (tableLba >> (63 - _sectorSizeLog)) != 0) return S_FALSE; - UInt32 numEntries = Get32(buf + 0x50); - UInt32 entrySize = Get32(buf + 0x54); // = 128 usually - UInt32 entriesCrc = Get32(buf + 0x58); - - if (entrySize < 128 - || entrySize > (1 << 12) - || numEntries > (1 << 16) - || tableLba < 2 - || tableLba >= ((UInt64)1 << (64 - 10))) + const UInt32 numEntries = Get32(buf + 0x50); + if (numEntries > (1 << 16)) + return S_FALSE; + const UInt32 entrySize = Get32(buf + 0x54); // = 128 usually + if (entrySize < 128 || entrySize > (1 << 12)) return S_FALSE; + const UInt32 entriesCrc = Get32(buf + 0x58); - UInt32 tableSize = entrySize * numEntries; - UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1); + const UInt32 tableSize = entrySize * numEntries; + const UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1); _buffer.Alloc(tableSizeAligned); - UInt64 tableOffset = tableLba * kSectorSize; - RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned)); + const UInt64 tableOffset = tableLba * kSectorSize; + RINOK(InStream_SeekSet(stream, tableOffset)) + RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned)) if (CrcCalc(_buffer, tableSize) != entriesCrc) return S_FALSE; @@ -224,21 +238,27 @@ item.Parse(_buffer + i * entrySize); if (item.IsUnused()) continue; - UInt64 endPos = item.GetEnd(); + if (item.LastLba < item.FirstLba) + return S_FALSE; + if ((item.LastLba >> (63 - _sectorSizeLog)) != 0) + return S_FALSE; + const UInt64 endPos = item.GetEnd(_sectorSizeLog); if (_totalSize < endPos) _totalSize = endPos; _items.Add(item); } - + + _buffer.Free(); { + if ((backupLba >> (63 - _sectorSizeLog)) != 0) + return S_FALSE; const UInt64 end = (backupLba + 1) * kSectorSize; if (_totalSize < end) _totalSize = end; } - { UInt64 fileEnd; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileEnd)); + RINOK(InStream_GetSize_SeekToEnd(stream, fileEnd)) if (_totalSize < fileEnd) { @@ -246,7 +266,7 @@ const UInt64 kRemMax = 1 << 22; if (rem <= kRemMax) { - RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, _totalSize)) bool areThereNonZeros = false; UInt64 numZeros = 0; if (ReadZeroTail(stream, areThereNonZeros, numZeros, kRemMax) == S_OK) @@ -260,34 +280,13 @@ } - -static const unsigned k_Ntfs_Fat_HeaderSize = 512; - -static const Byte k_NtfsSignature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; - -static bool IsNtfs(const Byte *p) -{ - if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) - return false; - if (memcmp(p + 3, k_NtfsSignature, ARRAY_SIZE(k_NtfsSignature)) != 0) - return false; - switch (p[0]) - { - case 0xE9: /* codeOffset = 3 + (Int16)Get16(p + 1); */ break; - case 0xEB: if (p[2] != 0x90) return false; /* codeOffset = 2 + (int)(signed char)p[1]; */ break; - default: return false; - } - return true; -} - - -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - RINOK(Open2(stream)); + RINOK(Open2(stream)) _stream = stream; FOR_VECTOR (fileIndex, _items) @@ -305,22 +304,13 @@ if (t.Type && IsString1PrefixedByString2_NoCase_Ascii(t.Type, "Windows")) { CMyComPtr inStream; - if (GetStream(fileIndex, &inStream) == S_OK && inStream) + if ( + // ((IInArchiveGetStream *)this)-> + GetStream(fileIndex, &inStream) == S_OK && inStream) { - Byte temp[k_Ntfs_Fat_HeaderSize]; - if (ReadStream_FAIL(inStream, temp, k_Ntfs_Fat_HeaderSize) == S_OK) - { - if (IsNtfs(temp)) - { - item.Ext = "ntfs"; - continue; - } - if (NFat::IsArc_Fat(temp, k_Ntfs_Fat_HeaderSize) == k_IsArc_Res_YES) - { - item.Ext = "fat"; - continue; - } - } + const char *fs = NMbr::GetFileSystem(inStream, item.GetSize(_sectorSizeLog)); + if (fs) + item.Ext = fs; } } } @@ -329,8 +319,9 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { + _sectorSizeLog = 0; _totalSize = 0; memset(Guid, 0, sizeof(Guid)); _items.Clear(); @@ -350,13 +341,14 @@ static const Byte kArcProps[] = { + kpidSectorSize, kpidId }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -369,6 +361,7 @@ break; } case kpidPhySize: prop = _totalSize; break; + case kpidSectorSize: prop = (UInt32)((UInt32)1 << _sectorSizeLog); break; case kpidId: { char s[48]; @@ -382,13 +375,13 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -414,21 +407,28 @@ } if (!s2.IsEmpty()) { - s += '.'; + s.Add_Dot(); s += s2; } } { - s += '.'; - s += (item.Ext ? item.Ext : "img"); + s.Add_Dot(); + if (item.Ext) + { + AString fs (item.Ext); + fs.MakeLower_Ascii(); + s += fs; + } + else + s += "img"; } prop = s; break; } case kpidSize: - case kpidPackSize: prop = item.GetSize(); break; - case kpidOffset: prop = item.GetPos(); break; + case kpidPackSize: prop = item.GetSize(_sectorSizeLog); break; + case kpidOffset: prop = item.GetPos(_sectorSizeLog); break; case kpidFileSystem: { @@ -462,10 +462,11 @@ COM_TRY_END } +// we suppport signature only for 512-bytes sector. REGISTER_ARC_I( "GPT", "gpt mbr", NULL, 0xCB, k_Signature, - kSectorSize, + 1 << 9, 0, NULL) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/GzHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GzHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/GzHandler.cpp 2022-05-09 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/GzHandler.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -10,7 +10,6 @@ #include "../../Common/Defs.h" #include "../../Common/StringConvert.h" -#include "../../Windows/PropVariant.h" #include "../../Windows/PropVariantUtils.h" #include "../../Windows/TimeUtils.h" @@ -206,13 +205,13 @@ s.Empty(); for (size_t i = 0; i < limit; i++) { - Byte b = stream->ReadAlignedByte(); + const Byte b = stream->ReadAlignedByte(); if (stream->InputEofError()) return S_FALSE; // crc = CRC_UPDATE_BYTE(crc, b); if (b == 0) return S_OK; - s += (char)b; + s.Add_Char((char)b); } return S_FALSE; } @@ -229,7 +228,7 @@ return k_IsArc_Res_NO; if (type == 0) { - // Stored (uncompreessed data) + // Stored (uncompreessed data) if ((b >> 3) != 0) return k_IsArc_Res_NO; if (size < 4) @@ -261,11 +260,11 @@ p[2] != kSignature_2) return k_IsArc_Res_NO; - Byte flags = p[3]; + const Byte flags = p[3]; if ((flags & NFlags::kReserved) != 0) return k_IsArc_Res_NO; - Byte extraFlags = p[8]; + const Byte extraFlags = p[8]; // maybe that flag can have another values for some gz archives? if (extraFlags != 0 && extraFlags != NExtraFlags::kMaximum && @@ -288,7 +287,7 @@ return k_IsArc_Res_NO; if (size < 4) return k_IsArc_Res_NEED_MORE; - unsigned len = GetUi16(p + 2); + const unsigned len = GetUi16(p + 2); size -= 4; xlen -= 4; p += 4; @@ -354,7 +353,7 @@ // UInt32 crc = CRC_INIT_VAL; Byte buf[10]; - RINOK(ReadBytes(stream, buf, 10)); + RINOK(ReadBytes(stream, buf, 10)) if (buf[0] != kSignature_0 || buf[1] != kSignature_1 || @@ -374,22 +373,22 @@ if (ExtraFieldIsPresent()) { UInt32 xlen; - RINOK(ReadUInt16(stream, xlen /* , crc */)); - RINOK(SkipBytes(stream, xlen)); + RINOK(ReadUInt16(stream, xlen /* , crc */)) + RINOK(SkipBytes(stream, xlen)) // Extra.SetCapacity(xlen); // RINOK(ReadStream_FALSE(stream, Extra, xlen)); // crc = CrcUpdate(crc, Extra, xlen); } if (NameIsPresent()) - RINOK(ReadString(stream, Name, kNameMaxLen /* , crc */)); + RINOK(ReadString(stream, Name, kNameMaxLen /* , crc */)) if (CommentIsPresent()) - RINOK(ReadString(stream, Comment, kCommentMaxLen /* , crc */)); + RINOK(ReadString(stream, Comment, kCommentMaxLen /* , crc */)) if (HeaderCrcIsPresent()) { UInt32 headerCRC; // UInt32 dummy = 0; - RINOK(ReadUInt16(stream, headerCRC /* , dummy */)); + RINOK(ReadUInt16(stream, headerCRC /* , dummy */)) /* if ((UInt16)CRC_GET_DIGEST(crc) != headerCRC) return S_FALSE; @@ -401,7 +400,7 @@ HRESULT CItem::ReadFooter1(NDecoder::CCOMCoder *stream) { Byte buf[8]; - RINOK(ReadBytes(stream, buf, 8)); + RINOK(ReadBytes(stream, buf, 8)) Crc = Get32(buf); Size32 = Get32(buf + 4); return stream->InputEofError() ? S_FALSE : S_OK; @@ -410,7 +409,7 @@ HRESULT CItem::ReadFooter2(ISequentialInStream *stream) { Byte buf[8]; - RINOK(ReadStream_FALSE(stream, buf, 8)); + RINOK(ReadStream_FALSE(stream, buf, 8)) Crc = Get32(buf); Size32 = Get32(buf + 4); return S_OK; @@ -424,15 +423,15 @@ buf[2] = kSignature_2; buf[3] = (Byte)(Flags & NFlags::kName); // buf[3] |= NFlags::kCrc; - SetUi32(buf + 4, Time); + SetUi32(buf + 4, Time) buf[8] = ExtraFlags; buf[9] = HostOS; - RINOK(WriteStream(stream, buf, 10)); + RINOK(WriteStream(stream, buf, 10)) // crc = CrcUpdate(CRC_INIT_VAL, buf, 10); if (NameIsPresent()) { // crc = CrcUpdate(crc, (const char *)Name, Name.Len() + 1); - RINOK(WriteStream(stream, (const char *)Name, Name.Len() + 1)); + RINOK(WriteStream(stream, (const char *)Name, Name.Len() + 1)) } // SetUi16(buf, (UInt16)CRC_GET_DIGEST(crc)); // RINOK(WriteStream(stream, buf, 2)); @@ -442,18 +441,16 @@ HRESULT CItem::WriteFooter(ISequentialOutStream *stream) { Byte buf[8]; - SetUi32(buf, Crc); - SetUi32(buf + 4, Size32); + SetUi32(buf, Crc) + SetUi32(buf + 4, Size32) return WriteStream(stream, buf, 8); } -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveOpenSeq, + IOutArchive, + ISetProperties +) CItem _item; bool _isArc; @@ -471,34 +468,19 @@ UInt64 _headerSize; // only start header (without footer) CMyComPtr _stream; - CMyComPtr _decoder; - NDecoder::CCOMCoder *_decoderSpec; + CMyComPtr2 _decoder; CSingleMethodProps _props; CHandlerTimeOptions _timeOptions; public: - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveOpenSeq, - IOutArchive, - ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - CHandler(): - _isArc(false), - _decoderSpec(NULL) + _isArc(false) {} void CreateDecoder() { - if (_decoder) - return; - _decoderSpec = new NDecoder::CCOMCoder; - _decoder = _decoderSpec; + _decoder.Create_if_Empty(); } }; @@ -523,7 +505,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -550,6 +532,7 @@ prop = s; } break; + default: break; } prop.Detach(value); return S_OK; @@ -557,13 +540,13 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -599,25 +582,24 @@ } case kpidHostOS: TYPE_TO_PROP(kHostOSes, _item.HostOS, prop); break; case kpidCRC: if (_stream) prop = _item.Crc; break; + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) CMyComPtr Callback; public: UInt64 Offset; - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); void Init(IArchiveOpenCallback *callback) { Callback = callback; } }; -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { @@ -631,15 +613,15 @@ /* */ -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) { COM_TRY_BEGIN - RINOK(OpenSeq(stream)); + RINOK(OpenSeq(stream)) _isArc = false; UInt64 endPos; - RINOK(stream->Seek(-8, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(-8, STREAM_SEEK_END, &endPos)) _packSize = endPos + 8; - RINOK(_item.ReadFooter2(stream)); + RINOK(_item.ReadFooter2(stream)) _stream = stream; _isArc = true; _needSeekToStart = true; @@ -647,19 +629,19 @@ COM_TRY_END } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { COM_TRY_BEGIN try { Close(); CreateDecoder(); - _decoderSpec->SetInStream(stream); - _decoderSpec->InitInStream(true); - RINOK(_item.ReadHeader(_decoderSpec)); - if (_decoderSpec->InputEofError()) + _decoder->SetInStream(stream); + _decoder->InitInStream(true); + RINOK(_item.ReadHeader(_decoder.ClsPtr())) + if (_decoder->InputEofError()) return S_FALSE; - _headerSize = _decoderSpec->GetInputProcessedSize(); + _headerSize = _decoder->GetInputProcessedSize(); _isArc = true; return S_OK; } @@ -667,7 +649,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _needSeekToStart = false; @@ -683,12 +665,12 @@ _stream.Release(); if (_decoder) - _decoderSpec->ReleaseInStream(); + _decoder->ReleaseInStream(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -697,29 +679,29 @@ return E_INVALIDARG; if (_packSize_Defined) - extractCallback->SetTotal(_packSize); + RINOK(extractCallback->SetTotal(_packSize)) // UInt64 currentTotalPacked = 0; // RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + Int32 retResult; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) CreateDecoder(); - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); bool needReadFirstItem = _needSeekToStart; @@ -728,8 +710,8 @@ { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - _decoderSpec->InitInStream(true); + RINOK(InStream_SeekToBegin(_stream)) + _decoder->InitInStream(true); // printf("\nSeek"); } else @@ -737,7 +719,7 @@ bool firstItem = true; - UInt64 packSize = _decoderSpec->GetInputProcessedSize(); + UInt64 packSize = _decoder->GetInputProcessedSize(); // printf("\npackSize = %d", (unsigned)packSize); UInt64 unpackedSize = 0; @@ -754,18 +736,18 @@ lps->InSize = packSize; lps->OutSize = unpackedSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CItem item; if (!firstItem || needReadFirstItem) { - result = item.ReadHeader(_decoderSpec); + result = item.ReadHeader(_decoder.ClsPtr()); if (result != S_OK && result != S_FALSE) return result; - if (_decoderSpec->InputEofError()) + if (_decoder->InputEofError()) result = S_FALSE; if (result != S_OK && firstItem) @@ -774,7 +756,7 @@ break; } - if (packSize == _decoderSpec->GetStreamSize()) + if (packSize == _decoder->GetStreamSize()) { result = S_OK; break; @@ -790,20 +772,20 @@ numStreams++; firstItem = false; - UInt64 startOffset = outStreamSpec->GetSize(); - outStreamSpec->InitCRC(); + const UInt64 startOffset = outStream->GetSize(); + outStream->InitCRC(); - result = _decoderSpec->CodeResume(outStream, NULL, progress); + result = _decoder->CodeResume(outStream, NULL, lps); - packSize = _decoderSpec->GetInputProcessedSize(); - unpackedSize = outStreamSpec->GetSize(); + packSize = _decoder->GetInputProcessedSize(); + unpackedSize = outStream->GetSize(); if (result != S_OK && result != S_FALSE) return result; - if (_decoderSpec->InputEofError()) + if (_decoder->InputEofError()) { - packSize = _decoderSpec->GetStreamSize(); + packSize = _decoder->GetStreamSize(); _needMoreInput = true; result = S_FALSE; } @@ -811,18 +793,18 @@ if (result != S_OK) break; - _decoderSpec->AlignToByte(); + _decoder->AlignToByte(); - result = item.ReadFooter1(_decoderSpec); + result = item.ReadFooter1(_decoder.ClsPtr()); - packSize = _decoderSpec->GetInputProcessedSize(); + packSize = _decoder->GetInputProcessedSize(); if (result != S_OK && result != S_FALSE) return result; if (result != S_OK) { - if (_decoderSpec->InputEofError()) + if (_decoder->InputEofError()) { _needMoreInput = true; result = S_FALSE; @@ -830,7 +812,7 @@ break; } - if (item.Crc != outStreamSpec->GetCRC() || + if (item.Crc != outStream->GetCRC() || item.Size32 != (UInt32)(unpackedSize - startOffset)) { crcError = true; @@ -854,9 +836,9 @@ _numStreams_Defined = true; } - outStream.Release(); + // outStream.Release(); - Int32 retResult = NExtract::NOperationResult::kDataError; + retResult = NExtract::NOperationResult::kDataError; if (!_isArc) retResult = NExtract::NOperationResult::kIsNotArc; @@ -872,10 +854,9 @@ retResult = NExtract::NOperationResult::kOK; else return result; + } return extractCallback->SetOperationResult(retResult); - - COM_TRY_END } @@ -954,14 +935,15 @@ { CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); + RINOK(updateCallback->GetStream(0, &fileInStream)) if (!fileInStream) return S_FALSE; { - CMyComPtr getProps; - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetProps, + getProps, fileInStream) if (getProps) { FILETIME mTime; @@ -976,16 +958,14 @@ } UInt64 complexity = 0; - RINOK(updateCallback->SetTotal(unpackSize)); - RINOK(updateCallback->SetCompleted(&complexity)); + RINOK(updateCallback->SetTotal(unpackSize)) + RINOK(updateCallback->SetCompleted(&complexity)) - CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC; - CMyComPtr crcStream(inStreamSpec); - inStreamSpec->SetStream(fileInStream); - inStreamSpec->Init(); + CMyComPtr2_Create crcStream; + crcStream->SetStream(fileInStream); + crcStream->Init(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); item.ExtraFlags = props.GetLevel() >= 7 ? @@ -994,17 +974,17 @@ item.HostOS = kHostOS; - RINOK(item.WriteHeader(outStream)); + RINOK(item.WriteHeader(outStream)) - NEncoder::CCOMCoder *deflateEncoderSpec = new NEncoder::CCOMCoder; - CMyComPtr deflateEncoder = deflateEncoderSpec; - RINOK(props.SetCoderProps(deflateEncoderSpec, NULL)); - RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress)); + CMyComPtr2_Create deflateEncoder; - item.Crc = inStreamSpec->GetCRC(); - unpackSizeReal = inStreamSpec->GetSize(); + RINOK(props.SetCoderProps(deflateEncoder.ClsPtr(), NULL)) + RINOK(deflateEncoder.Interface()->Code(crcStream, outStream, NULL, NULL, lps)) + + item.Crc = crcStream->GetCRC(); + unpackSizeReal = crcStream->GetSize(); item.Size32 = (UInt32)unpackSizeReal; - RINOK(item.WriteFooter(outStream)); + RINOK(item.WriteFooter(outStream)) } /* if (reportArcProp) @@ -1020,7 +1000,7 @@ } -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { /* if (_item.Time != 0) @@ -1049,24 +1029,29 @@ return S_OK; } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN if (numItems != 1) return E_INVALIDARG; + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) - /* - CMyComPtr reportArcProp; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); - */ + // Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, reportArcProp, updateCallback) CItem newItem; @@ -1080,7 +1065,7 @@ if (_timeOptions.Write_MTime.Val) { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidMTime, &prop)); + RINOK(updateCallback->GetProperty(0, kpidMTime, &prop)) if (prop.vt == VT_FILETIME) NTime::FileTime_To_UnixTime(prop.filetime, newItem.Time); else if (prop.vt == VT_EMPTY) @@ -1090,7 +1075,7 @@ } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidPath, &prop)); + RINOK(updateCallback->GetProperty(0, kpidPath, &prop)) if (prop.vt == VT_BSTR) { UString name = prop.bstrVal; @@ -1106,7 +1091,7 @@ } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) if (prop.vt != VT_EMPTY) if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; @@ -1118,7 +1103,7 @@ UInt64 size; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; @@ -1132,12 +1117,12 @@ if (!_stream) return E_NOTIMPL; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) if (opCallback) { RINOK(opCallback->ReportOperation( @@ -1153,7 +1138,7 @@ newItem.WriteHeader(outStream); offset += _headerSize; } - RINOK(_stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, offset)) /* if (reportArcProp) @@ -1163,12 +1148,12 @@ NULL); // unpacksize */ - return NCompress::CopyStream(_stream, outStream, progress); + return NCompress::CopyStream(_stream, outStream, lps); COM_TRY_END } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { _timeOptions.Init(); _props.Init(); @@ -1182,7 +1167,7 @@ const PROPVARIANT &value = values[i]; { bool processed = false; - RINOK(_timeOptions.Parse(name, value, processed)); + RINOK(_timeOptions.Parse(name, value, processed)) if (processed) { if (_timeOptions.Write_CTime.Val || @@ -1197,7 +1182,7 @@ continue; } } - RINOK(_props.SetProperty(name, value)); + RINOK(_props.SetProperty(name, value)) } return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/HandlerCont.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/HandlerCont.cpp 2022-01-31 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.cpp 2023-12-18 16:00:00.000000000 +0000 @@ -18,14 +18,14 @@ API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size); } -STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) { - RINOK(GetNumberOfItems(&numItems)); + RINOK(GetNumberOfItems(&numItems)) } if (numItems == 0) return S_OK; @@ -37,33 +37,31 @@ GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size); totalSize += size; } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) totalSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); + CMyComPtr2_Create streamSpec; streamSpec->SetStream(_stream); + CMyComPtr2_Create copyCoder; - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { lps->InSize = totalSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; + CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) UInt64 pos, size; int opRes = GetItem_ExtractInfo(index, pos, size); @@ -71,32 +69,31 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (opRes == NExtract::NOperationResult::kOK) { - RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, pos)) streamSpec->Init(size); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, lps)) opRes = NExtract::NOperationResult::kDataError; - - if (copyCoderSpec->TotalSize == size) + if (copyCoder->TotalSize == size) opRes = NExtract::NOperationResult::kOK; - else if (copyCoderSpec->TotalSize < size) + else if (copyCoder->TotalSize < size) opRes = NExtract::NOperationResult::kUnexpectedEnd; } outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; @@ -114,7 +111,7 @@ Clear_HandlerImg_Vars(); } -STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -129,29 +126,34 @@ *newPosition = _virtPos; return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; } - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }; +static const Byte k_GDP_Signature[] = + { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }; // static const Byte k_Ext_Signature[] = { 0x53, 0xEF }; // static const unsigned k_Ext_Signature_offset = 0x438; static const char *GetImgExt(ISequentialInStream *stream) { - const size_t kHeaderSize = 1 << 11; + // const size_t kHeaderSize_for_Ext = (1 << 11); // for ext + const size_t kHeaderSize = 2 << 12; // for 4 KB sector GPT Byte buf[kHeaderSize]; - if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK) + size_t processed = kHeaderSize; + if (ReadStream(stream, buf, &processed) == S_OK) { + if (processed >= kHeaderSize) if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) { - if (memcmp(buf + 512, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0) - return "gpt"; + for (unsigned k = (1 << 9); k <= (1u << 12); k <<= 3) + if (memcmp(buf + k, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0) + return "gpt"; return "mbr"; } - if (NExt::IsArc_Ext(buf, kHeaderSize) == k_IsArc_Res_YES) + if (NExt::IsArc_Ext(buf, processed) == k_IsArc_Res_YES) return "ext"; } return NULL; @@ -171,9 +173,9 @@ Reset_PosInArc(); } -STDMETHODIMP CHandlerImg::Open(IInStream *stream, +Z7_COM7F_IMF(CHandlerImg::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * openCallback) + IArchiveOpenCallback * openCallback)) { COM_TRY_BEGIN { @@ -209,31 +211,26 @@ COM_TRY_END } -STDMETHODIMP CHandlerImg::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandlerImg::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -class CHandlerImgProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CHandlerImgProgress + , ICompressProgressInfo +) public: CHandlerImg &Handler; CMyComPtr _ratioProgress; CHandlerImgProgress(CHandlerImg &handler) : Handler(handler) {} - - // MY_UNKNOWN_IMP1(ICompressProgressInfo) - MY_UNKNOWN_IMP - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -STDMETHODIMP CHandlerImgProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CHandlerImgProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { UInt64 inSize2; if (Handler.Get_PackSizeProcessed(inSize2)) @@ -242,8 +239,8 @@ } -STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -251,15 +248,15 @@ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - RINOK(extractCallback->SetTotal(_size)); + RINOK(extractCallback->SetTotal(_size)) CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &outStream, askMode)); + RINOK(extractCallback->GetStream(0, &outStream, askMode)) if (!testMode && !outStream) return S_OK; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) int opRes = NExtract::NOperationResult::kDataError; @@ -285,13 +282,12 @@ progress = imgProgress; } - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + CMyComPtr2_Create copyCoder; - hres = copyCoder->Code(inStream, outStream, NULL, &_size, progress); + hres = copyCoder.Interface()->Code(inStream, outStream, NULL, &_size, progress); if (hres == S_OK) { - if (copyCoderSpec->TotalSize == _size) + if (copyCoder->TotalSize == _size) opRes = NExtract::NOperationResult::kOK; if (_stream_unavailData) @@ -300,7 +296,7 @@ opRes = NExtract::NOperationResult::kUnsupportedMethod; else if (_stream_dataError) opRes = NExtract::NOperationResult::kDataError; - else if (copyCoderSpec->TotalSize < _size) + else if (copyCoder->TotalSize < _size) opRes = NExtract::NOperationResult::kUnexpectedEnd; } } @@ -322,30 +318,4 @@ COM_TRY_END } - -HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) -{ - areThereNonZeros = false; - numZeros = 0; - const size_t kBufSize = 1 << 11; - Byte buf[kBufSize]; - for (;;) - { - UInt32 size = 0; - RINOK(stream->Read(buf, kBufSize, &size)); - if (size == 0) - return S_OK; - for (UInt32 i = 0; i < size; i++) - if (buf[i] != 0) - { - areThereNonZeros = true; - numZeros += i; - return S_OK; - } - numZeros += size; - if (numZeros > maxSize) - return S_OK; - } -} - } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/HandlerCont.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/HandlerCont.h 2022-04-30 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HandlerCont.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // HandlerCont.h -#ifndef __HANDLER_CONT_H -#define __HANDLER_CONT_H +#ifndef ZIP7_INC_HANDLER_CONT_H +#define ZIP7_INC_HANDLER_CONT_H #include "../../Common/MyCom.h" @@ -9,75 +9,89 @@ namespace NArchive { -#define INTERFACE_IInArchive_Cont(x) \ - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ +#define Z7_IFACEM_IInArchive_Cont(x) \ + x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \ + x(Close()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + /* x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) */ \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ +// #define Z7_COM7F_PUREO(f) virtual Z7_COM7F_IMF(f) Z7_override =0; +// #define Z7_COM7F_PUREO2(t, f) virtual Z7_COM7F_IMF2(t, f) Z7_override =0; + class CHandlerCont: public IInArchive, public IInArchiveGetStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_2( + IInArchive, + IInArchiveGetStream) + /* + Z7_IFACEM_IInArchive_Cont(Z7_COM7F_PUREO) + // Z7_IFACE_COM7_PURE(IInArchive_Cont) + */ + Z7_COM7F_IMP(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) protected: - CMyComPtr _stream; + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + CMyComPtr _stream; virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0; - -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive_Cont(PURE) - - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY; - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - // destructor must be virtual for this class virtual ~CHandlerCont() {} }; -#define INTERFACE_IInArchive_Img(x) \ - /* STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ +#define Z7_IFACEM_IInArchive_Img(x) \ + /* x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) */ \ + x(Close()) \ + /* x(GetNumberOfItems(UInt32 *numItems)) */ \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + /* x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) */ \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ class CHandlerImg: - public IInStream, public IInArchive, public IInArchiveGetStream, + public IInStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_4( + IInArchive, + IInArchiveGetStream, + ISequentialInStream, + IInStream) + + Z7_COM7F_IMP(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) + Z7_COM7F_IMP(GetNumberOfItems(UInt32 *numItems)) + Z7_COM7F_IMP(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) + Z7_IFACE_COM7_IMP(IInStream) + // Z7_IFACEM_IInArchive_Img(Z7_COM7F_PUREO) + protected: + bool _stream_unavailData; + bool _stream_unsupportedMethod; + bool _stream_dataError; + // bool _stream_UsePackSize; + // UInt64 _stream_PackSize; UInt64 _virtPos; UInt64 _posInArc; UInt64 _size; CMyComPtr Stream; const char *_imgExt; - bool _stream_unavailData; - bool _stream_unsupportedMethod; - bool _stream_dataError; - // bool _stream_UsePackSize; - // UInt64 _stream_PackSize; - void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; } void Reset_VirtPos() { _virtPos = (UInt64)0; } @@ -107,18 +121,6 @@ return false; } - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IInStream) - INTERFACE_IInArchive_Img(PURE) - - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) = 0; - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0; - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - CHandlerImg(); // destructor must be virtual for this class virtual ~CHandlerImg() {} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/HfsHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/HfsHandler.cpp 2022-07-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.cpp 2024-11-23 08:00:00.000000000 +0000 @@ -25,6 +25,9 @@ #define Get32(p) GetBe32(p) #define Get64(p) GetBe64(p) +#define Get16a(p) GetBe16a(p) +#define Get32a(p) GetBe32a(p) + namespace NArchive { namespace NHfs { @@ -104,38 +107,36 @@ { UInt32 num = 0; FOR_VECTOR (i, Extents) - { num += Extents[i].NumBlocks; - } return num; } bool CFork::Check_NumBlocks() const { - UInt32 num = 0; + UInt32 num = NumBlocks; FOR_VECTOR (i, Extents) { - UInt32 next = num + Extents[i].NumBlocks; - if (next < num) + const UInt32 cur = Extents[i].NumBlocks; + if (num < cur) return false; - num = next; + num -= cur; } - return num == NumBlocks; + return num == 0; } struct CIdIndexPair { UInt32 ID; - int Index; + unsigned Index; int Compare(const CIdIndexPair &a) const; }; -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; } int CIdIndexPair::Compare(const CIdIndexPair &a) const { - RINOZ(MyCompare(ID, a.ID)); + RINOZ(MyCompare(ID, a.ID)) return MyCompare(Index, a.Index); } @@ -144,10 +145,10 @@ unsigned left = 0, right = items.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - UInt32 midVal = items[mid].ID; + const unsigned mid = (left + right) / 2; + const UInt32 midVal = items[mid].ID; if (id == midVal) - return items[mid].Index; + return (int)items[mid].Index; if (id < midVal) right = mid; else @@ -161,10 +162,10 @@ unsigned left = 0, right = items.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - UInt32 midVal = items[mid].ID; + const unsigned mid = (left + right) / 2; + const UInt32 midVal = items[mid].ID; if (id == midVal) - return mid; + return (int)mid; if (id < midVal) right = mid; else @@ -175,7 +176,7 @@ bool CFork::Upgrade(const CObjectVector &items, UInt32 id) { - int index = Find_in_IdExtents(items, id); + const int index = Find_in_IdExtents(items, id); if (index < 0) return true; const CIdExtents &item = items[index]; @@ -188,8 +189,13 @@ struct CVolHeader { - Byte Header[2]; - UInt16 Version; + unsigned BlockSizeLog; + UInt32 NumFiles; + UInt32 NumFolders; + UInt32 NumBlocks; + UInt32 NumFreeBlocks; + + bool Is_Hsfx_ver5; // UInt32 Attr; // UInt32 LastMountedVersion; // UInt32 JournalInfoBlock; @@ -199,19 +205,13 @@ // UInt32 BackupTime; // UInt32 CheckedTime; - UInt32 NumFiles; - UInt32 NumFolders; - unsigned BlockSizeLog; - UInt32 NumBlocks; - UInt32 NumFreeBlocks; - // UInt32 WriteCount; // UInt32 FinderInfo[8]; // UInt64 VolID; UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; } UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; } - bool IsHfsX() const { return Version > 4; } + bool IsHfsX() const { return Is_Hsfx_ver5; } }; inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) @@ -244,6 +244,8 @@ // static const UInt32 kMethod_LZFSE_ATTR = 11; static const UInt32 kMethod_LZFSE_RSRC = 12; +// static const UInt32 kMethod_ZBM_RSRC = 14; + static const char * const g_Methods[] = { NULL @@ -259,6 +261,8 @@ , "COPY-rsrc" , "LZFSE-attr" , "LZFSE-rsrc" + , NULL + , "ZBM-rsrc" }; @@ -281,7 +285,9 @@ if ( Method == kMethod_ZLIB_RSRC || Method == kMethod_COPY_RSRC || Method == kMethod_LZVN_RSRC - || Method == kMethod_LZFSE_RSRC) + || Method == kMethod_LZFSE_RSRC + // || Method == kMethod_ZBM_RSRC // for debug + ) { IsResource = true; if (dataSize == 0) @@ -327,7 +333,7 @@ return; const UInt32 method = Method; const char *p = NULL; - if (method < ARRAY_SIZE(g_Methods)) + if (method < Z7_ARRAY_SIZE(g_Methods)) p = g_Methods[method]; AString s; if (p) @@ -457,18 +463,18 @@ bool UnsupportedFeature; bool ThereAreAltStreams; // bool CaseSensetive; + UInt32 MethodsMask; UString ResFileName; UInt64 SpecOffset; - UInt64 PhySize; + // UInt64 PhySize; UInt64 PhySize2; UInt64 ArcFileSize; - UInt32 MethodsMask; void Clear() { SpecOffset = 0; - PhySize = 0; + // PhySize = 0; PhySize2 = 0; ArcFileSize = 0; MethodsMask = 0; @@ -520,7 +526,7 @@ { unsigned len = 0; const unsigned kNumLevelsMax = (1 << 10); - int cur = index; + unsigned cur = index; unsigned i; for (i = 0; i < kNumLevelsMax; i++) @@ -537,8 +543,8 @@ len += s->Len(); len++; - cur = ref.Parent; - if (cur < 0) + cur = (unsigned)ref.Parent; + if (ref.Parent < 0) break; } @@ -580,7 +586,7 @@ if (len == 0) break; p[--len] = delimChar; - cur = ref.Parent; + cur = (unsigned)ref.Parent; } } @@ -590,7 +596,7 @@ { if (fork.NumBlocks >= Header.NumBlocks) return S_FALSE; - if ((ArcFileSize >> Header.BlockSizeLog) + 1 < fork.NumBlocks) + if (((ArcFileSize - SpecOffset) >> Header.BlockSizeLog) + 1 < fork.NumBlocks) return S_FALSE; const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; @@ -607,10 +613,10 @@ e.NumBlocks > fork.NumBlocks - curBlock || e.NumBlocks > Header.NumBlocks - e.Pos) return S_FALSE; - RINOK(inStream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog))) RINOK(ReadStream_FALSE(inStream, (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), - (size_t)e.NumBlocks << Header.BlockSizeLog)); + (size_t)e.NumBlocks << Header.BlockSizeLog)) curBlock += e.NumBlocks; } return S_OK; @@ -733,13 +739,13 @@ if (fork.NumBlocks == 0) return S_OK; CByteBuffer buf; - RINOK(ReadFile(fork, buf, inStream)); + RINOK(ReadFile(fork, buf, inStream)) const Byte *p = (const Byte *)buf; // CNodeDescriptor nodeDesc; // nodeDesc.Parse(p); CHeaderRec hr; - RINOK(hr.Parse2(buf)); + RINOK(hr.Parse2(buf)) UInt32 node = hr.FirstLeafNode; if (node == 0) @@ -872,13 +878,13 @@ return S_OK; CByteBuffer AttrBuf; - RINOK(ReadFile(fork, AttrBuf, inStream)); + RINOK(ReadFile(fork, AttrBuf, inStream)) const Byte *p = (const Byte *)AttrBuf; // CNodeDescriptor nodeDesc; // nodeDesc.Parse(p); CHeaderRec hr; - RINOK(hr.Parse2(AttrBuf)); + RINOK(hr.Parse2(AttrBuf)) // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); @@ -948,7 +954,7 @@ if (progress && (Attrs.Size() & 0xFFF) == 0) { const UInt64 numFiles = 0; - RINOK(progress->SetCompleted(&numFiles, NULL)); + RINOK(progress->SetCompleted(&numFiles, NULL)) } if (Attrs.Size() >= ((UInt32)1 << 31)) @@ -1012,7 +1018,7 @@ if (item.CompressHeader.IsCorrect) { - item.decmpfs_AttrIndex = attrIndex; + item.decmpfs_AttrIndex = (int)attrIndex; skip = true; if (item.CompressHeader.Method < sizeof(MethodsMask) * 8) MethodsMask |= ((UInt32)1 << item.CompressHeader.Method); @@ -1025,13 +1031,13 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress) { CByteBuffer buf; - RINOK(ReadFile(fork, buf, inStream)); + RINOK(ReadFile(fork, buf, inStream)) const Byte *p = (const Byte *)buf; // CNodeDescriptor nodeDesc; // nodeDesc.Parse(p); CHeaderRec hr; - RINOK(hr.Parse2(buf)); + RINOK(hr.Parse2(buf)) CRecordVector IdToIndexMap; @@ -1196,7 +1202,7 @@ if (progress && (Items.Size() & 0xFFF) == 0) { const UInt64 numItems = Items.Size(); - RINOK(progress->SetCompleted(&numItems, NULL)); + RINOK(progress->SetCompleted(&numItems, NULL)) } } node = desc.fLink; @@ -1265,7 +1271,7 @@ ThereAreAltStreams = true; ref.AttrIndex = kAttrIndex_Resource; - ref.Parent = Refs.Size() - 1; + ref.Parent = (int)(Refs.Size() - 1); Refs.Add(ref); #endif @@ -1311,7 +1317,7 @@ ThereAreAltStreams = true; CRef ref; - ref.AttrIndex = i; + ref.AttrIndex = (int)i; ref.Parent = refIndex; ref.ItemIndex = Refs[refIndex].ItemIndex; Refs.Add(ref); @@ -1322,28 +1328,26 @@ return S_OK; } -static const unsigned kHeaderPadSize = (1 << 10); +static const unsigned kHeaderPadSize = 1 << 10; static const unsigned kMainHeaderSize = 512; static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize; +static const unsigned k_Signature_LE16_HFS_BD = 'B' + ((unsigned)'D' << 8); +static const unsigned k_Signature_LE16_HPLUS = 'H' + ((unsigned)'+' << 8); +static const UInt32 k_Signature_LE32_HFSP_VER4 = 'H' + ((UInt32)'+' << 8) + ((UInt32)4 << 24); +static const UInt32 k_Signature_LE32_HFSX_VER5 = 'H' + ((UInt32)'X' << 8) + ((UInt32)5 << 24); + API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size) { if (size < kHfsHeaderSize) return k_IsArc_Res_NEED_MORE; p += kHeaderPadSize; - if (p[0] == 'B' && p[1] == 'D') - { - if (p[0x7C] != 'H' || p[0x7C + 1] != '+') - return k_IsArc_Res_NO; - } - else - { - if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) - return k_IsArc_Res_NO; - UInt32 version = Get16(p + 2); - if (version < 4 || version > 5) - return k_IsArc_Res_NO; - } + const UInt32 sig = GetUi32(p); + if (sig != k_Signature_LE32_HFSP_VER4) + if (sig != k_Signature_LE32_HFSX_VER5) + if ((UInt16)sig != k_Signature_LE16_HFS_BD + || GetUi16(p + 0x7c) != k_Signature_LE16_HPLUS) + return k_IsArc_Res_NO; return k_IsArc_Res_YES; } } @@ -1351,30 +1355,42 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) { Clear(); - Byte buf[kHfsHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)); - { - for (unsigned i = 0; i < kHeaderPadSize; i++) - if (buf[i] != 0) - return S_FALSE; - } - const Byte *p = buf + kHeaderPadSize; + UInt32 buf32[kHfsHeaderSize / 4]; + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) + const Byte *p = (const Byte *)buf32 + kHeaderPadSize; CVolHeader &h = Header; - h.Header[0] = p[0]; - h.Header[1] = p[1]; - - if (p[0] == 'B' && p[1] == 'D') + if (GetUi16a(p) == k_Signature_LE16_HFS_BD) { /* It's header for old HFS format. We don't support old HFS format, but we support - special HFS volume that contains embedded HFS+ volume + special HFS volume that contains embedded HFS+ volume. + HFS MDB : Master directory block + HFS VIB : Volume information block + some old images contain boot data with "LK" signature at start of buf32. */ - - if (p[0x7C] != 'H' || p[0x7C + 1] != '+') +#if 1 + // here we check first bytes of archive, + // because start data can contain signature of some another + // archive type that could have priority over HFS. + const void *buf_ptr = (const void *)buf32; + const unsigned sig = GetUi16a(buf_ptr); + if (sig != 'L' + ((unsigned)'K' << 8)) + { + // some old HFS (non HFS+) files have no "LK" signature, + // but have non-zero data after 2 first bytes in start 1 KiB. + if (sig != 0) + return S_FALSE; +/* + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; +*/ + } +#endif + if (GetUi16a(p + 0x7c) != k_Signature_LE16_HPLUS) // signature of embedded HFS+ volume return S_FALSE; - /* h.CTime = Get32(p + 0x2); h.MTime = Get32(p + 0x6); @@ -1388,85 +1404,109 @@ if (progress) { UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; - RINOK(progress->SetTotal(&numFiles, NULL)); + RINOK(progress->SetTotal(&numFiles, NULL)) } h.NumFreeBlocks = Get16(p + 0x22); */ - UInt32 blockSize = Get32(p + 0x14); - - { - unsigned i; - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i == 31) - return S_FALSE; - h.BlockSizeLog = i; - } - - h.NumBlocks = Get16(p + 0x12); + // v24.09: blockSize in old HFS image can be non-power of 2. + const UInt32 blockSize = Get32a(p + 0x14); // drAlBlkSiz + if (blockSize == 0 || (blockSize & 0x1ff)) + return S_FALSE; + const unsigned numBlocks = Get16a(p + 0x12); // drNmAlBlks + // UInt16 drFreeBks = Get16a(p + 0x22); // number of unused allocation blocks /* - we suppose that it has the follwing layout + we suppose that it has the following layout: { - start block with header - [h.NumBlocks] - end block with header + start data with header + blocks[h.NumBlocks] + end data with header (probably size_of_footer <= blockSize). } */ - PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog; - - UInt32 startBlock = Get16(p + 0x7C + 2); - UInt32 blockCount = Get16(p + 0x7C + 4); - SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog; - UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog); + // PhySize2 = ((UInt64)numBlocks + 2) * blockSize; + const unsigned sector_of_FirstBlock = Get16a(p + 0x1c); // drAlBlSt : first allocation block in volume + const UInt32 startBlock = Get16a(p + 0x7c + 2); + const UInt32 blockCount = Get16a(p + 0x7c + 4); + SpecOffset = (UInt32)sector_of_FirstBlock << 9; // it's 32-bit here + PhySize2 = SpecOffset + (UInt64)numBlocks * blockSize; + SpecOffset += (UInt64)startBlock * blockSize; + // before v24.09: // SpecOffset = (UInt64)(1 + startBlock) * blockSize; + const UInt64 phy = SpecOffset + (UInt64)blockCount * blockSize; if (PhySize2 < phy) - PhySize2 = phy; - RINOK(inStream->Seek(SpecOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)); + PhySize2 = phy; + UInt32 tail = 1 << 10; // at least 1 KiB tail (for footer MDB) is expected. + if (tail < blockSize) + tail = blockSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (ArcFileSize > PhySize2 && + ArcFileSize - PhySize2 <= tail) + { + // data after blocks[h.NumBlocks] must contain another copy of MDB. + // In example where blockSize is not power of 2, we have + // (ArcFileSize - PhySize2) < blockSize. + // We suppose that data after blocks[h.NumBlocks] is part of HFS archive. + // Maybe we should scan for footer MDB data (in last 1 KiB)? + PhySize2 = ArcFileSize; + } + RINOK(InStream_SeekSet(inStream, SpecOffset)) + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) } - if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) - return S_FALSE; - h.Version = Get16(p + 2); - if (h.Version < 4 || h.Version > 5) - return S_FALSE; - - // h.Attr = Get32(p + 4); - // h.LastMountedVersion = Get32(p + 8); - // h.JournalInfoBlock = Get32(p + 0xC); - - h.CTime = Get32(p + 0x10); - h.MTime = Get32(p + 0x14); - // h.BackupTime = Get32(p + 0x18); - // h.CheckedTime = Get32(p + 0x1C); - - h.NumFiles = Get32(p + 0x20); - h.NumFolders = Get32(p + 0x24); - - if (h.NumFolders > ((UInt32)1 << 29) || - h.NumFiles > ((UInt32)1 << 30)) - return S_FALSE; - - RINOK(inStream->Seek(0, STREAM_SEEK_END, &ArcFileSize)); - - if (progress) + // HFS+ / HFSX volume header (starting from offset==1024): { - const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; - RINOK(progress->SetTotal(&numFiles, NULL)); + // v24.09: we use strict condition test for pair signature(Version): + // H+(4), HX(5): + const UInt32 sig = GetUi32a(p); + // h.Version = Get16(p + 2); + h.Is_Hsfx_ver5 = false; + if (sig != k_Signature_LE32_HFSP_VER4) + { + if (sig != k_Signature_LE32_HFSX_VER5) + return S_FALSE; + h.Is_Hsfx_ver5 = true; + } } - - UInt32 blockSize = Get32(p + 0x28); - { + const UInt32 blockSize = Get32a(p + 0x28); unsigned i; for (i = 9; ((UInt32)1 << i) != blockSize; i++) if (i == 31) return S_FALSE; h.BlockSizeLog = i; } +#if 1 + // HFS Plus DOCs: The first 1024 bytes are reserved for use as boot blocks + // v24.09: we don't check starting 1 KiB before old (HFS MDB) block ("BD" signture) . + // but we still check starting 1 KiB before HFS+ / HFSX volume header. + // are there HFS+ / HFSX images with non-zero data in this reserved area? + { + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; + } +#endif + // h.Attr = Get32a(p + 4); + // h.LastMountedVersion = Get32a(p + 8); + // h.JournalInfoBlock = Get32a(p + 0xC); + h.CTime = Get32a(p + 0x10); + h.MTime = Get32a(p + 0x14); + // h.BackupTime = Get32a(p + 0x18); + // h.CheckedTime = Get32a(p + 0x1C); + h.NumFiles = Get32a(p + 0x20); + h.NumFolders = Get32a(p + 0x24); + if (h.NumFolders > ((UInt32)1 << 29) || + h.NumFiles > ((UInt32)1 << 30)) + return S_FALSE; - h.NumBlocks = Get32(p + 0x2C); - h.NumFreeBlocks = Get32(p + 0x30); + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (progress) + { + const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; + RINOK(progress->SetTotal(&numFiles, NULL)) + } + h.NumBlocks = Get32a(p + 0x2C); + h.NumFreeBlocks = Get32a(p + 0x30); /* h.NextCalatlogNodeID = Get32(p + 0x40); h.WriteCount = Get32(p + 0x44); @@ -1489,7 +1529,7 @@ HeadersError = true; else { - HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); + const HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); if (res == S_FALSE) HeadersError = true; else if (res != S_OK) @@ -1504,33 +1544,31 @@ else { if (attrFork.Size != 0) - RINOK(LoadAttrs(attrFork, inStream, progress)); + RINOK(LoadAttrs(attrFork, inStream, progress)) } - RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)); + RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)) - PhySize = Header.GetPhySize(); + // PhySize = Header.GetPhySize(); return S_OK; } -class CHandler: +Z7_class_CHandler_final: public IInArchive, public IArchiveGetRawProps, public IInArchiveGetStream, public CMyUnknownImp, public CDatabase { - CMyComPtr _stream; + Z7_IFACES_IMP_UNK_3( + IInArchive, + IArchiveGetRawProps, + IInArchiveGetStream) + CMyComPtr _stream; HRESULT GetForkStream(const CFork &fork, ISequentialInStream **stream); - -public: - MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; static const Byte kProps[] = @@ -1576,7 +1614,7 @@ prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Base); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -1587,7 +1625,7 @@ case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break; case kpidPhySize: { - UInt64 v = SpecOffset + PhySize; + UInt64 v = SpecOffset + Header.GetPhySize(); // PhySize; if (v < PhySize2) v = PhySize2; prop = v; @@ -1624,20 +1662,20 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = 0; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { const CRef &ref = Refs[index]; *parentType = ref.IsAltStream() ? @@ -1647,7 +1685,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -1669,13 +1707,13 @@ return S_OK; } #else - UNUSED_VAR(index); - UNUSED_VAR(propID); + UNUSED_VAR(index) + UNUSED_VAR(propID) #endif return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -1761,19 +1799,19 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); - RINOK(Open2(inStream, callback)); + RINOK(Open2(inStream, callback)) _stream = inStream; return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _stream.Release(); Clear(); @@ -1782,14 +1820,14 @@ static const UInt32 kCompressionBlockSize = 1 << 16; -CDecoder::CDecoder() +CDecoder::CDecoder(bool IsAdlerOptional) { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); - _zlibDecoder = _zlibDecoderSpec; - - _lzfseDecoderSpec = new NCompress::NLzfse::CDecoder(); - _lzfseDecoder = _lzfseDecoderSpec; - _lzfseDecoderSpec->LzvnMode = true; + /* Some new hfs files contain zlib resource fork without Adler checksum. + We do not know how we must detect case where there is Adler + checksum or there is no Adler checksum. + */ + _zlibDecoder->IsAdlerOptional = IsAdlerOptional; + _lzfseDecoder->LzvnMode = true; } HRESULT CDecoder::ExtractResourceFork_ZLIB( @@ -1802,7 +1840,7 @@ const size_t kBufSize = kCompressionBlockSize; _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header - RINOK(ReadStream_FALSE(inStream, _buf, kHeaderSize)); + RINOK(ReadStream_FALSE(inStream, _buf, kHeaderSize)) Byte *buf = _buf; const UInt32 dataPos = Get32(buf); const UInt32 mapPos = Get32(buf + 4); @@ -1837,7 +1875,7 @@ _tableBuf.AllocAtLeast(tableSize); - RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)); + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)) const Byte *tableBuf = _tableBuf; UInt32 prev = 4 + tableSize; @@ -1858,8 +1896,7 @@ if (prev != dataSize2) return S_FALSE; - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; + CMyComPtr2_Create bufInStream; // bool padError = false; UInt64 outPos = 0; @@ -1878,7 +1915,7 @@ if (size > kCompressionBlockSize + 1) return S_FALSE; - RINOK(ReadStream_FALSE(inStream, buf, size)); + RINOK(ReadStream_FALSE(inStream, buf, size)) if ((buf[0] & 0xF) == 0xF) { @@ -1889,17 +1926,17 @@ if (outStream) { - RINOK(WriteStream(outStream, buf, blockSize)); + RINOK(WriteStream(outStream, buf + 1, blockSize)) } } else { const UInt64 blockSize64 = blockSize; - bufInStreamSpec->Init(buf, size); - RINOK(_zlibDecoderSpec->Code(bufInStream, outStream, NULL, &blockSize64, NULL)); - if (_zlibDecoderSpec->GetOutputProcessedSize() != blockSize) + bufInStream->Init(buf, size); + RINOK(_zlibDecoder.Interface()->Code(bufInStream, outStream, NULL, &blockSize64, NULL)) + if (_zlibDecoder->GetOutputProcessedSize() != blockSize) return S_FALSE; - const UInt64 inSize = _zlibDecoderSpec->GetInputProcessedSize(); + const UInt64 inSize = _zlibDecoder->GetInputProcessedSize(); if (inSize != size) { if (inSize > size) @@ -1928,7 +1965,7 @@ if ((i & 0xFF) == 0) { const UInt64 progressPos = progressStart + outPos; - RINOK(extractCallback->SetCompleted(&progressPos)); + RINOK(extractCallback->SetCompleted(&progressPos)) } } @@ -1940,7 +1977,7 @@ /* We check Resource Map Are there HFS files with another values in Resource Map ??? */ - RINOK(ReadStream_FALSE(inStream, buf, mapSize)); + RINOK(ReadStream_FALSE(inStream, buf, mapSize)) const UInt32 types = Get16(buf + 24); const UInt32 names = Get16(buf + 26); const UInt32 numTypes = Get16(buf + 28); @@ -1980,7 +2017,7 @@ if (tableSize > forkSize) return S_FALSE; _tableBuf.AllocAtLeast(tableSize); - RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)); + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)) const Byte *tableBuf = _tableBuf; { @@ -2001,8 +2038,7 @@ const size_t kBufSize = kCompressionBlockSize; _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; + CMyComPtr2_Create bufInStream; UInt64 outPos = 0; @@ -2022,7 +2058,7 @@ if (size > kCompressionBlockSize + 1) return S_FALSE; - RINOK(ReadStream_FALSE(inStream, _buf, size)); + RINOK(ReadStream_FALSE(inStream, _buf, size)) const Byte *buf = _buf; if (buf[0] == k_LZVN_Uncompressed_Marker) @@ -2031,15 +2067,15 @@ return S_FALSE; if (outStream) { - RINOK(WriteStream(outStream, buf, blockSize)); + RINOK(WriteStream(outStream, buf + 1, blockSize)) } } else { const UInt64 blockSize64 = blockSize; const UInt64 packSize64 = size; - bufInStreamSpec->Init(buf, size); - RINOK(_lzfseDecoderSpec->Code(bufInStream, outStream, &packSize64, &blockSize64, NULL)); + bufInStream->Init(buf, size); + RINOK(_lzfseDecoder.Interface()->Code(bufInStream, outStream, &packSize64, &blockSize64, NULL)) // in/out sizes were checked in Code() } @@ -2047,7 +2083,7 @@ if ((i & 0xFF) == 0) { const UInt64 progressPos = progressStart + outPos; - RINOK(extractCallback->SetCompleted(&progressPos)); + RINOK(extractCallback->SetCompleted(&progressPos)) } } @@ -2055,6 +2091,186 @@ } +/* +static UInt32 GetUi24(const Byte *p) +{ + return p[0] + ((UInt32)p[1] << 8) + ((UInt32)p[2] << 24); +} + +HRESULT CDecoder::ExtractResourceFork_ZBM( + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback) +{ + const UInt32 kNumBlocksMax = (UInt32)1 << 29; + if (unpackSize >= (UInt64)kNumBlocksMax * kCompressionBlockSize) + return S_FALSE; + const UInt32 numBlocks = (UInt32)((unpackSize + kCompressionBlockSize - 1) / kCompressionBlockSize); + const UInt32 numBlocks2 = numBlocks + 1; + const UInt32 tableSize = (numBlocks2 << 2); + if (tableSize > forkSize) + return S_FALSE; + _tableBuf.AllocAtLeast(tableSize); + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)); + const Byte *tableBuf = _tableBuf; + + { + UInt32 prev = GetUi32(tableBuf); + if (prev != tableSize) + return S_FALSE; + for (UInt32 i = 1; i < numBlocks2; i++) + { + const UInt32 offs = GetUi32(tableBuf + i * 4); + if (offs <= prev) + return S_FALSE; + prev = offs; + } + if (prev != forkSize) + return S_FALSE; + } + + const size_t kBufSize = kCompressionBlockSize; + _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header + + CBufInStream *bufInStream = new CBufInStream; + CMyComPtr bufInStream = bufInStream; + + UInt64 outPos = 0; + + for (UInt32 i = 0; i < numBlocks; i++) + { + const UInt64 rem = unpackSize - outPos; + if (rem == 0) + return S_FALSE; + UInt32 blockSize = kCompressionBlockSize; + if (rem < kCompressionBlockSize) + blockSize = (UInt32)rem; + + const UInt32 size = + GetUi32(tableBuf + i * 4 + 4) - + GetUi32(tableBuf + i * 4); + + // if (size > kCompressionBlockSize + 1) + if (size > blockSize + 1) + return S_FALSE; // we don't expect it, because encode will use uncompressed chunk + + RINOK(ReadStream_FALSE(inStream, _buf, size)); + const Byte *buf = _buf; + + // (size != 0) + // if (size == 0) return S_FALSE; + + if (buf[0] == 0xFF) // uncompressed marker + { + if (size != blockSize + 1) + return S_FALSE; + if (outStream) + { + RINOK(WriteStream(outStream, buf + 1, blockSize)); + } + } + else + { + if (size < 4) + return S_FALSE; + if (buf[0] != 'Z' || + buf[1] != 'B' || + buf[2] != 'M' || + buf[3] != 9) + return S_FALSE; + // for debug: + unsigned packPos = 4; + unsigned unpackPos = 0; + unsigned packRem = size - packPos; + for (;;) + { + if (packRem < 6) + return S_FALSE; + const UInt32 packSize = GetUi24(buf + packPos); + const UInt32 chunkUnpackSize = GetUi24(buf + packPos + 3); + if (packSize < 6) + return S_FALSE; + if (packSize > packRem) + return S_FALSE; + if (chunkUnpackSize > blockSize - unpackPos) + return S_FALSE; + packPos += packSize; + packRem -= packSize; + unpackPos += chunkUnpackSize; + if (packSize == 6) + { + if (chunkUnpackSize != 0) + return S_FALSE; + break; + } + if (packSize >= chunkUnpackSize + 6) + { + if (packSize > chunkUnpackSize + 6) + return S_FALSE; + // uncompressed chunk; + } + else + { + // compressed chunk + const Byte *t = buf + packPos - packSize + 6; + UInt32 r = packSize - 6; + if (r < 9) + return S_FALSE; + const UInt32 v0 = GetUi24(t); + const UInt32 v1 = GetUi24(t + 3); + const UInt32 v2 = GetUi24(t + 6); + if (v0 > v1 || v1 > v2 || v2 > packSize) + return S_FALSE; + // here we need the code that will decompress ZBM chunk + } + } + + if (unpackPos != blockSize) + return S_FALSE; + + UInt32 size1 = size; + if (size1 > kCompressionBlockSize) + { + size1 = kCompressionBlockSize; + // return S_FALSE; + } + if (outStream) + { + RINOK(WriteStream(outStream, buf, size1)) + + const UInt32 kTempSize = 1 << 16; + Byte temp[kTempSize]; + memset(temp, 0, kTempSize); + + for (UInt32 k = size1; k < kCompressionBlockSize; k++) + { + UInt32 cur = kCompressionBlockSize - k; + if (cur > kTempSize) + cur = kTempSize; + RINOK(WriteStream(outStream, temp, cur)) + k += cur; + } + } + + // const UInt64 blockSize64 = blockSize; + // const UInt64 packSize64 = size; + // bufInStream->Init(buf, size); + // RINOK(_zbmDecoderSpec->Code(bufInStream, outStream, &packSize64, &blockSize64, NULL)); + // in/out sizes were checked in Code() + } + + outPos += blockSize; + if ((i & 0xFF) == 0) + { + const UInt64 progressPos = progressStart + outPos; + RINOK(extractCallback->SetCompleted(&progressPos)); + } + } + + return S_OK; +} +*/ + HRESULT CDecoder::Extract( ISequentialInStream *inStreamFork, ISequentialOutStream *realOutStream, UInt64 forkSize, @@ -2070,7 +2286,7 @@ const size_t packSize = data->Size() - compressHeader.DataPos; if (realOutStream) { - RINOK(WriteStream(realOutStream, *data + compressHeader.DataPos, packSize)); + RINOK(WriteStream(realOutStream, *data + compressHeader.DataPos, packSize)) } opRes = NExtract::NOperationResult::kOK; return S_OK; @@ -2079,24 +2295,23 @@ if (compressHeader.Method == kMethod_ZLIB_ATTR || compressHeader.Method == kMethod_LZVN_ATTR) { - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; + CMyComPtr2_Create bufInStream; const size_t packSize = data->Size() - compressHeader.DataPos; - bufInStreamSpec->Init(*data + compressHeader.DataPos, packSize); + bufInStream->Init(*data + compressHeader.DataPos, packSize); if (compressHeader.Method == kMethod_ZLIB_ATTR) { - const HRESULT hres = _zlibDecoder->Code(bufInStream, realOutStream, + const HRESULT hres = _zlibDecoder.Interface()->Code(bufInStream, realOutStream, NULL, &compressHeader.UnpackSize, NULL); if (hres == S_OK) - if (_zlibDecoderSpec->GetOutputProcessedSize() == compressHeader.UnpackSize - && _zlibDecoderSpec->GetInputProcessedSize() == packSize) + if (_zlibDecoder->GetOutputProcessedSize() == compressHeader.UnpackSize + && _zlibDecoder->GetInputProcessedSize() == packSize) opRes = NExtract::NOperationResult::kOK; return hres; } { const UInt64 packSize64 = packSize; - const HRESULT hres = _lzfseDecoder->Code(bufInStream, realOutStream, + const HRESULT hres = _lzfseDecoder.Interface()->Code(bufInStream, realOutStream, &packSize64, &compressHeader.UnpackSize, NULL); if (hres == S_OK) { @@ -2114,6 +2329,8 @@ inStreamFork, realOutStream, forkSize, compressHeader.UnpackSize, progressStart, extractCallback); + // for debug: + // hres = NCompress::CopyStream(inStreamFork, realOutStream, NULL); } else if (compressHeader.Method == NHfs::kMethod_LZVN_RSRC) { @@ -2122,6 +2339,15 @@ forkSize, compressHeader.UnpackSize, progressStart, extractCallback); } + /* + else if (compressHeader.Method == NHfs::kMethod_ZBM_RSRC) + { + hres = ExtractResourceFork_ZBM( + inStreamFork, realOutStream, + forkSize, compressHeader.UnpackSize, + progressStart, extractCallback); + } + */ else { opRes = NExtract::NOperationResult::kUnsupportedMethod; @@ -2134,8 +2360,8 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN const bool allFilesMode = (numItems == (UInt32)(Int32)-1); @@ -2150,44 +2376,47 @@ const CRef &ref = Refs[allFilesMode ? i : indices[i]]; totalSize += Get_UnpackSize_of_Ref(ref); } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 currentTotalSize = 0, currentItemSize = 0; const size_t kBufSize = kCompressionBlockSize; CByteBuffer buf(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header - CDecoder decoder; + // there are hfs without adler in zlib. + CDecoder decoder(true); // IsAdlerOptional for (i = 0;; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); - if (i == numItems) + RINOK(extractCallback->SetCompleted(¤tTotalSize)) + if (i >= numItems) break; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CRef &ref = Refs[index]; const CItem &item = Items[ref.ItemIndex]; currentItemSize = Get_UnpackSize_of_Ref(ref); + int opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (ref.IsItem() && item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) UInt64 pos = 0; - int opRes = NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; const CFork *fork = NULL; if (ref.AttrIndex >= 0) @@ -2203,7 +2432,7 @@ RINOK(WriteStream(realOutStream, // AttrBuf + attr.Pos, attr.Size attr.Data, attr.Data.Size() - )); + )) } } } @@ -2258,7 +2487,7 @@ if (fork->Size == pos) break; const CExtent &e = fork->Extents[extentIndex]; - RINOK(_stream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog))) UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog; while (extentRem != 0) { @@ -2275,7 +2504,7 @@ cur = (size_t)rem; if (cur > extentRem) cur = (size_t)extentRem; - RINOK(ReadStream(_stream, buf, &cur)); + RINOK(ReadStream(_stream, buf, &cur)) if (cur == 0) { opRes = NExtract::NOperationResult::kDataError; @@ -2283,26 +2512,26 @@ } if (realOutStream) { - RINOK(WriteStream(realOutStream, buf, cur)); + RINOK(WriteStream(realOutStream, buf, cur)) } pos += cur; extentRem -= cur; const UInt64 processed = currentTotalSize + pos; - RINOK(extractCallback->SetCompleted(&processed)); + RINOK(extractCallback->SetCompleted(&processed)) } } if (extentIndex != fork->Extents.Size() || fork->Size != pos) opRes = NExtract::NOperationResult::kDataError; } } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = Refs.Size(); return S_OK; @@ -2310,13 +2539,13 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream) { - *stream = 0; + *stream = NULL; if (!fork.IsOk(Header.BlockSizeLog)) return S_FALSE; - CExtentsStream *extentStreamSpec = new CExtentsStream(); - CMyComPtr extentStream = extentStreamSpec; + CMyComPtr2 extentStream; + extentStream.Create_if_Empty(); UInt64 rem = fork.Size; UInt64 virt = 0; @@ -2334,29 +2563,29 @@ return S_FALSE; } CSeekExtent se; - se.Phy = (UInt64)e.Pos << Header.BlockSizeLog; + se.Phy = SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog); se.Virt = virt; virt += cur; rem -= cur; - extentStreamSpec->Extents.Add(se); + extentStream->Extents.Add(se); } if (rem != 0) return S_FALSE; CSeekExtent se; - se.Phy = 0; + se.Phy = 0; // = SpecOffset ? se.Virt = virt; - extentStreamSpec->Extents.Add(se); - extentStreamSpec->Stream = _stream; - extentStreamSpec->Init(); + extentStream->Extents.Add(se); + extentStream->Stream = _stream; + extentStream->Init(); *stream = extentStream.Detach(); return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { - *stream = 0; + *stream = NULL; const CRef &ref = Refs[index]; const CFork *fork = NULL; @@ -2388,7 +2617,7 @@ 4, 'H', 'X', 0, 5 }; REGISTER_ARC_I( - "HFS", "hfs hfsx", 0, 0xE3, + "HFS", "hfs hfsx", NULL, 0xE3, k_Signature, kHeaderPadSize, NArcInfoFlags::kMultiSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/HfsHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/HfsHandler.h 2022-07-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/HfsHandler.h 2023-12-11 16:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // HfsHandler.h -#ifndef __HFS_HANDLER_H -#define __HFS_HANDLER_H +#ifndef ZIP7_INC_HFS_HANDLER_H +#define ZIP7_INC_HFS_HANDLER_H #include "../../Windows/PropVariant.h" @@ -23,7 +23,7 @@ bool IsResource; bool IsMethod_Compressed_Inline() const { return DataPos == k_decmpfs_HeaderSize; } - bool IsMethod_Uncompressed_Inline() const { return DataPos == k_decmpfs_HeaderSize + 1; } + bool IsMethod_Uncompressed_Inline() const { return DataPos == k_decmpfs_HeaderSize + 1; } bool IsMethod_Resource() const { return IsResource; } void Parse(const Byte *p, size_t size); @@ -48,11 +48,8 @@ class CDecoder { - NCompress::NZlib::CDecoder *_zlibDecoderSpec; - CMyComPtr _zlibDecoder; - - NCompress::NLzfse::CDecoder *_lzfseDecoderSpec; - CMyComPtr _lzfseDecoder; + CMyComPtr2_Create _zlibDecoder; + CMyComPtr2_Create _lzfseDecoder; CByteBuffer _tableBuf; CByteBuffer _buf; @@ -67,6 +64,11 @@ UInt64 forkSize, UInt64 unpackSize, UInt64 progressStart, IArchiveExtractCallback *extractCallback); + HRESULT ExtractResourceFork_ZBM( + ISequentialInStream *inStream, ISequentialOutStream *realOutStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback); + public: HRESULT Extract( @@ -77,7 +79,7 @@ UInt64 progressStart, IArchiveExtractCallback *extractCallback, int &opRes); - CDecoder(); + CDecoder(bool IsAdlerOptional); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/IArchive.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IArchive.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/IArchive.h 2022-05-10 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IArchive.h 2024-03-20 06:00:00.000000000 +0000 @@ -1,14 +1,21 @@ // IArchive.h -#ifndef __IARCHIVE_H -#define __IARCHIVE_H +#ifndef ZIP7_INC_IARCHIVE_H +#define ZIP7_INC_IARCHIVE_H #include "../IProgress.h" #include "../IStream.h" #include "../PropID.h" -#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x) -#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) +Z7_PURE_INTERFACES_BEGIN + + +#define Z7_IFACE_CONSTR_ARCHIVE_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 6, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_ARCHIVE(i, n) \ + Z7_IFACE_CONSTR_ARCHIVE_SUB(i, IUnknown, n) /* How the function in 7-Zip returns object for output parameter via pointer @@ -81,11 +88,11 @@ const unsigned kTime_Prec_Default_num_bits = 5; } -#define TIME_PREC_TO_ARC_FLAGS_MASK(x) \ - ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (x))) +#define TIME_PREC_TO_ARC_FLAGS_MASK(v) \ + ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (v))) -#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(x) \ - ((UInt32)(x) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index) +#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(v) \ + ((UInt32)(v) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index) namespace NArchive { @@ -136,6 +143,7 @@ kIsNotArc, kHeadersError, kWrongPassword + // , kMemError }; } } @@ -166,14 +174,11 @@ } } -#define INTERFACE_IArchiveOpenCallback(x) \ - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ +#define Z7_IFACEM_IArchiveOpenCallback(x) \ + x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \ + x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \ -ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) -{ - INTERFACE_IArchiveOpenCallback(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10) /* IArchiveExtractCallback:: @@ -224,57 +229,49 @@ Int32 opRes (NExtract::NOperationResult) */ -#define INTERFACE_IArchiveExtractCallback(x) \ - INTERFACE_IProgress(x) \ - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ - STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes) x; \ +// INTERFACE_IProgress(x) -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) -{ - INTERFACE_IArchiveExtractCallback(PURE) -}; +#define Z7_IFACEM_IArchiveExtractCallback(x) \ + x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \ + x(PrepareOperation(Int32 askExtractMode)) \ + x(SetOperationResult(Int32 opRes)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20) /* -IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object +v23: +IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object by Extract() or UpdateItems() functions to report about extracting errors ReportExtractResult() UInt32 indexType (NEventIndexType) UInt32 index Int32 opRes (NExtract::NOperationResult) */ - -#define INTERFACE_IArchiveExtractCallbackMessage(x) \ - STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) -{ - INTERFACE_IArchiveExtractCallbackMessage(PURE) -}; - - -#define INTERFACE_IArchiveOpenVolumeCallback(x) \ - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ - -ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) -{ - INTERFACE_IArchiveOpenVolumeCallback(PURE); -}; - - -ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) -{ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; -}; - - -ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) -{ - STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; -}; +/* +before v23: +#define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) +*/ +#define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveExtractCallbackMessage2, 0x22) + +#define Z7_IFACEM_IArchiveOpenVolumeCallback(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetStream(const wchar_t *name, IInStream **inStream)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30) + + +#define Z7_IFACEM_IInArchiveGetStream(x) \ + x(GetStream(UInt32 index, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40) + +#define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \ + x(SetSubArchiveName(const wchar_t *name)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50) /* @@ -310,28 +307,25 @@ Some IInArchive handlers will work incorrectly in that case. */ -#ifdef _MSC_VER - #define MY_NO_THROW_DECL_ONLY throw() +#if defined(_MSC_VER) && !defined(__clang__) + #define MY_NO_THROW_DECL_ONLY Z7_COM7F_E #else #define MY_NO_THROW_DECL_ONLY #endif -#define INTERFACE_IInArchive(x) \ - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ +#define Z7_IFACEM_IInArchive(x) \ + x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \ + x(Close()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ -ARCHIVE_INTERFACE(IInArchive, 0x60) -{ - INTERFACE_IInArchive(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60) namespace NParentType { @@ -340,7 +334,7 @@ kDir = 0, kAltStream }; -}; +} namespace NPropDataType { @@ -356,41 +350,36 @@ const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd; const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; -}; +} // UTF string (pointer to wchar_t) with zero end and little-endian. #define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1)) + /* GetRawProp: Result: S_OK - even if property is not set */ -#define INTERFACE_IArchiveGetRawProps(x) \ - STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \ - STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ - STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \ - STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x; - -ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70) -{ - INTERFACE_IArchiveGetRawProps(PURE) -}; - -#define INTERFACE_IArchiveGetRootProps(x) \ - STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ +#define Z7_IFACEM_IArchiveGetRawProps(x) \ + x(GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) \ + x(GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ + x(GetNumRawProps(UInt32 *numProps)) \ + x(GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRawProps, 0x70) + +#define Z7_IFACEM_IArchiveGetRootProps(x) \ + x(GetRootProp(PROPID propID, PROPVARIANT *value)) \ + x(GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ -ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71) -{ - INTERFACE_IArchiveGetRootProps(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71) -ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61) -{ - STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; -}; +#define Z7_IFACEM_IArchiveOpenSeq(x) \ + x(OpenSeq(ISequentialInStream *stream)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61) /* OpenForSize @@ -416,12 +405,10 @@ the handler can return S_OK, but it doesn't check even Signature. So next Extract can be called for that sequential stream. */ - /* -ARCHIVE_INTERFACE(IArchiveOpen2, 0x62) -{ - STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE; -}; +#define Z7_IFACEM_IArchiveOpen2(x) \ + x(ArcOpen2(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62) */ // ---------- UPDATE ---------- @@ -454,27 +441,21 @@ Int32 opRes (NExtract::NOperationResult::kOK) */ -#define INTERFACE_IArchiveUpdateCallback(x) \ - INTERFACE_IProgress(x); \ - STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ - STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) -{ - INTERFACE_IArchiveUpdateCallback(PURE); -}; +// INTERFACE_IProgress(x) +#define Z7_IFACEM_IArchiveUpdateCallback(x) \ + x(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(GetStream(UInt32 index, ISequentialInStream **inStream)) \ + x(SetOperationResult(Int32 operationResult)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback, IProgress, 0x80) + +// INTERFACE_IArchiveUpdateCallback(x) +#define Z7_IFACEM_IArchiveUpdateCallback2(x) \ + x(GetVolumeSize(UInt32 index, UInt64 *size)) \ + x(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) \ -#define INTERFACE_IArchiveUpdateCallback2(x) \ - INTERFACE_IArchiveUpdateCallback(x) \ - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) -{ - INTERFACE_IArchiveUpdateCallback2(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) namespace NUpdateNotifyOp { @@ -493,7 +474,7 @@ // , kOpFinished // , kNumDefined }; -}; +} /* IArchiveUpdateCallbackFile::ReportOperation @@ -502,36 +483,26 @@ UInt32 notifyOp (NUpdateNotifyOp) */ -#define INTERFACE_IArchiveUpdateCallbackFile(x) \ - STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \ - STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \ +#define Z7_IFACEM_IArchiveUpdateCallbackFile(x) \ + x(GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp)) \ + x(ReportOperation(UInt32 indexType, UInt32 index, UInt32 notifyOp)) \ -ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83) -{ - INTERFACE_IArchiveUpdateCallbackFile(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83) -#define INTERFACE_IArchiveGetDiskProperty(x) \ - STDMETHOD(GetDiskProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ +#define Z7_IFACEM_IArchiveGetDiskProperty(x) \ + x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ -ARCHIVE_INTERFACE(IArchiveGetDiskProperty, 0x84) -{ - INTERFACE_IArchiveGetDiskProperty(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetDiskProperty, 0x84) /* -#define INTERFACE_IArchiveUpdateCallbackArcProp(x) \ - STDMETHOD(ReportProp)(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x; \ - STDMETHOD(ReportRawProp)(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x; \ - STDMETHOD(ReportFinished)(UInt32 indexType, UInt32 index, Int32 opRes) x; \ - STDMETHOD(DoNeedArcProp)(PROPID propID, Int32 *answer) x; \ +#define Z7_IFACEM_IArchiveUpdateCallbackArcProp(x) \ + x(ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) \ + x(ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) \ + x(ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) \ + x(DoNeedArcProp(PROPID propID, Int32 *answer)) \ - -ARCHIVE_INTERFACE(IArchiveUpdateCallbackArcProp, 0x85) -{ - INTERFACE_IArchiveUpdateCallbackArcProp(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85) */ /* @@ -556,14 +527,11 @@ */ -#define INTERFACE_IOutArchive(x) \ - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(GetFileTimeType)(UInt32 *type) x; +#define Z7_IFACEM_IOutArchive(x) \ + x(UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback)) \ + x(GetFileTimeType(UInt32 *type)) -ARCHIVE_INTERFACE(IOutArchive, 0xA0) -{ - INTERFACE_IOutArchive(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0) /* @@ -576,31 +544,76 @@ VT_BSTR */ -ARCHIVE_INTERFACE(ISetProperties, 0x03) -{ - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE; -}; +#define Z7_IFACEM_ISetProperties(x) \ + x(SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) -ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04) -{ - STDMETHOD(KeepModeForNextOpen)() PURE; -}; +Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03) + +#define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \ + x(KeepModeForNextOpen()) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveKeepModeForNextOpen, 0x04) /* Exe handler: the handler for executable format (PE, ELF, Mach-O). SFX archive: executable stub + some tail data. before 9.31: exe handler didn't parse SFX archives as executable format. for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */ -ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05) +#define Z7_IFACEM_IArchiveAllowTail(x) \ + x(AllowTail(Int32 allowTail)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05) + + +namespace NRequestMemoryUseFlags { - STDMETHOD(AllowTail)(Int32 allowTail) PURE; -}; + const UInt32 k_AllowedSize_WasForced = 1 << 0; // (*allowedSize) was forced by -mmemx or -smemx + const UInt32 k_DefaultLimit_Exceeded = 1 << 1; // default limit of archive format was exceeded + const UInt32 k_MLimit_Exceeded = 1 << 2; // -mmemx value was exceeded + const UInt32 k_SLimit_Exceeded = 1 << 3; // -smemx value was exceeded + + const UInt32 k_NoErrorMessage = 1 << 10; // do not show error message, and show only request + const UInt32 k_IsReport = 1 << 11; // only report is required, without user request + + const UInt32 k_SkipArc_IsExpected = 1 << 12; // NRequestMemoryAnswerFlags::k_SkipArc flag answer is expected + const UInt32 k_Report_SkipArc = 1 << 13; // report about SkipArc operation + + // const UInt32 k_SkipBigFile_IsExpected = 1 << 14; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused) + // const UInt32 k_Report_SkipBigFile = 1 << 15; // report about SkipFile operation (unused) + + // const UInt32 k_SkipBigFiles_IsExpected = 1 << 16; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused) + // const UInt32 k_Report_SkipBigFiles = 1 << 17; // report that all big files will be skipped (unused) +} +namespace NRequestMemoryAnswerFlags +{ + const UInt32 k_Allow = 1 << 0; // allow further archive extraction + const UInt32 k_Stop = 1 << 1; // for exit (and return_code == E_ABORT is used) + const UInt32 k_SkipArc = 1 << 2; // skip current archive extraction + // const UInt32 k_SkipBigFile = 1 << 4; // skip extracting of files that exceed limit (unused) + // const UInt32 k_SkipBigFiles = 1 << 5; // skip extracting of files that exceed limit (unused) + const UInt32 k_Limit_Exceeded = 1 << 10; // limit was exceeded +} -#define IMP_IInArchive_GetProp(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ +/* + *allowedSize is in/out: + in : default allowed memory usage size or forced size, if it was changed by switch -mmemx. + out : value specified by user or unchanged value. + + *answerFlags is in/out: + *answerFlags must be set by caller before calling for default action, + + indexType : must be set with NEventIndexType::* constant + (indexType == kNoIndex), if request for whole archive. + index : must be set for some (indexType) types (if + fileIndex , if (indexType == NEventIndexType::kInArcIndex) + 0, if if (indexType == kNoIndex) + path : NULL can be used for any indexType. +*/ +#define Z7_IFACEM_IArchiveRequestMemoryUseCallback(x) \ + x(RequestMemoryUse(UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path, \ + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveRequestMemoryUseCallback, 0x09) struct CStatProp @@ -616,46 +629,69 @@ BSTR AllocBstrFromAscii(const char *s) throw(); }} -#define IMP_IInArchive_GetProp_WITH_NAME(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ + +#define IMP_IInArchive_GetProp_Base(fn, f, k) \ + Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \ + { *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \ + Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \ + +#define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ + *propID = k[index]; \ + *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \ + *name = NULL; return S_OK; } \ + +#define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ const CStatProp &prop = k[index]; \ - *propID = (PROPID)prop.PropID; *varType = prop.vt; \ + *propID = (PROPID)prop.PropID; \ + *varType = prop.vt; \ *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \ + #define IMP_IInArchive_Props \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps) + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) #define IMP_IInArchive_Props_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps) - + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) #define IMP_IInArchive_ArcProps \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) #define IMP_IInArchive_ArcProps_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps) + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) #define IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ + Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \ { *numProps = 0; return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ + Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \ { return E_NOTIMPL; } \ #define IMP_IInArchive_ArcProps_NO \ IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ + Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \ { value->vt = VT_EMPTY; return S_OK; } +#define Z7_class_CHandler_final \ + Z7_class_final(CHandler) + + +#define Z7_CLASS_IMP_CHandler_IInArchive_0 \ + Z7_CLASS_IMP_COM_1(CHandler, IInArchive) +#define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \ + Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1) +#define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \ + Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2) +#define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \ + Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3) +#define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \ + Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4) +#define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \ + Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5) + + #define k_IsArc_Res_NO 0 #define k_IsArc_Res_YES 1 @@ -714,4 +750,5 @@ NFileTimeType::kWindows)) */ +Z7_PURE_INTERFACES_END #endif Binary files /srv/release.debian.org/tmp/FKa5SyvX6d/7zip-22.01+dfsg/CPP/7zip/Archive/Icons/zst.ico and /srv/release.debian.org/tmp/danBDQ1hk5/7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Icons/zst.ico differ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/IhexHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IhexHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/IhexHandler.cpp 2021-01-26 09:46:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/IhexHandler.cpp 2023-10-02 09:00:00.000000000 +0000 @@ -7,14 +7,14 @@ #include "../../Common/ComTry.h" #include "../../Common/DynamicBuffer.h" #include "../../Common/IntToString.h" -#include "../../Common/MyVector.h" +#include "../../Common/StringToInt.h" #include "../../Windows/PropVariant.h" +#include "../Common/InBuffer.h" #include "../Common/ProgressUtils.h" #include "../Common/RegisterArc.h" #include "../Common/StreamUtils.h" -#include "../Common/InBuffer.h" namespace NArchive { namespace NIhex { @@ -27,10 +27,9 @@ UInt32 Offset; }; -class CHandler: - public IInArchive, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_0 + bool _isArc; bool _needMoreInput; bool _dataError; @@ -38,9 +37,6 @@ UInt64 _phySize; CObjectVector _blocks; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) }; static const Byte kProps[] = @@ -53,13 +49,13 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _blocks.Size(); return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; switch (propID) @@ -68,17 +64,18 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; if (_dataError) v |= kpv_ErrorFlags_DataError; prop = v; + break; } } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -103,19 +100,12 @@ COM_TRY_END } -static inline int HexToByte(unsigned c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - return -1; -} static int Parse(const Byte *p) { - int c1 = HexToByte(p[0]); if (c1 < 0) return -1; - int c2 = HexToByte(p[1]); if (c2 < 0) return -1; - return (c1 << 4) | c2; + unsigned v0 = p[0]; Z7_PARSE_HEX_DIGIT(v0, return -1;) + unsigned v1 = p[1]; Z7_PARSE_HEX_DIGIT(v1, return -1;) + return (int)((v0 << 4) | v1); } #define kType_Data 0 @@ -127,7 +117,11 @@ #define kType_MAX 5 -#define IS_LINE_DELIMITER(c) ((c) == 0 || (c) == 10 || (c) == 13) +// we don't want to read files with big number of spaces between records +// it's our limitation (out of specification): +static const unsigned k_NumSpaces_LIMIT = 16 + 1; + +#define IS_LINE_DELIMITER(c) (/* (c) == 0 || */ (c) == 10 || (c) == 13) API_FUNC_static_IsArc IsArc_Ihex(const Byte *p, size_t size) { @@ -145,11 +139,11 @@ if (size < 4 * 2) return k_IsArc_Res_NEED_MORE; - int num = Parse(p); + const int num = Parse(p); if (num < 0) return k_IsArc_Res_NO; - int type = Parse(p + 6); + const int type = Parse(p + 6); if (type < 0 || type > kType_MAX) return k_IsArc_Res_NO; @@ -166,7 +160,7 @@ sum += (unsigned)v; } - if ((sum & 0xFF) != 0) + if (sum & 0xFF) return k_IsArc_Res_NO; if (type == kType_Data) @@ -203,17 +197,17 @@ p += numChars; size -= numChars; + unsigned numSpaces = k_NumSpaces_LIMIT; for (;;) { if (size == 0) return k_IsArc_Res_NEED_MORE; - char b = *p++; + const Byte b = *p++; size--; - if (IS_LINE_DELIMITER(b)) - continue; if (b == ':') break; - return k_IsArc_Res_NO; + if (--numSpaces == 0 || !IS_LINE_DELIMITER(b)) + return k_IsArc_Res_NO; } } @@ -221,7 +215,7 @@ } } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) { COM_TRY_BEGIN { @@ -232,8 +226,8 @@ Byte temp[kStartSize]; { size_t size = kStartSize; - RINOK(ReadStream(stream, temp, &size)); - UInt32 isArcRes = IsArc_Ihex(temp, size); + RINOK(ReadStream(stream, temp, &size)) + const UInt32 isArcRes = IsArc_Ihex(temp, size); if (isArcRes == k_IsArc_Res_NO) return S_FALSE; if (isArcRes == k_IsArc_Res_NEED_MORE && size != kStartSize) @@ -241,13 +235,12 @@ } _isArc = true; - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(stream)) CInBuffer s; if (!s.Create(1 << 15)) return E_OUTOFMEMORY; s.SetStream(stream); s.Init(); - { Byte b; if (!s.ReadByte(b)) @@ -263,6 +256,8 @@ } UInt32 globalOffset = 0; + const UInt32 k_progressStep = 1 << 24; + UInt64 progressNext = k_progressStep; for (;;) { @@ -271,49 +266,47 @@ _needMoreInput = true; return S_FALSE; } - int num = Parse(temp); + const int num = Parse(temp); if (num < 0) { _dataError = true; return S_FALSE; } - { - size_t numPairs = ((unsigned)num + 4); - size_t numBytes = numPairs * 2; + const size_t numPairs = (unsigned)num + 4; + const size_t numBytes = numPairs * 2; if (s.ReadBytes(temp, numBytes) != numBytes) { _needMoreInput = true; return S_FALSE; } - - unsigned sum = num; + unsigned sum = (unsigned)num; for (size_t i = 0; i < numPairs; i++) { - int a = Parse(temp + i * 2); + const int a = Parse(temp + i * 2); if (a < 0) { _dataError = true; return S_FALSE; } temp[i] = (Byte)a; - sum += a; + sum += (unsigned)a; } - if ((sum & 0xFF) != 0) + if (sum & 0xFF) { _dataError = true; return S_FALSE; } } - unsigned type = temp[2]; + const unsigned type = temp[2]; if (type > kType_MAX) { _dataError = true; return S_FALSE; } - UInt32 a = GetBe16(temp); + const UInt32 a = GetBe16(temp); if (type == kType_Data) { @@ -326,7 +319,7 @@ } // if (num != 0) { - UInt32 offs = globalOffset + a; + const UInt32 offs = globalOffset + a; CBlock *block = NULL; if (!_blocks.IsEmpty()) { @@ -342,10 +335,21 @@ block->Data.AddData(temp + 3, (unsigned)num); } } - else if (type == kType_Eof) + else { - _phySize = s.GetProcessedSize(); + if (a != 0) // from description: the address field is typically 0. { + _dataError = true; + return S_FALSE; + } + if (type == kType_Eof) + { + if (num != 0) + { + _dataError = true; + return S_FALSE; + } + _phySize = s.GetProcessedSize(); Byte b; if (s.ReadByte(b)) { @@ -361,16 +365,9 @@ } } } + return S_OK; } - return S_OK; - } - else - { - if (a != 0) - { - _dataError = true; - return S_FALSE; - } + if (type == kType_Seg || type == kType_High) { if (num != 2) @@ -378,8 +375,8 @@ _dataError = true; return S_FALSE; } - UInt32 d = GetBe16(temp + 3); - globalOffset = d << (type == kType_Seg ? 4 : 16); + // here we use optimization trick for num shift calculation: (type == kType_Seg ? 4 : 16) + globalOffset = (UInt32)GetBe16(temp + 3) << (1u << type); } else { @@ -391,6 +388,18 @@ } } + if (openCallback) + { + const UInt64 processed = s.GetProcessedSize(); + if (processed >= progressNext) + { + progressNext = processed + k_progressStep; + const UInt64 numFiles = _blocks.Size(); + RINOK(openCallback->SetCompleted(&numFiles, &processed)) + } + } + + unsigned numSpaces = k_NumSpaces_LIMIT; for (;;) { Byte b; @@ -399,12 +408,13 @@ _needMoreInput = true; return S_FALSE; } - if (IS_LINE_DELIMITER(b)) - continue; if (b == ':') break; - _dataError = true; - return S_FALSE; + if (--numSpaces == 0 || !IS_LINE_DELIMITER(b)) + { + _dataError = true; + return S_FALSE; + } } } } @@ -413,24 +423,23 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() + +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; - _isArc = false; _needMoreInput = false; _dataError = false; - _blocks.Clear(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _blocks.Size(); if (numItems == 0) @@ -440,56 +449,43 @@ UInt32 i; for (i = 0; i < numItems; i++) totalSize += _blocks[allFilesMode ? i : indices[i]].Data.GetPos(); - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + for (i = 0;; i++) { - currentItemSize = 0; - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - - UInt32 index = allFilesMode ? i : indices[i]; + lps->InSize = lps->OutSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const UInt32 index = allFilesMode ? i : indices[i]; const CByteDynamicBuffer &data = _blocks[index].Data; - currentItemSize = data.GetPos(); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (!testMode && !realOutStream) - continue; - - extractCallback->PrepareOperation(askMode); - - if (realOutStream) + lps->OutSize += data.GetPos(); { - RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos())); + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (realOutStream) + RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos())) } - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } - lps->InSize = lps->OutSize = currentTotalSize; - return lps->SetCur(); - + return S_OK; COM_TRY_END } -// k_Signature: { ':', '1' } +// k_Signature: { ':' } REGISTER_ARC_I_NO_SIG( - "IHex", "ihex", 0, 0xCD, + "IHex", "ihex", NULL, 0xCD, 0, NArcInfoFlags::kStartOpen, IsArc_Ihex) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.cpp 2022-05-03 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.cpp 2024-03-03 16:00:00.000000000 +0000 @@ -8,6 +8,7 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" @@ -48,28 +49,28 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); { - RINOK(_archive.Open(stream)); + RINOK(_archive.Open(stream)) _stream = stream; } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _archive.Clear(); _stream.Release(); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _archive.Refs.Size() + _archive.BootEntries.Size(); return S_OK; @@ -84,13 +85,21 @@ { AString d; d.SetFrom((const char *)p, i); - s += '\n'; s += name; s += ": "; s += d; + s.Add_LF(); } } +static void AddProp_Size64(AString &s, const char *name, UInt64 size) +{ + s += name; + s += ": "; + s.Add_UInt64(size); + s.Add_LF(); +} + #define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v)) static void AddErrorMessage(AString &s, const char *message) @@ -100,7 +109,7 @@ s += message; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -121,6 +130,11 @@ ADD_STRING("Copyright", CopyrightFileId); ADD_STRING("Abstract", AbstractFileId); ADD_STRING("Bib", BibFileId); + // ADD_STRING("EscapeSequence", EscapeSequence); + AddProp_Size64(s, "VolumeSpaceSize", vol.Get_VolumeSpaceSize_inBytes()); + AddProp_Size64(s, "VolumeSetSize", vol.VolumeSetSize); + AddProp_Size64(s, "VolumeSequenceNumber", vol.VolumeSequenceNumber); + prop = s; break; } @@ -161,7 +175,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -177,7 +191,7 @@ if (_archive.BootEntries.Size() != 1) { s.Add_UInt32(index + 1); - s += '-'; + s.Add_Minus(); } s += be.GetName(); prop = s; @@ -303,11 +317,11 @@ COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _archive.Refs.Size(); if (numItems == 0) @@ -327,34 +341,33 @@ else totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size()); } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 currentTotalSize = 0; UInt64 currentItemSize; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + for (i = 0;; i++, currentTotalSize += currentItemSize) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; currentItemSize = 0; + Int32 opRes = NExtract::NOperationResult::kOK; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) UInt64 blockIndex; if (index < (UInt32)_archive.Refs.Size()) @@ -363,8 +376,8 @@ const CDir &item = ref.Dir->_subItems[ref.Index]; if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } currentItemSize = ref.TotalSize; @@ -382,9 +395,8 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) - bool isOK = true; if (index < (UInt32)_archive.Refs.Size()) { const CRef &ref = _archive.Refs[index]; @@ -395,12 +407,12 @@ if (item2.Size == 0) continue; lps->InSize = lps->OutSize = currentTotalSize + offset; - RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item2.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != item2.Size) + RINOK(InStream_SeekSet(_stream, (UInt64)item2.ExtentLocation * kBlockSize)) + inStream->Init(item2.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item2.Size) { - isOK = false; + opRes = NExtract::NOperationResult::kDataError; break; } offset += item2.Size; @@ -408,25 +420,24 @@ } else { - RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != currentItemSize) - isOK = false; + RINOK(InStream_SeekSet(_stream, (UInt64)blockIndex * kBlockSize)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != currentItemSize) + opRes = NExtract::NOperationResult::kDataError; } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(isOK ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + // realOutStream.Release(); + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; UInt64 blockIndex; UInt64 currentItemSize; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.h 2013-01-17 08:01:58.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHandler.h 2023-03-26 13:00:00.000000000 +0000 @@ -1,29 +1,22 @@ // IsoHandler.h -#ifndef __ISO_HANDLER_H -#define __ISO_HANDLER_H +#ifndef ZIP7_INC_ISO_HANDLER_H +#define ZIP7_INC_ISO_HANDLER_H #include "../../../Common/MyCom.h" #include "../IArchive.h" #include "IsoIn.h" -#include "IsoItem.h" namespace NArchive { namespace NIso { -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CMyComPtr _stream; CInArchive _archive; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoHeader.h 2017-02-04 17:53:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/IsoHeader.h -#ifndef __ARCHIVE_ISO_HEADER_H -#define __ARCHIVE_ISO_HEADER_H +#ifndef ZIP7_INC_ARCHIVE_ISO_HEADER_H +#define ZIP7_INC_ARCHIVE_ISO_HEADER_H #include "../../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.cpp 2022-01-10 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.cpp 2024-05-14 09:00:00.000000000 +0000 @@ -48,9 +48,9 @@ AString CBootInitialEntry::GetName() const { AString s (Bootable ? "Boot" : "NotBoot"); - s += '-'; + s.Add_Minus(); - if (BootMediaType < ARRAY_SIZE(kMediaTypes)) + if (BootMediaType < Z7_ARRAY_SIZE(kMediaTypes)) s += kMediaTypes[BootMediaType]; else s.Add_UInt32(BootMediaType); @@ -65,10 +65,10 @@ break; if (i == sizeof(VendorSpec)) { - s += '-'; + s.Add_Minus(); for (i = 1; i < sizeof(VendorSpec); i++) { - char c = VendorSpec[i]; + char c = (char)VendorSpec[i]; if (c == 0) break; if (c == '\\' || c == '/') @@ -134,7 +134,7 @@ { if (b[i] != b[3 - i]) IncorrectBigEndian = true; - val |= ((UInt16)(b[i]) << (8 * i)); + val |= ((UInt32)(b[i]) << (8 * i)); } return (UInt16)val; } @@ -287,11 +287,17 @@ ReadDateTime(d.MTime); ReadDateTime(d.ExpirationTime); ReadDateTime(d.EffectiveTime); - d.FileStructureVersion = ReadByte(); // = 1 - SkipZeros(1); + const Byte fileStructureVersion = ReadByte(); + // d.FileStructureVersion = fileStructureVersion; + if (fileStructureVersion != 1 && // ECMA-119 + fileStructureVersion != 2) // some ISO files have fileStructureVersion == 2. + { + // v24.05: we ignore that field, because we don't know what exact values are allowed there + // throw CHeaderErrorException(); + } + SkipZeros(1); // (Reserved for future standardization) ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); - - // Most ISO contains zeros in the following field (reserved for future standardization). + // Most ISO contain zeros in the following field (reserved for future standardization). // But some ISO programs write some data to that area. // So we disable check for zeros. Skip(653); // SkipZeros(653); @@ -316,7 +322,9 @@ void CInArchive::SeekToBlock(UInt32 blockIndex) { - HRESULT res = _stream->Seek((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize, STREAM_SEEK_SET, &_position); + const HRESULT res = _stream->Seek( + (Int64)((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize), + STREAM_SEEK_SET, &_position); if (res != S_OK) throw CSystemException(res); m_BufferPos = 0; @@ -506,10 +514,10 @@ HRESULT CInArchive::Open2() { _position = 0; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &_fileSize)); + RINOK(InStream_GetSize_SeekToEnd(_stream, _fileSize)) if (_fileSize < kStartPos) return S_FALSE; - RINOK(_stream->Seek(kStartPos, STREAM_SEEK_SET, &_position)); + RINOK(_stream->Seek(kStartPos, STREAM_SEEK_SET, &_position)) PhySize = _position; m_BufferPos = 0; @@ -584,7 +592,7 @@ if (VolDescs.IsEmpty()) return S_FALSE; - for (MainVolDescIndex = VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--) + for (MainVolDescIndex = (int)VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--) if (VolDescs[MainVolDescIndex].IsJoliet()) break; /* FIXME: some volume can contain Rock Ridge, that is better than @@ -593,7 +601,16 @@ const CVolumeDescriptor &vd = VolDescs[MainVolDescIndex]; if (vd.LogicalBlockSize != kBlockSize) return S_FALSE; - + + { + FOR_VECTOR (i, VolDescs) + { + const CVolumeDescriptor &vd2 = VolDescs[i]; + UpdatePhySize(0, vd2.Get_VolumeSpaceSize_inBytes()); + } + } + + IsArc = true; (CDirRecord &)_rootDir = vd.RootDirRecord; @@ -613,6 +630,21 @@ } } } + + { + // find boot item for expand: + // UEFI Specification : 13.3.2.1. ISO-9660 and El Torito + _expand_BootEntries_index = -1; + FOR_VECTOR (i, BootEntries) + { + const CBootInitialEntry &be = BootEntries[i]; + if (be.SectorCount <= 1 && be.BootMediaType == NBootMediaType::kNoEmulation) + if (_expand_BootEntries_index == -1 + || be.LoadRBA >= BootEntries[_expand_BootEntries_index].LoadRBA) + _expand_BootEntries_index = (int)i; + } + } + { FOR_VECTOR (i, BootEntries) { @@ -627,10 +659,10 @@ const UInt64 kRemMax = 1 << 21; if (rem <= kRemMax) { - RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, PhySize)) bool areThereNonZeros = false; UInt64 numZeros = 0; - RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax)); + RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax)) if (!areThereNonZeros) PhySize += numZeros; } @@ -668,6 +700,36 @@ BootEntries.Clear(); SuspSkipSize = 0; IsSusp = false; + + _expand_BootEntries_index = -1; +} + + +UInt64 CInArchive::GetBootItemSize(unsigned index) const +{ + const CBootInitialEntry &be = BootEntries[index]; + UInt64 size = be.GetSize(); + if (be.BootMediaType == NBootMediaType::k1d2Floppy) size = 1200 << 10; + else if (be.BootMediaType == NBootMediaType::k1d44Floppy) size = 1440 << 10; + else if (be.BootMediaType == NBootMediaType::k2d88Floppy) size = 2880 << 10; + const UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize; + if (startPos < _fileSize) + { + const UInt64 rem = _fileSize - startPos; + /* + UEFI modification to ISO specification: + because SectorCount is 16-bit, size is limited by (32 MB). + UEFI Specification : + 13.3.2.1. ISO-9660 and El Torito + If the value of Sector Count is set to 0 or 1, + EFI will assume the system partition consumes the space + from the beginning of the "no emulation" image to the end of the CD-ROM. + */ + // + if ((int)index == _expand_BootEntries_index || rem < size) + size = rem; + } + return size; } }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.h 2022-05-03 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoIn.h 2024-03-03 16:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/IsoIn.h -#ifndef __ARCHIVE_ISO_IN_H -#define __ARCHIVE_ISO_IN_H +#ifndef ZIP7_INC_ARCHIVE_ISO_IN_H +#define ZIP7_INC_ARCHIVE_ISO_IN_H #include "../../../Common/MyCom.h" @@ -20,7 +20,7 @@ void Clear() { - Parent = 0; + Parent = NULL; _subItems.Clear(); } @@ -133,7 +133,7 @@ const bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, v); if (res) { - v -= (Int64)((Int32)GmtOffset * 15 * 60); + v = (UInt64)((Int64)v - (Int64)((Int32)GmtOffset * 15 * 60)); v *= 10000000; if (Hundredths < 100) v += (UInt32)Hundredths * 100000; @@ -214,17 +214,19 @@ CDateTime MTime; CDateTime ExpirationTime; CDateTime EffectiveTime; - Byte FileStructureVersion; // = 1; + // Byte FileStructureVersion; // = 1; Byte ApplicationUse[512]; bool IsJoliet() const { if ((VolFlags & 1) != 0) return false; - Byte b = EscapeSequence[2]; + const Byte b = EscapeSequence[2]; return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && (b == 0x40 || b == 0x43 || b == 0x45)); } + + UInt64 Get_VolumeSpaceSize_inBytes() const { return (UInt64)VolumeSpaceSize * LogicalBlockSize; } }; struct CRef @@ -244,10 +246,6 @@ UInt32 m_BufferPos; - CDir _rootDir; - bool _bootIsDefined; - CBootRecordDescriptor _bootDesc; - void Skip(size_t size); void SkipZeros(size_t size); Byte ReadByte(); @@ -285,17 +283,23 @@ // UInt32 BlockSize; CObjectVector BootEntries; +private: + bool _bootIsDefined; +public: bool IsArc; bool UnexpectedEnd; bool HeadersError; bool IncorrectBigEndian; bool TooDeepDirs; bool SelfLinkedDirs; - CRecordVector UniqStartLocations; + bool IsSusp; + unsigned SuspSkipSize; - Byte m_Buffer[kBlockSize]; + int _expand_BootEntries_index; - void UpdatePhySize(UInt32 blockIndex, UInt64 size) + CRecordVector UniqStartLocations; + + void UpdatePhySize(const UInt32 blockIndex, const UInt64 size) { const UInt64 alignedSize = (size + kBlockSize - 1) & ~((UInt64)kBlockSize - 1); const UInt64 end = (UInt64)blockIndex * kBlockSize + alignedSize; @@ -305,27 +309,12 @@ bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } - UInt64 GetBootItemSize(int index) const - { - const CBootInitialEntry &be = BootEntries[index]; - UInt64 size = be.GetSize(); - if (be.BootMediaType == NBootMediaType::k1d2Floppy) - size = (1200 << 10); - else if (be.BootMediaType == NBootMediaType::k1d44Floppy) - size = (1440 << 10); - else if (be.BootMediaType == NBootMediaType::k2d88Floppy) - size = (2880 << 10); - UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize; - if (startPos < _fileSize) - { - if (_fileSize - startPos < size) - size = _fileSize - startPos; - } - return size; - } + UInt64 GetBootItemSize(unsigned index) const; - bool IsSusp; - unsigned SuspSkipSize; +private: + CDir _rootDir; + Byte m_Buffer[kBlockSize]; + CBootRecordDescriptor _bootDesc; }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoItem.h 2022-05-03 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoItem.h 2023-11-29 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/IsoItem.h -#ifndef __ARCHIVE_ISO_ITEM_H -#define __ARCHIVE_ISO_ITEM_H +#ifndef ZIP7_INC_ARCHIVE_ISO_ITEM_H +#define ZIP7_INC_ARCHIVE_ISO_ITEM_H #include "../../../../C/CpuArch.h" @@ -31,7 +31,7 @@ const bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, v); if (res) { - v -= (Int64)((Int32)GmtOffset * 15 * 60); + v = (UInt64)((Int64)v - (Int64)((Int32)GmtOffset * 15 * 60)); v *= 10000000; prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base); } @@ -101,29 +101,29 @@ { lenRes = 0; if (SystemUse.Size() < skipSize) - return 0; + return NULL; const Byte *p = (const Byte *)SystemUse + skipSize; unsigned rem = (unsigned)(SystemUse.Size() - skipSize); while (rem >= 5) { unsigned len = p[2]; if (len < 3 || len > rem) - return 0; + return NULL; if (p[0] == id0 && p[1] == id1 && p[3] == 1) { if (len < 4) - return 0; // Check it + return NULL; // Check it lenRes = len - 4; return p + 4; } p += len; rem -= len; } - return 0; + return NULL; } - const Byte* GetNameCur(bool checkSusp, int skipSize, unsigned &nameLenRes) const + const Byte* GetNameCur(bool checkSusp, unsigned skipSize, unsigned &nameLenRes) const { const Byte *res = NULL; unsigned len = 0; @@ -148,7 +148,7 @@ } - bool GetSymLink(int skipSize, AString &link) const + bool GetSymLink(unsigned skipSize, AString &link) const { link.Empty(); const Byte *p = NULL; @@ -179,19 +179,19 @@ if (flags & (1 << 1)) link += "./"; else if (flags & (1 << 2)) link += "../"; - else if (flags & (1 << 3)) link += '/'; + else if (flags & (1 << 3)) link.Add_Slash(); else needSlash = true; for (unsigned i = 0; i < cl; i++) { - char c = p[i]; + const Byte c = p[i]; if (c == 0) { break; // return false; } - link += c; + link += (char)c; } p += cl; @@ -201,7 +201,7 @@ break; if (needSlash) - link += '/'; + link.Add_Slash(); } return true; @@ -220,7 +220,7 @@ } - bool GetPx(int skipSize, unsigned pxType, UInt32 &val) const + bool GetPx(unsigned skipSize, unsigned pxType, UInt32 &val) const { val = 0; const Byte *p = NULL; @@ -229,7 +229,7 @@ if (!p) return false; // px.Clear(); - if (len < ((unsigned)pxType + 1) * 8) + if (len < (pxType + 1) * 8) return false; return GetLe32Be32(p + pxType * 8, val); @@ -302,7 +302,7 @@ bool CheckSusp(unsigned &startPos) const { const Byte *p = (const Byte *)SystemUse; - unsigned len = (int)SystemUse.Size(); + const size_t len = SystemUse.Size(); const unsigned kMinLen = 7; if (len < kMinLen) return false; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/IsoRegister.cpp 2015-02-11 09:22:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/IsoRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -12,7 +12,7 @@ static const Byte k_Signature[] = { 'C', 'D', '0', '0', '1' }; REGISTER_ARC_I( - "Iso", "iso img", 0, 0xE7, + "Iso", "iso img", NULL, 0xE7, k_Signature, NArchive::NIso::kStartPos + 1, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Iso/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Iso/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/LpHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LpHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/LpHandler.cpp 2022-02-02 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LpHandler.cpp 2024-11-21 16:00:00.000000000 +0000 @@ -59,9 +59,9 @@ #define LP_METADATA_GEOMETRY_SIZE 4096 #define LP_METADATA_HEADER_MAGIC 0x414C5030 -#define SIGNATURE { 0x67, 0x44, 0x6c, 0x61, 0x34, 0, 0, 0 } static const unsigned k_SignatureSize = 8; -static const Byte k_Signature[k_SignatureSize] = SIGNATURE; +static const Byte k_Signature[k_SignatureSize] = + { 0x67, 0x44, 0x6c, 0x61, 0x34, 0, 0, 0 }; // The length (36) is the same as the maximum length of a GPT partition name. static const unsigned kNameLen = 36; @@ -103,9 +103,9 @@ bool Parse(const Byte *p) { - G32 (40, metadata_max_size); - G32 (44, metadata_slot_count); - G32 (48, logical_block_size); + G32 (40, metadata_max_size) + G32 (44, metadata_slot_count) + G32 (48, logical_block_size) if (metadata_slot_count == 0 || metadata_slot_count >= ((UInt32)1 << 20)) return false; if (metadata_max_size == 0) @@ -135,9 +135,9 @@ void Parse(const Byte *p) { - G32 (0, offset); - G32 (4, num_entries); - G32 (8, entry_size); + G32 (0, offset) + G32 (4, num_entries) + G32 (8, entry_size) } bool CheckLimits(UInt32 limit) const @@ -208,10 +208,10 @@ void Parse(const Byte *p) { memcpy(name, p, kNameLen); - G32 (36, attributes); - G32 (40, first_extent_index); - G32 (44, num_extents); - G32 (48, group_index); + G32 (36, attributes) + G32 (40, first_extent_index) + G32 (44, num_extents) + G32 (48, group_index) } // calced properties: @@ -264,10 +264,10 @@ void Parse(const Byte *p) { - G64 (0, num_sectors); - G32 (8, target_type); - G64 (12, target_data); - G32 (20, target_source); + G64 (0, num_sectors) + G32 (8, target_type) + G64 (12, target_data) + G32 (20, target_source) } }; @@ -289,8 +289,8 @@ void Parse(const Byte *p) { memcpy(name, p, kNameLen); - G32 (36, flags); - G64 (40, maximum_size); + G32 (36, flags) + G64 (40, maximum_size) } }; @@ -358,11 +358,11 @@ void Parse(const Byte *p) { memcpy(partition_name, p + 24, kNameLen); - G64 (0, first_logical_sector); - G32 (8, alignment); - G32 (12, alignment_offset); - G64 (16, size); - G32 (60, flags); + G64 (0, first_logical_sector) + G32 (8, alignment) + G32 (12, alignment_offset) + G64 (16, size) + G32 (60, flags) } }; @@ -439,9 +439,9 @@ void Parse128(const Byte *p) { - G32 (0, magic); - G16 (4, major_version); - G16 (6, minor_version); + G32 (0, magic) + G16 (4, major_version) + G16 (6, minor_version) G32 (8, header_size) // Byte header_checksum[32]; G32 (44, tables_size) @@ -460,9 +460,11 @@ static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum) { + MY_ALIGN (16) CSha256 sha; Sha256_Init(&sha); Sha256_Update(&sha, data, size); + MY_ALIGN (16) Byte calced[32]; Sha256_Final(&sha, calced); return memcmp(checksum, calced, 32) == 0; @@ -470,6 +472,7 @@ static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset) { + MY_ALIGN (4) Byte checksum[32]; Byte *shaData = &data[hashOffset]; memcpy(checksum, shaData, 32); @@ -479,11 +482,9 @@ -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CRecordVector _items; CRecordVector Extents; @@ -505,11 +506,6 @@ AString DeviceArcName; HRESULT Open2(IInStream *stream); - -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; @@ -533,10 +529,11 @@ HRESULT CHandler::Open2(IInStream *stream) { - RINOK(stream->Seek(LP_PARTITION_RESERVED_BYTES, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES)) { + MY_ALIGN (4) Byte buf[k_Geometry_Size]; - RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size)); + RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size)) if (memcmp(buf, k_Signature, k_SignatureSize) != 0) return S_FALSE; if (!geom.Parse(buf)) @@ -546,11 +543,11 @@ } CByteBuffer buffer; - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(stream)) buffer.Alloc(LP_METADATA_GEOMETRY_SIZE * 2); { // buffer.Size() >= LP_PARTITION_RESERVED_BYTES - RINOK(ReadStream_FALSE(stream, buffer, LP_PARTITION_RESERVED_BYTES)); + RINOK(ReadStream_FALSE(stream, buffer, LP_PARTITION_RESERVED_BYTES)) if (!IsBufZero(buffer, LP_PARTITION_RESERVED_BYTES)) { _headerWarning = true; @@ -558,7 +555,7 @@ } } - RINOK(ReadStream_FALSE(stream, buffer, LP_METADATA_GEOMETRY_SIZE * 2)); + RINOK(ReadStream_FALSE(stream, buffer, LP_METADATA_GEOMETRY_SIZE * 2)) // we check that 2 copies of GEOMETRY are identical: if (memcmp(buffer, buffer + LP_METADATA_GEOMETRY_SIZE, LP_METADATA_GEOMETRY_SIZE) != 0 || !IsBufZero(buffer + k_Geometry_Size, LP_METADATA_GEOMETRY_SIZE - k_Geometry_Size)) @@ -567,7 +564,7 @@ // return S_FALSE; } - RINOK(ReadStream_FALSE(stream, buffer, k_LpMetadataHeader10_size)); + RINOK(ReadStream_FALSE(stream, buffer, k_LpMetadataHeader10_size)) LpMetadataHeader header; header.Parse128(buffer); if (header.magic != LP_METADATA_HEADER_MAGIC || @@ -580,7 +577,7 @@ if (header.header_size != k_LpMetadataHeader12_size) return S_FALSE; RINOK(ReadStream_FALSE(stream, buffer + k_LpMetadataHeader10_size, - header.header_size - k_LpMetadataHeader10_size)); + header.header_size - k_LpMetadataHeader10_size)) Flags = Get32(buffer + k_LpMetadataHeader10_size); } Major_version = header.major_version; @@ -594,7 +591,7 @@ return S_FALSE; buffer.AllocAtLeast(header.tables_size); - RINOK(ReadStream_FALSE(stream, buffer, header.tables_size)); + RINOK(ReadStream_FALSE(stream, buffer, header.tables_size)) const UInt64 totalMetaSize = geom.GetTotalMetadataSize(); // _headersSize = _totalSize; @@ -733,13 +730,13 @@ } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - RINOK(Open2(stream)); + RINOK(Open2(stream)) _stream = stream; int mainFileIndex = -1; @@ -750,7 +747,7 @@ CPartition &item = _items[fileIndex]; if (item.NumSectors != 0) { - mainFileIndex = fileIndex; + mainFileIndex = (int)fileIndex; numNonEmptyParts++; CMyComPtr parseStream; if (GetStream(fileIndex, &parseStream) == S_OK && parseStream) @@ -775,7 +772,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; // _usedSize = 0; @@ -818,7 +815,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -849,7 +846,7 @@ { AString s; s.Add_UInt32(Major_version); - s += '.'; + s.Add_Dot(); s.Add_UInt32(Minor_version); prop = s; break; @@ -874,7 +871,7 @@ if (Flags != 0) { s += "flags: "; - s += FlagsToString(g_Header_Flags, ARRAY_SIZE(g_Header_Flags), Flags); + s += FlagsToString(g_Header_Flags, Z7_ARRAY_SIZE(g_Header_Flags), Flags); s.Add_LF(); } @@ -916,14 +913,14 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -940,7 +937,7 @@ s.Add_UInt32(index); if (item.num_extents != 0) { - s += '.'; + s.Add_Dot(); s += (item.Ext ? item.Ext : "img"); } prop = s; @@ -971,7 +968,7 @@ s += "group:"; s.Add_UInt32(item.group_index); s.Add_Space(); - s += FlagsToString(g_PartitionAttr, ARRAY_SIZE(g_PartitionAttr), item.attributes); + s += FlagsToString(g_PartitionAttr, Z7_ARRAY_SIZE(g_PartitionAttr), item.attributes); prop = s; break; } @@ -984,7 +981,7 @@ -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; @@ -1093,8 +1090,8 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN const bool allFilesMode = (numItems == (UInt32)(Int32)-1); @@ -1124,21 +1121,21 @@ { lps->InSize = totalSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr outStream; const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) const UInt64 size = _items[index].GetSize(); totalSize += size; if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) CMyComPtr inStream; const HRESULT hres = GetStream(index, &inStream); @@ -1147,7 +1144,7 @@ { if (hres != S_OK) return hres; - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) opRes = NExtract::NOperationResult::kDataError; if (copyCoderSpec->TotalSize == size) opRes = NExtract::NOperationResult::kOK; @@ -1155,7 +1152,7 @@ opRes = NExtract::NOperationResult::kUnexpectedEnd; } outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/LvmHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LvmHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/LvmHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LvmHandler.cpp 2023-12-19 08:00:00.000000000 +0000 @@ -0,0 +1,1107 @@ +// LvmHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringToInt.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define LE_32(offs, dest) dest = Get32(p + (offs)) +#define LE_64(offs, dest) dest = Get64(p + (offs)) + +using namespace NWindows; + +namespace NArchive { +namespace NLvm { + +#define SIGNATURE { 'L', 'A', 'B', 'E', 'L', 'O', 'N', 'E' } + +static const unsigned k_SignatureSize = 8; +static const Byte k_Signature[k_SignatureSize] = SIGNATURE; + +static const unsigned k_Signature2Size = 8; +static const Byte k_Signature2[k_Signature2Size] = + { 'L', 'V', 'M', '2', ' ', '0', '0', '1' }; + +static const Byte FMTT_MAGIC[16] = + { ' ', 'L', 'V', 'M', '2', ' ', 'x', '[', '5', 'A', '%', 'r', '0', 'N', '*', '>' }; + +static const UInt32 kSectorSize = 512; + + +struct CPropVal +{ + bool IsNumber; + AString String; + UInt64 Number; + + CPropVal(): IsNumber(false), Number(0) {} +}; + + +struct CConfigProp +{ + AString Name; + + bool IsVector; + CPropVal Val; + CObjectVector Vector; + + CConfigProp(): IsVector(false) {} +}; + + +class CConfigItem +{ +public: + AString Name; + CObjectVector Props; + CObjectVector Items; + + const char *ParseItem(const char *s, int numAllowedLevels); + + int FindProp(const char *name) const throw(); + bool GetPropVal_Number(const char *name, UInt64 &val) const throw(); + bool GetPropVal_String(const char *name, AString &val) const; + + int FindSubItem(const char *tag) const throw(); +}; + +struct CConfig +{ + CConfigItem Root; + + bool Parse(const char *s); +}; + + +static bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); +} + +static const char *SkipSpaces(const char * s) +{ + for (;; s++) + { + const char c = *s; + if (c == 0) + return s; + if (!IsSpaceChar(c)) + { + if (c != '#') + return s; + s++; + for (;;) + { + const char c2 = *s; + if (c2 == 0) + return s; + if (c2 == '\n') + break; + s++; + } + } + } +} + +#define SKIP_SPACES(s) s = SkipSpaces(s); + +int CConfigItem::FindProp(const char *name) const throw() +{ + FOR_VECTOR (i, Props) + if (Props[i].Name == name) + return (int)i; + return -1; +} + +bool CConfigItem::GetPropVal_Number(const char *name, UInt64 &val) const throw() +{ + val = 0; + int index = FindProp(name); + if (index < 0) + return false; + const CConfigProp &prop = Props[index]; + if (prop.IsVector) + return false; + if (!prop.Val.IsNumber) + return false; + val = prop.Val.Number; + return true; +} + +bool CConfigItem::GetPropVal_String(const char *name, AString &val) const +{ + val.Empty(); + int index = FindProp(name); + if (index < 0) + return false; + const CConfigProp &prop = Props[index]; + if (prop.IsVector) + return false; + if (prop.Val.IsNumber) + return false; + val = prop.Val.String; + return true; +} + +int CConfigItem::FindSubItem(const char *tag) const throw() +{ + FOR_VECTOR (i, Items) + if (Items[i].Name == tag) + return (int)i; + return -1; +} + +static const char *FillProp(const char *s, CPropVal &val) +{ + SKIP_SPACES(s) + const char c = *s; + if (c == 0) + return NULL; + + if (c == '\"') + { + s++; + val.IsNumber = false; + val.String.Empty(); + + for (;;) + { + const char c2 = *s; + if (c2 == 0) + return NULL; + s++; + if (c2 == '\"') + break; + val.String += c2; + } + } + else + { + const char *end; + val.IsNumber = true; + val.Number = ConvertStringToUInt64(s, &end); + if (s == end) + return NULL; + s = end; + } + + SKIP_SPACES(s) + return s; +} + + +const char *CConfigItem::ParseItem(const char *s, int numAllowedLevels) +{ + if (numAllowedLevels < 0) + return NULL; + + for (;;) + { + SKIP_SPACES(s) + const char *beg = s; + + for (;; s++) + { + char c = *s; + if (c == 0 || c == '}') + { + if (s != beg) + return NULL; + return s; + } + if (IsSpaceChar(c) || c == '=' || c == '{') + break; + } + + if (s == beg) + return NULL; + + AString name; + name.SetFrom(beg, (unsigned)(s - beg)); + + SKIP_SPACES(s) + + if (*s == 0 || *s == '}') + return NULL; + + if (*s == '{') + { + s++; + CConfigItem &item = Items.AddNew(); + item.Name = name; + s = item.ParseItem(s, numAllowedLevels - 1); + if (!s) + return NULL; + if (*s != '}') + return NULL; + s++; + continue; + } + + if (*s != '=') + continue; + + s++; + SKIP_SPACES(s) + if (*s == 0) + return NULL; + CConfigProp &prop = Props.AddNew(); + + prop.Name = name; + + if (*s == '[') + { + s++; + prop.IsVector = true; + + for (;;) + { + SKIP_SPACES(s) + char c = *s; + if (c == 0) + return NULL; + if (c == ']') + { + s++; + break; + } + + CPropVal val; + + s = FillProp(s, val); + if (!s) + return NULL; + prop.Vector.Add(val); + SKIP_SPACES(s) + + if (*s == ',') + { + s++; + continue; + } + if (*s != ']') + return NULL; + s++; + break; + } + } + else + { + prop.IsVector = false; + s = FillProp(s, prop.Val); + if (!s) + return NULL; + } + } +} + + +bool CConfig::Parse(const char *s) +{ + s = Root.ParseItem(s, 10); + if (!s) + return false; + SKIP_SPACES(s) + return *s == 0; +} + + +/* +static const CUInt32PCharPair g_PartitionFlags[] = +{ + { 0, "Sys" }, + { 1, "Ignore" }, + { 2, "Legacy" }, + { 60, "Win-Read-only" }, + { 62, "Win-Hidden" }, + { 63, "Win-Not-Automount" } +}; +*/ + +/* +static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } + +static void PrintHex(unsigned v, char *s) +{ + s[0] = GetHex((v >> 4) & 0xF); + s[1] = GetHex(v & 0xF); +} + +static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw() +{ + PrintHex(val >> 8, s); + PrintHex(val & 0xFF, s + 2); +} + +static void GuidToString(const Byte *g, char *s) +{ + ConvertUInt32ToHex8Digits(Get32(g ), s); s += 8; *s++ = '-'; + ConvertUInt16ToHex4Digits(Get16(g + 4), s); s += 4; *s++ = '-'; + ConvertUInt16ToHex4Digits(Get16(g + 6), s); s += 4; *s++ = '-'; + for (unsigned i = 0; i < 8; i++) + { + if (i == 2) + *s++ = '-'; + PrintHex(g[8 + i], s); + s += 2; + } + *s = 0; +} + +*/ + +struct CPhyVol +{ + AString Name; + + // AString id; + // AString device; // "/dev/sda2" + // AString status; // ["ALLOCATABLE"] + // AString flags; // [] + // UInt64 dev_size; // in sectors + UInt64 pe_start; // in sectors + UInt64 pe_count; // in extents + + bool Parse(const CConfigItem &ci) + { + Name = ci.Name; + // ci.GetPropVal_String("id", id); + // ci.GetPropVal_String("device", device); + bool res = true; + // if (!ci.GetPropVal_Number("dev_size", dev_size)) res = false; + if (!ci.GetPropVal_Number("pe_start", pe_start)) res = false; + if (!ci.GetPropVal_Number("pe_count", pe_count)) res = false; + return res; + } +}; + +struct CStripe +{ + AString Name; // "pv0"; + UInt64 ExtentOffset; // ???? +}; + +struct CSegment +{ + UInt64 start_extent; + UInt64 extent_count; + AString type; + CObjectVector stripes; + + bool IsPosSizeOk() const + { + return + (start_extent < ((UInt64)1 << 63)) && + (extent_count < ((UInt64)1 << 63)); + } + + UInt64 GetEndExtent() const { return start_extent + extent_count; } + + bool Parse(const CConfigItem &si) + { + UInt64 stripe_count; + + if (!si.GetPropVal_Number("start_extent", start_extent)) return false; + if (!si.GetPropVal_Number("extent_count", extent_count)) return false; + if (!si.GetPropVal_Number("stripe_count", stripe_count)) return false; + if (!si.GetPropVal_String("type", type)) return false; + + //if (stripe_count != 1) return false; + + const int spi = si.FindProp("stripes"); + if (spi < 0) + return false; + + const CConfigProp &prop = si.Props[spi]; + if (!prop.IsVector) + return false; + + if (stripe_count > (1 << 20)) + return false; + + const unsigned numStripes = (unsigned)stripe_count; + if (prop.Vector.Size() != numStripes * 2) + return false; + + for (unsigned i = 0; i < numStripes; i++) + { + const CPropVal &v0 = prop.Vector[i * 2]; + const CPropVal &v1 = prop.Vector[i * 2 + 1]; + if (v0.IsNumber || !v1.IsNumber) + return false; + CStripe stripe; + stripe.Name = v0.String; + stripe.ExtentOffset = v1.Number; + stripes.Add(stripe); + } + + return true; + } +}; + + +struct CLogVol +{ + bool IsSupported; + + AString Name; + + AString id; + AString status; // ["READ", "WRITE", "VISIBLE"] + AString flags; // [] + + // UInt64 Pos; + // UInt64 Size; + + // UInt64 GetSize() const { return Size; } + // UInt64 GetPos() const { return Pos; } + + CObjectVector Segments; + + CLogVol(): /* Pos(0), Size(0), */ IsSupported(false) {} + + bool Parse(const CConfigItem &ci) + { + Name = ci.Name; + + UInt64 segment_count; + if (!ci.GetPropVal_Number("segment_count", segment_count)) + return false; + + if (ci.Items.Size() != segment_count) + return false; + + FOR_VECTOR (segIndex, ci.Items) + { + const CConfigItem &si = ci.Items[segIndex]; + { + AString t ("segment"); + t.Add_UInt32(segIndex + 1); + if (si.Name != t) + return false; + } + + CSegment segment; + + if (!segment.Parse(si)) + return false; + + // item.Size += (segment.extent_count * _extentSize) << 9; + + Segments.Add(segment); + } + + IsSupported = true; + return true; + } + + bool GetNumExtents(UInt64 &numExtents) const + { + numExtents = 0; + if (Segments.IsEmpty()) + return true; + unsigned i; + for (i = 1; i < Segments.Size(); i++) + if (!Segments[i].IsPosSizeOk()) + return false; + for (i = 1; i < Segments.Size(); i++) + if (Segments[i - 1].GetEndExtent() != Segments[i].start_extent) + return false; + numExtents = Segments.Back().GetEndExtent(); + return true; + } +}; + + +struct CItem +{ + int LogVol; + int PhyVol; + UInt64 Pos; + UInt64 Size; + AString Name; + bool IsSupported; + + CItem(): LogVol(-1), PhyVol(-1), Pos(0), Size(0), IsSupported(false) {} +}; + + +struct CVolGroup +{ + CObjectVector _logVols; + CObjectVector _phyVols; + AString _id; + int _extentSizeBits; + + /* + UInt64 secno; // 3 + AString status; // ["RESIZEABLE", "READ", "WRITE"] + AString flags; // [] + UInt64 max_lv; // 0 + UInt64 max_pv; // 0 + UInt64 metadata_copies; // 0 + */ + + void Clear() + { + _logVols.Clear(); + _phyVols.Clear(); + _id.Empty(); + _extentSizeBits = -1; + } +}; + + +Z7_class_CHandler_final: public CHandlerCont, public CVolGroup +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + CObjectVector _items; + + UInt64 _cTime; + + bool _isArc; + + UInt64 _phySize; + CByteBuffer _buffer; + + UInt64 _cfgPos; + UInt64 _cfgSize; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + if (index >= _items.Size()) + { + pos = _cfgPos; + size = _cfgSize; + return NExtract::NOperationResult::kOK; + } + const CItem &item = _items[index]; + if (!item.IsSupported) + return NExtract::NOperationResult::kUnsupportedMethod; + pos = item.Pos; + size = item.Size; + return NExtract::NOperationResult::kOK; + } +}; + +static const UInt32 LVM_CRC_INIT_VAL = 0xf597a6cf; + +static UInt32 Z7_FASTCALL LvmCrcCalc(const void *data, size_t size) +{ + return CrcUpdate(LVM_CRC_INIT_VAL, data, size); +} + +struct CRawLocn +{ + UInt64 Offset; /* Offset in bytes to start sector */ + UInt64 Size; /* Bytes */ + UInt32 Checksum; + UInt32 Flags; + + bool IsEmpty() const { return Offset == 0 && Size == 0; } + + void Parse(const Byte *p) + { + LE_64(0x00, Offset); + LE_64(0x08, Size); + LE_32(0x10, Checksum); + LE_32(0x14, Flags); + } +}; + +// #define MDA_HEADER_SIZE 512 + +struct mda_header +{ + UInt64 Start; /* Absolute start byte of mda_header */ + UInt64 Size; /* Size of metadata area */ + + CRecordVector raw_locns; + + bool Parse(const Byte *p, size_t size) + { + if (memcmp(p + 4, FMTT_MAGIC, 16) != 0) + return false; + UInt32 version; + LE_32(0x14, version); + if (version != 1) + return false; + LE_64(0x18, Start); + LE_64(0x20, Size); + + unsigned pos = 0x28; + + for (;;) + { + if (pos + 0x18 > size) + return false; + CRawLocn locn; + locn.Parse(p + pos); + if (locn.IsEmpty()) + break; + pos += 0x18; + raw_locns.Add(locn); + } + + return true; + } +}; + + +static int inline GetLog(UInt64 num) +{ + for (unsigned i = 0; i < 64; i++) + if (((UInt64)1 << i) == num) + return (int)i; + return -1; +} + +#define ID_LEN 32 + +HRESULT CHandler::Open2(IInStream *stream) +{ + _buffer.Alloc(kSectorSize * 2); + RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2)) + + const Byte *buf = _buffer; + + buf += kSectorSize; + + // label_header + + if (memcmp(buf, k_Signature, k_SignatureSize) != 0) + return S_FALSE; + const UInt64 sectorNumber = Get64(buf + 8); + if (sectorNumber != 1) + return S_FALSE; + if (Get32(buf + 16) != LvmCrcCalc(buf + 20, kSectorSize - 20)) + return S_FALSE; + + const UInt32 offsetToCont = Get32(buf + 20); + if (memcmp(buf + 24, k_Signature2, k_Signature2Size) != 0) + return S_FALSE; + + if (offsetToCont != 32) + return S_FALSE; + + // pv_header + + size_t pos = offsetToCont; + const Byte *p = buf; + + /* + { + Byte id[ID_LEN]; + memcpy(id, p + pos, ID_LEN); + } + */ + + pos += ID_LEN; + const UInt64 device_size_xl = Get64(p + pos); + pos += 8; + + _phySize = device_size_xl; + _isArc = true; + + for (;;) + { + if (pos > kSectorSize - 16) + return S_FALSE; + // disk_locn (data areas) + UInt64 offset = Get64(p + pos); + UInt64 size = Get64(p + pos + 8); + pos += 16; + if (offset == 0 && size == 0) + break; + } + + CConfig cfg; + // bool isFinded = false; + + // for (;;) + { + if (pos > kSectorSize - 16) + return S_FALSE; + // disk_locn (metadata area headers) + UInt64 offset = Get64(p + pos); + UInt64 size = Get64(p + pos + 8); + pos += 16; + if (offset == 0 && size == 0) + { + // break; + return S_FALSE; + } + + CByteBuffer meta; + const size_t sizeT = (size_t)size; + if (sizeT != size) + return S_FALSE; + meta.Alloc(sizeT); + RINOK(InStream_SeekSet(stream, offset)) + RINOK(ReadStream_FALSE(stream, meta, sizeT)) + if (Get32(meta) != LvmCrcCalc(meta + 4, kSectorSize - 4)) + return S_FALSE; + mda_header mh; + if (!mh.Parse(meta, kSectorSize)) + return S_FALSE; + + if (mh.raw_locns.Size() != 1) + return S_FALSE; + unsigned g = 0; + // for (unsigned g = 0; g < mh.raw_locns.Size(); g++) + { + const CRawLocn &locn = mh.raw_locns[g]; + + CByteBuffer vgBuf; + if (locn.Size > ((UInt32)1 << 24)) + return S_FALSE; + + const size_t vgSize = (size_t)locn.Size; + if (vgSize == 0) + return S_FALSE; + + vgBuf.Alloc(vgSize); + + _cfgPos = offset + locn.Offset; + _cfgSize = vgSize; + RINOK(InStream_SeekSet(stream, _cfgPos)) + RINOK(ReadStream_FALSE(stream, vgBuf, vgSize)) + if (locn.Checksum != LvmCrcCalc(vgBuf, vgSize)) + return S_FALSE; + + { + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)vgBuf, (unsigned)vgSize); + _cfgSize = s.Len(); + if (!cfg.Parse(s)) + return S_FALSE; + // isFinded = true; + // break; + } + } + + // if (isFinded) break; + } + + // if (!isFinded) return S_FALSE; + + if (cfg.Root.Items.Size() != 1) + return S_FALSE; + const CConfigItem &volGroup = cfg.Root.Items[0]; + if (volGroup.Name != "VolGroup00") + return S_FALSE; + + volGroup.GetPropVal_String("id", _id); + + if (!cfg.Root.GetPropVal_Number("creation_time", _cTime)) + _cTime = 0; + + UInt64 extentSize; + if (!volGroup.GetPropVal_Number("extent_size", extentSize)) + return S_FALSE; + + _extentSizeBits = GetLog(extentSize); + if (_extentSizeBits < 0 || _extentSizeBits > (62 - 9)) + return S_FALSE; + + + { + int pvsIndex = volGroup.FindSubItem("physical_volumes"); + if (pvsIndex < 0) + return S_FALSE; + + const CConfigItem &phyVols = volGroup.Items[pvsIndex]; + + FOR_VECTOR (i, phyVols.Items) + { + const CConfigItem &ci = phyVols.Items[i]; + CPhyVol pv; + if (!pv.Parse(ci)) + return S_FALSE; + _phyVols.Add(pv); + } + } + + { + int lvIndex = volGroup.FindSubItem("logical_volumes"); + if (lvIndex < 0) + return S_FALSE; + + const CConfigItem &logVolumes = volGroup.Items[lvIndex]; + + FOR_VECTOR (i, logVolumes.Items) + { + const CConfigItem &ci = logVolumes.Items[i]; + CLogVol &lv = _logVols.AddNew(); + lv.Parse(ci) ; // check error + } + } + + { + FOR_VECTOR (i, _logVols) + { + CLogVol &lv = _logVols[i]; + + CItem item; + + item.LogVol = (int)i; + item.Pos = 0; + item.Size = 0; + item.Name = lv.Name; + + if (lv.IsSupported) + { + UInt64 numExtents; + lv.IsSupported = lv.GetNumExtents(numExtents); + + if (lv.IsSupported) + { + lv.IsSupported = false; + item.Size = numExtents << (_extentSizeBits + 9); + + if (lv.Segments.Size() == 1) + { + const CSegment &segment = lv.Segments[0]; + if (segment.stripes.Size() == 1) + { + const CStripe &stripe = segment.stripes[0]; + FOR_VECTOR (pvIndex, _phyVols) + { + const CPhyVol &pv = _phyVols[pvIndex]; + if (pv.Name == stripe.Name) + { + item.Pos = (pv.pe_start + (stripe.ExtentOffset << _extentSizeBits)) << 9; + lv.IsSupported = true; + item.IsSupported = true; + break; + } + } + } + } + } + } + + _items.Add(item); + } + } + + { + FOR_VECTOR (i, _phyVols) + { + const CPhyVol &pv = _phyVols[i]; + + if (pv.pe_start > (UInt64)1 << (62 - 9)) + return S_FALSE; + if (pv.pe_count > (UInt64)1 << (62 - 9 - _extentSizeBits)) + return S_FALSE; + + CItem item; + + item.PhyVol = (int)i; + item.Pos = pv.pe_start << 9; + item.Size = pv.pe_count << (_extentSizeBits + 9); + item.Name = pv.Name; + item.IsSupported = true; + + _items.Add(item); + } + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(stream)) + _stream = stream; + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + CVolGroup::Clear(); + + _cfgPos = 0; + _cfgSize = 0; + _cTime = 0; + _phySize = 0; + _isArc = false; + _items.Clear(); + + _stream.Release(); + return S_OK; +} + + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidFileSystem, + kpidCharacts, + kpidOffset, + kpidId +}; + +static const Byte kArcProps[] = +{ + kpidId, + kpidCTime, + kpidClusterSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidMainSubfile: + { + /* + if (_items.Size() == 1) + prop = (UInt32)0; + */ + break; + } + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidId: + { + prop = _id; + break; + } + case kpidClusterSize: + { + if (_extentSizeBits >= 0) + prop = ((UInt64)1 << (_extentSizeBits + 9)); + break; + } + case kpidCTime: + { + if (_cTime != 0) + { + FILETIME ft; + NTime::UnixTime64_To_FileTime((Int64)_cTime, ft); + prop = ft; + } + break; + } + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + // if (_headerError) v |= kpv_ErrorFlags_HeadersError; + if (v == 0 && !_stream) + v |= kpv_ErrorFlags_UnsupportedMethod; + if (v != 0) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size() + (_cfgSize == 0 ? 0 : 1); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CItem &item = _items[index]; + + // const CLogVol &item = _items[index]; + + if (index >= _items.Size()) + { + switch (propID) + { + case kpidPath: + { + prop = "meta.txt"; + break; + } + + case kpidSize: + case kpidPackSize: prop = _cfgSize; break; + } + } + else + { + switch (propID) + { + case kpidPath: + { + AString s = item.Name; + s += ".img"; + prop = s; + break; + } + + case kpidSize: + case kpidPackSize: prop = item.Size; break; + case kpidOffset: prop = item.Pos; break; + + case kpidId: + { + // prop = item.id; + break; + } + + // case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "LVM", "lvm", NULL, 0xBF, + k_Signature, + kSectorSize, + 0, + NULL) + +}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/LzhHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzhHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/LzhHandler.cpp 2022-02-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzhHandler.cpp 2024-06-07 04:00:00.000000000 +0000 @@ -4,6 +4,7 @@ #include "../../../C/CpuArch.h" +#include "../../Common/AutoPtr.h" #include "../../Common/ComTry.h" #include "../../Common/MyBuffer.h" #include "../../Common/StringConvert.h" @@ -37,6 +38,7 @@ static const UInt16 kCrc16Poly = 0xA001; +MY_ALIGN(64) static UInt16 g_LzhCrc16Table[256]; #define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) @@ -51,9 +53,8 @@ return crc; } -static class CLzhCrc16TableInit +static struct CLzhCrc16TableInit { -public: CLzhCrc16TableInit() { for (UInt32 i = 0; i < 256; i++) @@ -176,7 +177,7 @@ { FOR_VECTOR (i, Extensions) if (Extensions[i].Type == type) - return i; + return (int)i; return -1; } @@ -220,7 +221,7 @@ AString s (GetDirName()); const char kDirSeparator = '\\'; // check kDirSeparator in Linux - s.Replace((char)(unsigned char)0xFF, kDirSeparator); + s.Replace((char)(Byte)0xFF, kDirSeparator); if (!s.IsEmpty() && s.Back() != kDirSeparator) s += kDirSeparator; s += GetFileName(); @@ -239,10 +240,10 @@ s.Empty(); for (size_t i = 0; i < size; i++) { - char c = p[i]; + const Byte c = p[i]; if (c == 0) break; - s += c; + s += (char)c; } return p + size; } @@ -271,7 +272,7 @@ Byte header[256]; processedSize = kBasicPartSize; - RINOK(ReadStream(stream, header, &processedSize)); + RINOK(ReadStream(stream, header, &processedSize)) if (processedSize != kBasicPartSize) return (startHeader[0] == 0) ? S_OK: S_FALSE; @@ -294,11 +295,11 @@ headerSize = startHeader[0]; if (headerSize < kBasicPartSize) return S_FALSE; - RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize)); + RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize)) if (startHeader[1] != CalcSum(header, headerSize)) return S_FALSE; - size_t nameLength = *p++; - if ((p - header) + nameLength + 2 > headerSize) + const size_t nameLength = *p++; + if ((size_t)(p - header) + nameLength + 2 > headerSize) return S_FALSE; p = ReadString(p, nameLength, item.Name); } @@ -309,7 +310,7 @@ { if (item.Level == 2) { - RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2)); + RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2)) } if ((size_t)(p - header) + 3 > headerSize) return S_FALSE; @@ -335,7 +336,7 @@ RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize)) item.Extensions.Add(ext); Byte hdr2[2]; - RINOK(ReadStream_FALSE(stream, hdr2, 2)); + RINOK(ReadStream_FALSE(stream, hdr2, 2)) ReadUInt16(hdr2, nextSize); } } @@ -380,15 +381,10 @@ }; -class COutStreamWithCRC: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithCRC + , ISequentialOutStream +) UInt32 _crc; CMyComPtr _stream; public: @@ -401,7 +397,7 @@ UInt32 GetCRC() const { return _crc; } }; -STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT res = S_OK; if (_stream) @@ -419,18 +415,14 @@ }; -class CHandler: - public IInArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_0 + CObjectVector _items; CMyComPtr _stream; UInt64 _phySize; UInt32 _errorFlags; bool _isArc; public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) CHandler(); }; @@ -439,13 +431,13 @@ CHandler::CHandler() {} -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -462,7 +454,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -481,8 +473,8 @@ break; } case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidPackSize: prop = item.PackSize; break; + case kpidSize: prop = (UInt64)item.Size; break; + case kpidPackSize: prop = (UInt64)item.PackSize; break; case kpidCRC: prop = (UInt32)item.CRC; break; case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break; case kpidMTime: @@ -509,8 +501,8 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); @@ -518,18 +510,17 @@ { _items.Clear(); - UInt64 endPos = 0; + UInt64 endPos; bool needSetTotal = true; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_AtBegin_GetSize(stream, endPos)) for (;;) { CItemEx item; bool filled; - HRESULT res = GetNextItem(stream, filled, item); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition)); + const HRESULT res = GetNextItem(stream, filled, item); + RINOK(InStream_GetPos(stream, item.DataPosition)) if (res == S_FALSE) { _errorFlags = kpv_ErrorFlags_HeadersError; @@ -546,7 +537,7 @@ _isArc = true; UInt64 newPostion; - RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion)); + RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion)) if (newPostion > endPos) { _phySize = endPos; @@ -558,14 +549,14 @@ { if (needSetTotal) { - RINOK(callback->SetTotal(NULL, &endPos)); + RINOK(callback->SetTotal(NULL, &endPos)) needSetTotal = false; } if (_items.Size() % 100 == 0) { - UInt64 numFiles = _items.Size(); - UInt64 numBytes = item.DataPosition; - RINOK(callback->SetCompleted(&numFiles, &numBytes)); + const UInt64 numFiles = _items.Size(); + const UInt64 numBytes = item.DataPosition; + RINOK(callback->SetCompleted(&numFiles, &numBytes)) } } } @@ -582,7 +573,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; _phySize = 0; @@ -592,111 +583,95 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool testMode = (testModeSpec != 0); - UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) return S_OK; + UInt64 totalUnPacked = 0 /* , totalPacked = 0 */; UInt32 i; for (i = 0; i < numItems; i++) { const CItemEx &item = _items[allFilesMode ? i : indices[i]]; totalUnPacked += item.Size; - totalPacked += item.PackSize; + // totalPacked += item.PackSize; } - RINOK(extractCallback->SetTotal(totalUnPacked)); + RINOK(extractCallback->SetTotal(totalUnPacked)) - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; - - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; - CMyComPtr lzhDecoder; - // CMyComPtr lzh1Decoder; - // CMyComPtr arj2Decoder; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + UInt32 cur_Unpacked, cur_Packed; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyUniquePtr lzhDecoder; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++, + lps->OutSize += cur_Unpacked, + lps->InSize += cur_Packed) + { + cur_Unpacked = 0; + cur_Packed = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + break; - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - currentItemUnPacked = 0; - currentItemPacked = 0; - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - RINOK(lps->SetCur()); - - CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) + Int32 opRes; { - // if (!testMode) + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItemEx &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + continue; } - continue; - } - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - currentItemUnPacked = item.Size; - currentItemPacked = item.PackSize; + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + cur_Unpacked = item.Size; + cur_Packed = item.PackSize; - { - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(realOutStream); + CMyComPtr2_Create outStream; + outStream->Init(realOutStream); realOutStream.Release(); - UInt64 pos; - _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); + RINOK(InStream_SeekSet(_stream, item.DataPosition)) - streamSpec->Init(item.PackSize); + inStream->Init(item.PackSize); HRESULT res = S_OK; - Int32 opRes = NExtract::NOperationResult::kOK; + opRes = NExtract::NOperationResult::kOK; if (item.IsCopyMethod()) { - res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (res == S_OK && copyCoderSpec->TotalSize != item.PackSize) + res = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + if (res == S_OK && copyCoder->TotalSize != item.PackSize) res = S_FALSE; } else if (item.IsLh4GroupMethod()) { - if (!lzhDecoder) - { - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - } - lzhDecoderSpec->FinishMode = true; - lzhDecoderSpec->SetDictSize(1 << item.GetNumDictBits()); - res = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); - if (res == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize) + lzhDecoder.Create_if_Empty(); + // lzhDecoder->FinishMode = true; + lzhDecoder->SetDictSize((UInt32)1 << item.GetNumDictBits()); + res = lzhDecoder->Code(inStream, outStream, cur_Unpacked, lps); + if (res == S_OK && lzhDecoder->GetInputProcessedSize() != item.PackSize) res = S_FALSE; } /* @@ -708,7 +683,7 @@ lzh1Decoder = lzh1DecoderSpec; } lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); - res = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); + res = lzh1Decoder->Code(inStream, outStream, NULL, &cur_Unpacked, progress); } */ else @@ -720,14 +695,13 @@ opRes = NExtract::NOperationResult::kDataError; else { - RINOK(res); - if (outStreamSpec->GetCRC() != item.CRC) + RINOK(res) + if (outStream->GetCRC() != item.CRC) opRes = NExtract::NOperationResult::kCRCError; } } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END @@ -736,7 +710,7 @@ static const Byte k_Signature[] = { '-', 'l', 'h' }; REGISTER_ARC_I( - "Lzh", "lzh lha", 0, 6, + "Lzh", "lzh lha", NULL, 6, k_Signature, 2, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/LzmaHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzmaHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/LzmaHandler.cpp 2019-07-04 11:00:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/LzmaHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -76,35 +76,30 @@ && CheckDicSize(LzmaProps + 1); } -class CDecoder +class CDecoder Z7_final { CMyComPtr _bcjStream; CFilterCoder *_filterCoder; - CMyComPtr _lzmaDecoder; public: - NCompress::NLzma::CDecoder *_lzmaDecoderSpec; + CMyComPtr2 _lzmaDecoder; ~CDecoder(); HRESULT Create(bool filtered, ISequentialInStream *inStream); HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress); - UInt64 GetInputProcessedSize() const { return _lzmaDecoderSpec->GetInputProcessedSize(); } + UInt64 GetInputProcessedSize() const { return _lzmaDecoder->GetInputProcessedSize(); } - void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoderSpec->ReleaseInStream(); } + void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoder->ReleaseInStream(); } HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize) - { return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); } + { return _lzmaDecoder->ReadFromInputStream(data, size, processedSize); } }; HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream) { - if (!_lzmaDecoder) - { - _lzmaDecoderSpec = new NCompress::NLzma::CDecoder; - _lzmaDecoderSpec->FinishStream = true; - _lzmaDecoder = _lzmaDecoderSpec; - } + _lzmaDecoder.Create_if_Empty(); + _lzmaDecoder->FinishStream = true; if (filteredMode) { @@ -112,12 +107,12 @@ { _filterCoder = new CFilterCoder(false); CMyComPtr coder = _filterCoder; - _filterCoder->Filter = new NCompress::NBcj::CCoder(false); + _filterCoder->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec); _bcjStream = _filterCoder; } } - return _lzmaDecoderSpec->SetInStream(inStream); + return _lzmaDecoder->SetInStream(inStream); } CDecoder::~CDecoder() @@ -131,19 +126,19 @@ if (header.FilterID > 1) return E_NOTIMPL; - RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5)); + RINOK(_lzmaDecoder->SetDecoderProperties2(header.LzmaProps, 5)) bool filteredMode = (header.FilterID == 1); if (filteredMode) { - RINOK(_filterCoder->SetOutStream(outStream)); + RINOK(_filterCoder->SetOutStream(outStream)) outStream = _bcjStream; - RINOK(_filterCoder->SetOutStreamSize(NULL)); + RINOK(_filterCoder->SetOutStreamSize(NULL)) } const UInt64 *Size = header.HasSize() ? &header.Size : NULL; - HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress); + HRESULT res = _lzmaDecoder->CodeResume(outStream, Size, progress); if (filteredMode) { @@ -157,60 +152,50 @@ res = res2; } - RINOK(res); + RINOK(res) if (header.HasSize()) - if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size) + if (_lzmaDecoder->GetOutputProcessedSize() != header.Size) return S_FALSE; return S_OK; } -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CHeader _header; +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) bool _lzma86; - CMyComPtr _stream; - CMyComPtr _seqStream; - bool _isArc; bool _needSeekToStart; bool _dataAfterEnd; bool _needMoreInput; + bool _unsupported; + bool _dataError; bool _packSize_Defined; bool _unpackSize_Defined; bool _numStreams_Defined; - bool _unsupported; - bool _dataError; - + CHeader _header; + CMyComPtr _stream; + CMyComPtr _seqStream; + UInt64 _packSize; UInt64 _unpackSize; UInt64 _numStreams; void GetMethod(NCOM::CPropVariant &prop); + unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); } public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - CHandler(bool lzma86) { _lzma86 = lzma86; } - - unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); } - }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -222,7 +207,7 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; @@ -230,12 +215,13 @@ prop = v; break; } + default: break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; @@ -244,7 +230,7 @@ static char * DictSizeToString(UInt32 val, char *s) { - for (unsigned i = 0; i <= 31; i++) + for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == val) return ::ConvertUInt32ToString(i, s); char c = 'b'; @@ -290,7 +276,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -298,6 +284,7 @@ case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break; case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; case kpidMethod: GetMethod(prop); break; + default: break; } prop.Detach(value); return S_OK; @@ -348,7 +335,7 @@ -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)) { Close(); @@ -356,7 +343,7 @@ const UInt32 kBufSize = 1 << 7; Byte buf[kBufSize]; size_t processedSize = kBufSize; - RINOK(ReadStream(inStream, buf, &processedSize)); + RINOK(ReadStream(inStream, buf, &processedSize)) if (processedSize < headerSize + 2) return S_FALSE; if (!_header.Parse(buf, _lzma86)) @@ -365,9 +352,9 @@ if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80 return S_FALSE; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, _packSize)) - SizeT srcLen = processedSize - headerSize; + SizeT srcLen = (SizeT)processedSize - headerSize; if (srcLen > 10 && _header.Size == 0 @@ -376,7 +363,6 @@ ) return S_FALSE; - CDecoder state; const UInt32 outLimit = 1 << 11; Byte outBuf[outLimit]; @@ -401,7 +387,7 @@ return S_OK; } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _isArc = true; @@ -409,41 +395,38 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; - _packSize_Defined = false; - _unpackSize_Defined = false; - _numStreams_Defined = false; - + _needSeekToStart = false; _dataAfterEnd = false; _needMoreInput = false; _unsupported = false; _dataError = false; - _packSize = 0; + _packSize_Defined = false; + _unpackSize_Defined = false; + _numStreams_Defined = false; - _needSeekToStart = false; + _packSize = 0; _stream.Release(); _seqStream.Release(); return S_OK; } -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) CMyComPtr Callback; public: UInt64 Offset; - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + void Init(IArchiveOpenCallback *callback) { Callback = callback; } }; -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { @@ -454,8 +437,8 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN @@ -465,41 +448,39 @@ return E_INVALIDARG; if (_packSize_Defined) - extractCallback->SetTotal(_packSize); + RINOK(extractCallback->SetTotal(_packSize)) - + Int32 opResult; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); if (_needSeekToStart) { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _needSeekToStart = true; CDecoder decoder; - HRESULT result = decoder.Create(_lzma86, _seqStream); - RINOK(result); + RINOK(decoder.Create(_lzma86, _seqStream)) bool firstItem = true; @@ -509,17 +490,19 @@ bool dataAfterEnd = false; + HRESULT hres = S_OK; + for (;;) { lps->InSize = packSize; lps->OutSize = unpackSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) const UInt32 kBufSize = 1 + 5 + 8; Byte buf[kBufSize]; const UInt32 headerSize = GetHeaderSize(); UInt32 processed; - RINOK(decoder.ReadInput(buf, headerSize, &processed)); + RINOK(decoder.ReadInput(buf, headerSize, &processed)) if (processed != headerSize) { if (processed != 0) @@ -536,32 +519,32 @@ numStreams++; firstItem = false; - result = decoder.Code(st, outStream, progress); + hres = decoder.Code(st, outStream, lps); packSize = decoder.GetInputProcessedSize(); - unpackSize = outStreamSpec->GetSize(); + unpackSize = outStream->GetSize(); - if (result == E_NOTIMPL) + if (hres == E_NOTIMPL) { _unsupported = true; - result = S_FALSE; + hres = S_FALSE; break; } - if (result == S_FALSE) + if (hres == S_FALSE) break; - RINOK(result); + RINOK(hres) } if (firstItem) { _isArc = false; - result = S_FALSE; + hres = S_FALSE; } - else if (result == S_OK || result == S_FALSE) + else if (hres == S_OK || hres == S_FALSE) { if (dataAfterEnd) _dataAfterEnd = true; - else if (decoder._lzmaDecoderSpec->NeedsMoreInput()) + else if (decoder._lzmaDecoder->NeedsMoreInput()) _needMoreInput = true; _packSize = packSize; @@ -573,7 +556,7 @@ _numStreams_Defined = true; } - Int32 opResult = NExtract::NOperationResult::kOK; + opResult = NExtract::NOperationResult::kOK; if (!_isArc) opResult = NExtract::NOperationResult::kIsNotArc; @@ -583,14 +566,15 @@ opResult = NExtract::NOperationResult::kUnsupportedMethod; else if (_dataAfterEnd) opResult = NExtract::NOperationResult::kDataAfterEnd; - else if (result == S_FALSE) + else if (hres == S_FALSE) opResult = NExtract::NOperationResult::kDataError; - else if (result == S_OK) + else if (hres == S_OK) opResult = NExtract::NOperationResult::kOK; else - return result; + return hres; - outStream.Release(); + // outStream.Release(); + } return extractCallback->SetOperationResult(opResult); COM_TRY_END @@ -602,7 +586,7 @@ REGISTER_ARC_I_CLS_NO_SIG( CHandler(false), - "lzma", "lzma", 0, 0xA, + "lzma", "lzma", NULL, 0xA, 0, NArcInfoFlags::kStartOpen | NArcInfoFlags::kKeepName, @@ -614,7 +598,7 @@ REGISTER_ARC_I_CLS_NO_SIG( CHandler(true), - "lzma86", "lzma86", 0, 0xB, + "lzma86", "lzma86", NULL, 0xB, 0, NArcInfoFlags::kKeepName, IsArc_Lzma86) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/MachoHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MachoHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/MachoHandler.cpp 2021-01-26 09:46:34.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MachoHandler.cpp 2023-03-27 09:00:00.000000000 +0000 @@ -95,6 +95,13 @@ , "GB_ZEROFILL" , "INTERPOSING" , "16BYTE_LITERALS" + , "DTRACE_DOF" + , "LAZY_DYLIB_SYMBOL_POINTERS" + , "THREAD_LOCAL_REGULAR" + , "THREAD_LOCAL_ZEROFILL" + , "THREAD_LOCAL_VARIABLES" + , "THREAD_LOCAL_VARIABLE_POINTERS" + , "THREAD_LOCAL_INIT_FUNCTION_POINTERS" }; enum EFileType @@ -157,7 +164,7 @@ }; -static const CUInt32PCharPair g_Flags[] = +static const CUInt32PCharPair g_SectFlags[] = { { 31, "PURE_INSTRUCTIONS" }, { 30, "NO_TOC" }, @@ -171,25 +178,54 @@ { 8, "LOC_RELOC" } }; + +// VM_PROT_* +static const char * const g_SegmentProt[] = +{ + "READ" + , "WRITE" + , "EXECUTE" + /* + , "NO_CHANGE" + , "COPY" + , "TRUSTED" + , "IS_MASK" + */ +}; + +// SG_* + +static const char * const g_SegmentFlags[] = +{ + "SG_HIGHVM" + , "SG_FVMLIB" + , "SG_NORELOC" + , "SG_PROTECTED_VERSION_1" + , "SG_READ_ONLY" +}; + static const unsigned kNameSize = 16; struct CSegment { char Name[kNameSize]; + UInt32 MaxProt; + UInt32 InitProt; + UInt32 Flags; }; struct CSection { char Name[kNameSize]; - char SegName[kNameSize]; + // char SegName[kNameSize]; UInt64 Va; UInt64 Pa; UInt64 VSize; UInt64 PSize; + UInt32 Align; UInt32 Flags; - int SegmentIndex; - + unsigned SegmentIndex; bool IsDummy; CSection(): IsDummy(false) {} @@ -198,11 +234,9 @@ }; -class CHandler: - public IInArchive, - public IArchiveAllowTail, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveAllowTail +) CMyComPtr _inStream; CObjectVector _segments; CObjectVector _sections; @@ -218,9 +252,6 @@ HRESULT Open2(ISequentialInStream *stream); public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(AllowTail)(Int32 allowTail); CHandler(): _allowTail(false) {} }; @@ -240,13 +271,14 @@ kpidPackSize, kpidCharacts, kpidOffset, - kpidVa + kpidVa, + kpidClusterSize // Align }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN CPropVariant prop; @@ -256,35 +288,28 @@ case kpidCpu: { AString s; - char temp[16]; - UInt32 cpu = _cpuType & ~(UInt32)CPU_ARCH_ABI64; + const UInt32 cpu = _cpuType & ~(UInt32)CPU_ARCH_ABI64; UInt32 flag64 = _cpuType & (UInt32)CPU_ARCH_ABI64; { - const char *n = NULL; - for (unsigned i = 0; i < ARRAY_SIZE(g_CpuPairs); i++) + s.Add_UInt32(cpu); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CpuPairs); i++) { const CUInt32PCharPair &pair = g_CpuPairs[i]; if (pair.Value == cpu || pair.Value == _cpuType) { if (pair.Value == _cpuType) flag64 = 0; - n = pair.Name; + s = pair.Name; break; } } - if (!n) - { - ConvertUInt32ToString(cpu, temp); - n = temp; - } - s = n; if (flag64 != 0) - s += " 64-bit"; + s.Add_OptSpaced("64-bit"); else if ((_cpuSubType & CPU_SUBTYPE_LIB64) && _cpuType != CPU_TYPE_AMD64) - s += " 64-bit-lib"; + s.Add_OptSpaced("64-bit-lib"); } - UInt32 t = _cpuSubType & ~(UInt32)CPU_SUBTYPE_LIB64; + const UInt32 t = _cpuSubType & ~(UInt32)CPU_SUBTYPE_LIB64; if (t != 0 && (t != CPU_SUBTYPE_I386_ALL || cpu != CPU_TYPE_386)) { const char *n = NULL; @@ -292,16 +317,14 @@ { if (t == CPU_SUBTYPE_POWERPC_970) n = "970"; - else if (t < ARRAY_SIZE(k_PowerPc_SubTypes)) + else if (t < Z7_ARRAY_SIZE(k_PowerPc_SubTypes)) n = k_PowerPc_SubTypes[t]; } - if (!n) - { - ConvertUInt32ToString(t, temp); - n = temp; - } s.Add_Space(); - s += n; + if (n) + s += n; + else + s.Add_UInt32(t); } prop = s; break; @@ -309,8 +332,8 @@ case kpidCharacts: { // TYPE_TO_PROP(g_FileTypes, _type, prop); break; - AString res (TypeToString(g_FileTypes, ARRAY_SIZE(g_FileTypes), _type)); - AString s (FlagsToString(g_ArcFlags, ARRAY_SIZE(g_ArcFlags), _flags)); + AString res (TypeToString(g_FileTypes, Z7_ARRAY_SIZE(g_FileTypes), _type)); + const AString s (FlagsToString(g_ArcFlags, Z7_ARRAY_SIZE(g_ArcFlags), _flags)); if (!s.IsEmpty()) { res.Add_Space(); @@ -343,16 +366,16 @@ COM_TRY_END } -static AString GetName(const char *name) +static void AddName(AString &s, const char *name) { - char res[kNameSize + 1]; - memcpy(res, name, kNameSize); - res[kNameSize] = 0; - return (AString)res; + char temp[kNameSize + 1]; + memcpy(temp, name, kNameSize); + temp[kNameSize] = 0; + s += temp; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN CPropVariant prop; @@ -361,29 +384,75 @@ { case kpidPath: { - AString s (GetName(_segments[item.SegmentIndex].Name)); + AString s; + AddName(s, _segments[item.SegmentIndex].Name); if (!item.IsDummy) - s += GetName(item.Name); + { + // CSection::SegName and CSegment::Name are same in real cases. + // AddName(s, item.SegName); + AddName(s, item.Name); + } prop = MultiByteToUnicodeString(s); break; } case kpidSize: /* prop = (UInt64)item.VSize; break; */ case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; case kpidCharacts: - if (!item.IsDummy) + { + AString res; { - AString res (TypeToString(g_SectTypes, ARRAY_SIZE(g_SectTypes), item.Flags & SECT_TYPE_MASK)); - AString s (FlagsToString(g_Flags, ARRAY_SIZE(g_Flags), item.Flags & SECT_ATTR_MASK)); - if (!s.IsEmpty()) + if (!item.IsDummy) { - res.Add_Space(); - res += s; + { + const AString s (TypeToString(g_SectTypes, Z7_ARRAY_SIZE(g_SectTypes), item.Flags & SECT_TYPE_MASK)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("sect_type:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SectFlags, Z7_ARRAY_SIZE(g_SectFlags), item.Flags & SECT_ATTR_MASK)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("sect_flags:"); + res.Add_OptSpaced(s); + } + } + } + const CSegment &seg = _segments[item.SegmentIndex]; + { + const AString s (FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), seg.Flags)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("seg_flags:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SegmentProt, Z7_ARRAY_SIZE(g_SegmentProt), seg.MaxProt)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("max_prot:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SegmentProt, Z7_ARRAY_SIZE(g_SegmentProt), seg.InitProt)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("init_prot:"); + res.Add_OptSpaced(s); + } } - prop = res; } + if (!res.IsEmpty()) + prop = res; break; + } case kpidOffset: prop = item.Pa; break; case kpidVa: prop = item.Va; break; + case kpidClusterSize: prop = (UInt32)1 << item.Align; break; } prop.Detach(value); return S_OK; @@ -396,7 +465,7 @@ const UInt32 kStartHeaderSize = 7 * 4; Byte header[kStartHeaderSize]; - RINOK(ReadStream_FALSE(stream, header, kStartHeaderSize)); + RINOK(ReadStream_FALSE(stream, header, kStartHeaderSize)) bool be, mode64; switch (GetUi32(header)) { @@ -410,8 +479,8 @@ _mode64 = mode64; _be = be; - UInt32 numCommands = Get32(header + 0x10, be); - UInt32 commandsSize = Get32(header + 0x14, be); + const UInt32 numCommands = Get32(header + 0x10, be); + const UInt32 commandsSize = Get32(header + 0x14, be); if (numCommands == 0) return S_FALSE; @@ -443,7 +512,7 @@ _headersSize = startHeaderSize + commandsSize; _totalSize = _headersSize; CByteArr buffer(_headersSize); - RINOK(ReadStream_FALSE(stream, buffer + kStartHeaderSize, _headersSize - kStartHeaderSize)); + RINOK(ReadStream_FALSE(stream, buffer + kStartHeaderSize, _headersSize - kStartHeaderSize)) const Byte *buf = buffer + startHeaderSize; size_t size = _headersSize - startHeaderSize; for (UInt32 cmdIndex = 0; cmdIndex < numCommands; cmdIndex++) @@ -489,6 +558,9 @@ } CSegment seg; + seg.MaxProt = Get32(buf + offs - 16, be); + seg.InitProt = Get32(buf + offs - 12, be); + seg.Flags = Get32(buf + offs - 4, be); memcpy(seg.Name, buf + 8, kNameSize); _segments.Add(seg); @@ -505,11 +577,12 @@ sect.PSize = phSize; sect.VSize = vmSize; sect.Pa = phAddr; + sect.Align = 0; sect.Flags = 0; } else do { - UInt32 headSize = (cmd == CMD_SEGMENT_64) ? 0x50 : 0x44; + const UInt32 headSize = (cmd == CMD_SEGMENT_64) ? 0x50 : 0x44; const Byte *p = buf + offs; if (cmdSize - offs < headSize) break; @@ -528,13 +601,16 @@ f32Offset = 0x28; } sect.Pa = Get32(p + f32Offset, be); - sect.Flags = Get32(p + f32Offset + 10, be); - if (sect.Flags == SECT_ATTR_ZEROFILL) + sect.Align = Get32(p + f32Offset + 4, be); + // sect.reloff = Get32(p + f32Offset + 8, be); + // sect.nreloc = Get32(p + f32Offset + 12, be); + sect.Flags = Get32(p + f32Offset + 16, be); + if ((sect.Flags & SECT_TYPE_MASK) == SECT_ATTR_ZEROFILL) sect.PSize = 0; else sect.PSize = sect.VSize; memcpy(sect.Name, p, kNameSize); - memcpy(sect.SegName, p + kNameSize, kNameSize); + // memcpy(sect.SegName, p + kNameSize, kNameSize); sect.SegmentIndex = _segments.Size() - 1; offs += headSize; } @@ -553,17 +629,17 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - RINOK(Open2(inStream)); + RINOK(Open2(inStream)) if (!_allowTail) { UInt64 fileSize; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) if (fileSize > _totalSize) return S_FALSE; } @@ -572,7 +648,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _inStream.Release(); @@ -581,17 +657,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _sections.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _sections.Size(); if (numItems == 0) @@ -619,33 +695,33 @@ for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? + RINOK(lps->SetCur()) + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CSection &item = _sections[index]; currentItemSize = item.GetPackSize(); CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_inStream, item.Pa)) streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) outStream.Release(); RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) { _allowTail = IntToBool(allowTail); return S_OK; @@ -658,7 +734,7 @@ 4, 0xFE, 0xED, 0xFA, 0xCF }; REGISTER_ARC_I( - "MachO", "macho", 0, 0xDF, + "MachO", "macho", NULL, 0xDF, k_Signature, 0, NArcInfoFlags::kMultiSignature | diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/MbrHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MbrHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/MbrHandler.cpp 2021-01-26 09:47:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MbrHandler.cpp 2023-06-26 16:00:00.000000000 +0000 @@ -30,6 +30,11 @@ using namespace NWindows; namespace NArchive { + +namespace NFat { +API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size); +} + namespace NMbr { struct CChs @@ -54,7 +59,7 @@ // Chs in some MBRs contains only low bits of "Cyl number". So we disable check. /* -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _t_ = (x); if (_t_ != 0) return _t_; } static int CompareChs(const CChs &c1, const CChs &c2) { RINOZ(MyCompare(c1.GetCyl(), c2.GetCyl())); @@ -67,9 +72,9 @@ { AString s; s.Add_UInt32(GetCyl()); - s += '-'; + s.Add_Minus(); s.Add_UInt32(Head); - s += '-'; + s.Add_Minus(); s.Add_UInt32(GetSector()); prop = s; } @@ -89,8 +94,8 @@ bool IsExtended() const { return Type == 5 || Type == 0xF; } UInt32 GetLimit() const { return Lba + NumBlocks; } // bool IsActive() const { return Status == 0x80; } - UInt64 GetPos() const { return (UInt64)Lba * 512; } - UInt64 GetSize() const { return (UInt64)NumBlocks * 512; } + UInt64 GetPos(unsigned sectorSizeLog) const { return (UInt64)Lba << sectorSizeLog; } + UInt64 GetSize(unsigned sectorSizeLog) const { return (UInt64)NumBlocks << sectorSizeLog; } bool CheckLbaLimits() const { return (UInt32)0xFFFFFFFF - Lba >= NumBlocks; } bool Parse(const Byte *p) @@ -132,17 +137,25 @@ #define kFat "fat" +/* +if we use "format" command in Windows 10 for existing partition: + - if we format to ExFAT, it sets type=7 + - if we format to UDF, it doesn't change type from previous value. +*/ + +static const unsigned kType_Windows_NTFS = 7; + static const CPartType kPartTypes[] = { { 0x01, kFat, "FAT12" }, { 0x04, kFat, "FAT16 DOS 3.0+" }, - { 0x05, 0, "Extended" }, + { 0x05, NULL, "Extended" }, { 0x06, kFat, "FAT16 DOS 3.31+" }, { 0x07, "ntfs", "NTFS" }, { 0x0B, kFat, "FAT32" }, { 0x0C, kFat, "FAT32-LBA" }, { 0x0E, kFat, "FAT16-LBA" }, - { 0x0F, 0, "Extended-LBA" }, + { 0x0F, NULL, "Extended-LBA" }, { 0x11, kFat, "FAT12-Hidden" }, { 0x14, kFat, "FAT16-Hidden < 32 MB" }, { 0x16, kFat, "FAT16-Hidden >= 32 MB" }, @@ -150,23 +163,23 @@ { 0x1C, kFat, "FAT32-LBA-Hidden" }, { 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" }, { 0x27, "ntfs", "NTFS-WinRE" }, - { 0x82, 0, "Solaris x86 / Linux swap" }, - { 0x83, 0, "Linux" }, + { 0x82, NULL, "Solaris x86 / Linux swap" }, + { 0x83, NULL, "Linux" }, { 0x8E, "lvm", "Linux LVM" }, - { 0xA5, 0, "BSD slice" }, - { 0xBE, 0, "Solaris 8 boot" }, - { 0xBF, 0, "New Solaris x86" }, - { 0xC2, 0, "Linux-Hidden" }, - { 0xC3, 0, "Linux swap-Hidden" }, - { 0xEE, 0, "GPT" }, - { 0xEE, 0, "EFI" } + { 0xA5, NULL, "BSD slice" }, + { 0xBE, NULL, "Solaris 8 boot" }, + { 0xBF, NULL, "New Solaris x86" }, + { 0xC2, NULL, "Linux-Hidden" }, + { 0xC3, NULL, "Linux swap-Hidden" }, + { 0xEE, NULL, "GPT" }, + { 0xEE, NULL, "EFI" } }; static int FindPartType(UInt32 type) { - for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPartTypes); i++) if (kPartTypes[i].Id == type) - return i; + return (int)i; return -1; } @@ -174,29 +187,52 @@ { bool IsReal; bool IsPrim; + bool WasParsed; + const char *FileSystem; UInt64 Size; CPartition Part; + + CItem(): + WasParsed(false), + FileSystem(NULL) + {} }; -class CHandler: public CHandlerCont + +Z7_class_CHandler_final: public CHandlerCont { + Z7_IFACE_COM7_IMP(IInArchive_Cont) + CObjectVector _items; UInt64 _totalSize; CByteBuffer _buffer; - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const + UInt32 _signature; + unsigned _sectorSizeLog; + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override Z7_final { const CItem &item = _items[index]; - pos = item.Part.GetPos(); + pos = item.Part.GetPos(_sectorSizeLog); size = item.Size; return NExtract::NOperationResult::kOK; } HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level); -public: - INTERFACE_IInArchive_Cont(;) }; +/* +static bool IsEmptyBuffer(const Byte *data, size_t size) +{ + for (unsigned i = 0; i < size; i++) + if (data[i] != 0) + return false; + return true; +} +*/ + +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize); + HRESULT CHandler::ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level) { if (level >= 128 || _items.Size() >= 128) @@ -205,24 +241,65 @@ const unsigned kNumHeaderParts = 4; CPartition parts[kNumHeaderParts]; + if (level == 0) + _sectorSizeLog = 9; + const UInt32 kSectorSize = (UInt32)1 << _sectorSizeLog; + UInt32 bufSize = kSectorSize; + if (level == 0 && _totalSize >= (1 << 12)) + bufSize = (1 << 12); + _buffer.Alloc(bufSize); { - const UInt32 kSectorSize = 512; - _buffer.Alloc(kSectorSize); Byte *buf = _buffer; - UInt64 newPos = (UInt64)lba << 9; - if (newPos + 512 > _totalSize) + const UInt64 newPos = (UInt64)lba << _sectorSizeLog; + if (newPos + bufSize > _totalSize) return S_FALSE; - RINOK(stream->Seek(newPos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - + RINOK(InStream_SeekSet(stream, newPos)) + RINOK(ReadStream_FALSE(stream, buf, bufSize)) if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) return S_FALSE; - + if (level == 0) + _signature = GetUi32(buf + 0x1B8); for (unsigned i = 0; i < kNumHeaderParts; i++) if (!parts[i].Parse(buf + 0x1BE + 16 * i)) return S_FALSE; } + // 23.02: now we try to detect 4kn format (4 KB sectors case) + if (level == 0) + // if (_totalSize >= (1 << 28)) // we don't expect small images with 4 KB sectors + if (bufSize >= (1 << 12)) + { + UInt32 lastLim = 0; + UInt32 firstLba = 0; + UInt32 numBlocks = 0; // in first partition + for (unsigned i = 0; i < kNumHeaderParts; i++) + { + const CPartition &part = parts[i]; + if (part.IsEmpty()) + continue; + if (firstLba == 0 && part.NumBlocks != 0) + { + firstLba = part.Lba; + numBlocks = part.NumBlocks; + } + const UInt32 newLim = part.GetLimit(); + if (newLim < lastLim) + return S_FALSE; + lastLim = newLim; + } + if (lastLim != 0) + { + const UInt64 lim12 = (UInt64)lastLim << 12; + if (lim12 <= _totalSize + // && _totalSize - lim12 < (1 << 28) // we can try to exclude false positive cases + ) + // if (IsEmptyBuffer(&_buffer[(1 << 9)], (1 << 12) - (1 << 9))) + if (InStream_SeekSet(stream, (UInt64)firstLba << 12) == S_OK) + if (GetFileSystem(stream, (UInt64)numBlocks << 12)) + _sectorSizeLog = 12; + } + } + PRF(printf("\n# %8X", lba)); UInt32 limLba = lba + 1; @@ -249,7 +326,7 @@ newLba = baseLba + part.Lba; if (newLba < limLba) return S_FALSE; - HRESULT res = ReadTables(stream, level < 1 ? newLba : baseLba, newLba, level + 1); + const HRESULT res = ReadTables(stream, level < 1 ? newLba : baseLba, newLba, level + 1); if (res != S_FALSE && res != S_OK) return res; } @@ -271,8 +348,8 @@ else { const CItem &back = _items.Back(); - UInt32 backLimit = back.Part.GetLimit(); - UInt32 partLimit = part.GetLimit(); + const UInt32 backLimit = back.Part.GetLimit(); + const UInt32 partLimit = part.GetLimit(); if (backLimit < partLimit) { n.IsReal = false; @@ -286,39 +363,131 @@ if (n.Part.GetLimit() < limLba) return S_FALSE; limLba = n.Part.GetLimit(); - n.Size = n.Part.GetSize(); + n.Size = n.Part.GetSize(_sectorSizeLog); _items.Add(n); } } return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, + +static const Byte k_Ntfs_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; + +static bool Is_Ntfs(const Byte *p) +{ + if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + return false; + switch (p[0]) + { + case 0xE9: /* codeOffset = 3 + (Int16)Get16(p + 1); */ break; + case 0xEB: if (p[2] != 0x90) return false; /* codeOffset = 2 + (int)(signed char)p[1]; */ break; + default: return false; + } + return memcmp(p + 3, k_Ntfs_Signature, Z7_ARRAY_SIZE(k_Ntfs_Signature)) == 0; +} + +static const Byte k_ExFat_Signature[] = { 'E', 'X', 'F', 'A', 'T', ' ', ' ', ' ' }; + +static bool Is_ExFat(const Byte *p) +{ + if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + return false; + if (p[0] != 0xEB || p[1] != 0x76 || p[2] != 0x90) + return false; + return memcmp(p + 3, k_ExFat_Signature, Z7_ARRAY_SIZE(k_ExFat_Signature)) == 0; +} + +static bool AllAreZeros(const Byte *p, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p[i] != 0) + return false; + return true; +} + +static const UInt32 k_Udf_StartPos = 0x8000; +static const Byte k_Udf_Signature[] = { 0, 'B', 'E', 'A', '0', '1', 1, 0 }; + +static bool Is_Udf(const Byte *p) +{ + return memcmp(p + k_Udf_StartPos, k_Udf_Signature, sizeof(k_Udf_Signature)) == 0; +} + + +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize) +{ + const size_t kHeaderSize = 1 << 9; + if (partitionSize >= kHeaderSize) + { + Byte buf[kHeaderSize]; + if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK) + { + // NTFS is expected default filesystem for (Type == 7) + if (Is_Ntfs(buf)) + return "NTFS"; + if (Is_ExFat(buf)) + return "exFAT"; + if (NFat::IsArc_Fat(buf, kHeaderSize)) + return "FAT"; + const size_t kHeaderSize2 = k_Udf_StartPos + (1 << 9); + if (partitionSize >= kHeaderSize2) + { + if (AllAreZeros(buf, kHeaderSize)) + { + CByteBuffer buffer(kHeaderSize2); + // memcpy(buffer, buf, kHeaderSize); + if (ReadStream_FAIL(stream, buffer + kHeaderSize, kHeaderSize2 - kHeaderSize) == S_OK) + if (Is_Udf(buffer)) + return "UDF"; + } + } + } + } + return NULL; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - RINOK(stream->Seek(0, STREAM_SEEK_END, &_totalSize)); - RINOK(ReadTables(stream, 0, 0, 0)); + RINOK(InStream_GetSize_SeekToEnd(stream, _totalSize)) + RINOK(ReadTables(stream, 0, 0, 0)) if (_items.IsEmpty()) return S_FALSE; - UInt32 lbaLimit = _items.Back().Part.GetLimit(); - UInt64 lim = (UInt64)lbaLimit << 9; - if (lim < _totalSize) { - CItem n; - n.Part.Lba = lbaLimit; - n.Size = _totalSize - lim; - n.IsReal = false; - _items.Add(n); + const UInt32 lbaLimit = _items.Back().Part.GetLimit(); + const UInt64 lim = (UInt64)lbaLimit << _sectorSizeLog; + if (lim < _totalSize) + { + CItem n; + n.Part.Lba = lbaLimit; + n.Size = _totalSize - lim; + n.IsReal = false; + _items.Add(n); + } + } + + FOR_VECTOR (i, _items) + { + CItem &item = _items[i]; + if (item.Part.Type != kType_Windows_NTFS) + continue; + if (InStream_SeekSet(stream, item.Part.GetPos(_sectorSizeLog)) != S_OK) + continue; + item.FileSystem = GetFileSystem(stream, item.Size); + item.WasParsed = true; } + _stream = stream; return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() + +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _items.Clear(); @@ -326,6 +495,7 @@ return S_OK; } + enum { kpidPrimary = kpidUserDefined, @@ -344,10 +514,17 @@ { "End CHS", kpidEndChs, VT_BSTR} }; +static const Byte kArcProps[] = +{ + kpidSectorSize, + kpidId +}; + IMP_IInArchive_Props_WITH_NAME -IMP_IInArchive_ArcProps_NO_Table +IMP_IInArchive_ArcProps + -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -363,25 +540,27 @@ mainIndex = -1; break; } - mainIndex = i; + mainIndex = (int)i; } if (mainIndex >= 0) - prop = (UInt32)mainIndex; + prop = (UInt32)(Int32)mainIndex; break; } case kpidPhySize: prop = _totalSize; break; + case kpidSectorSize: prop = (UInt32)((UInt32)1 << _sectorSizeLog); break; + case kpidId: prop = _signature; break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -396,11 +575,21 @@ s.Add_UInt32(index); if (item.IsReal) { - s += '.'; + s.Add_Dot(); const char *ext = NULL; - int typeIndex = FindPartType(part.Type); - if (typeIndex >= 0) - ext = kPartTypes[(unsigned)typeIndex].Ext; + if (item.FileSystem) + { + ext = ""; + AString fs (item.FileSystem); + fs.MakeLower_Ascii(); + s += fs; + } + else if (!item.WasParsed) + { + const int typeIndex = FindPartType(part.Type); + if (typeIndex >= 0) + ext = kPartTypes[(unsigned)typeIndex].Ext; + } if (!ext) ext = "img"; s += ext; @@ -414,15 +603,24 @@ char s[32]; ConvertUInt32ToString(part.Type, s); const char *res = s; - int typeIndex = FindPartType(part.Type); - if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Name) - res = kPartTypes[(unsigned)typeIndex].Name; + if (item.FileSystem) + { + // strcat(s, "-"); + // strcpy(s, item.FileSystem); + res = item.FileSystem; + } + else if (!item.WasParsed) + { + const int typeIndex = FindPartType(part.Type); + if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Name) + res = kPartTypes[(unsigned)typeIndex].Name; + } prop = res; } break; case kpidSize: case kpidPackSize: prop = item.Size; break; - case kpidOffset: prop = part.GetPos(); break; + case kpidOffset: prop = part.GetPos(_sectorSizeLog); break; case kpidPrimary: if (item.IsReal) prop = item.IsPrim; break; case kpidBegChs: if (item.IsReal) part.BeginChs.ToString(prop); break; case kpidEndChs: if (item.IsReal) part.EndChs.ToString(prop); break; @@ -437,7 +635,7 @@ // 2, { 0x55, 0x1FF }, REGISTER_ARC_I_NO_SIG( - "MBR", "mbr", 0, 0xDB, + "MBR", "mbr", NULL, 0xDB, 0, NArcInfoFlags::kPureStartOpen, NULL) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/MslzHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MslzHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/MslzHandler.cpp 2017-02-02 19:41:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MslzHandler.cpp 2024-01-24 17:00:00.000000000 +0000 @@ -21,11 +21,9 @@ static const UInt32 kUnpackSizeMax = 0xFFFFFFE0; -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) CMyComPtr _inStream; CMyComPtr _seqStream; @@ -43,10 +41,6 @@ UString _name; void ParseName(Byte replaceByte, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); }; static const Byte kProps[] = @@ -59,13 +53,13 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -77,10 +71,11 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; prop = v; + break; } } prop.Detach(value); @@ -89,7 +84,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -125,8 +120,7 @@ { if (!callback) return; - CMyComPtr volumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); + Z7_DECL_CMyComPtr_QI_FROM(IArchiveOpenVolumeCallback, volumeCallback, callback) if (!volumeCallback) return; @@ -146,37 +140,37 @@ { if (s.Len() < 3 || s[s.Len() - 3] != '.') return; - for (unsigned i = 0; i < ARRAY_SIZE(g_Exts); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exts); i++) { const char *ext = g_Exts[i]; if (s[s.Len() - 2] == (Byte)ext[0] && s[s.Len() - 1] == (Byte)ext[1]) { - replaceByte = ext[2]; + replaceByte = (Byte)ext[2]; break; } } } if (replaceByte >= 0x20 && replaceByte < 0x80) - _name += (char)replaceByte; + _name.Add_Char((char)replaceByte); } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { Close(); _needSeekToStart = true; Byte buffer[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize)) if (memcmp(buffer, kSignature, kSignatureSize) != 0) return S_FALSE; _unpackSize = GetUi32(buffer + 10); if (_unpackSize > kUnpackSizeMax) return S_FALSE; - RINOK(stream->Seek(0, STREAM_SEEK_END, &_originalFileSize)); + RINOK(InStream_GetSize_SeekToEnd(stream, _originalFileSize)) _packSize = _originalFileSize; ParseName(buffer[kSignatureSize], callback); @@ -190,7 +184,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _originalFileSize = 0; _packSize = 0; @@ -276,11 +270,11 @@ } if (outStream) - RINOK(WriteStream(outStream, buf, dest & kMask)); + RINOK(WriteStream(outStream, buf, dest & kMask)) return S_OK; } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { COM_TRY_BEGIN Close(); @@ -290,8 +284,8 @@ COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -299,38 +293,37 @@ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - // extractCallback->SetTotal(_unpackSize); - + // RINOK(extractCallback->SetTotal(_unpackSize)) + Int32 opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); if (_needSeekToStart) { if (!_inStream) return E_FAIL; - RINOK(_inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_inStream)) } else _needSeekToStart = true; - Int32 opRes = NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; bool isArc = false; bool needMoreInput = false; @@ -351,7 +344,7 @@ unpackSize = GetUi32(buffer + 10); if (unpackSize <= kUnpackSizeMax) { - HRESULT result = MslzDec(s, outStream, unpackSize, needMoreInput, progress); + const HRESULT result = MslzDec(s, outStream, unpackSize, needMoreInput, lps); if (result == S_OK) opRes = NExtract::NOperationResult::kOK; else if (result != S_FALSE) @@ -381,14 +374,13 @@ opRes = NExtract::NOperationResult::kUnexpectedEnd; else if (_dataAfterEnd) opRes = NExtract::NOperationResult::kDataAfterEnd; - - outStream.Release(); + } return extractCallback->SetOperationResult(opRes); COM_TRY_END } REGISTER_ARC_I( - "MsLZ", "mslz", 0, 0xD5, + "MsLZ", "mslz", NULL, 0xD5, kSignature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/MubHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MubHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/MubHandler.cpp 2021-01-22 19:51:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/MubHandler.cpp 2023-03-15 10:00:00.000000000 +0000 @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "../../../C/CpuArch.h" +#include "../../../C/SwapBytes.h" #include "../../Common/ComTry.h" #include "../../Common/IntToString.h" @@ -15,15 +16,13 @@ #include "HandlerCont.h" -static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } - using namespace NWindows; using namespace NCOM; namespace NArchive { namespace NMub { -#define MACH_CPU_ARCH_ABI64 (1 << 24) +#define MACH_CPU_ARCH_ABI64 ((UInt32)1 << 24) #define MACH_CPU_TYPE_386 7 #define MACH_CPU_TYPE_ARM 12 #define MACH_CPU_TYPE_SPARC 14 @@ -43,13 +42,15 @@ UInt32 SubType; UInt32 Offset; UInt32 Size; - // UInt32 Align; + UInt32 Align; }; -static const UInt32 kNumFilesMax = 10; +static const UInt32 kNumFilesMax = 6; -class CHandler: public CHandlerCont +Z7_class_CHandler_final: public CHandlerCont { + Z7_IFACE_COM7_IMP(IInArchive_Cont) + // UInt64 _startPos; UInt64 _phySize; UInt32 _numItems; @@ -58,16 +59,13 @@ HRESULT Open2(IInStream *stream); - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override { const CItem &item = _items[index]; pos = item.Offset; size = item.Size; return NExtract::NOperationResult::kOK; } - -public: - INTERFACE_IInArchive_Cont(;) }; static const Byte kArcProps[] = @@ -77,13 +75,16 @@ static const Byte kProps[] = { - kpidSize + kpidPath, + kpidSize, + kpidOffset, + kpidClusterSize // Align }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { PropVariant_Clear(value); switch (propID) @@ -94,7 +95,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { PropVariant_Clear(value); const CItem &item = _items[index]; @@ -103,7 +104,7 @@ case kpidExtension: { char temp[32]; - const char *ext = 0; + const char *ext = NULL; switch (item.Type) { case MACH_CPU_TYPE_386: ext = "x86"; break; @@ -117,13 +118,13 @@ temp[0] = 'c'; temp[1] = 'p'; temp[2] = 'u'; - ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3); + char *p = ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3); if (item.Type & MACH_CPU_ARCH_ABI64) - MyStringCopy(temp + MyStringLen(temp), "_64"); + MyStringCopy(p, "_64"); break; } if (ext) - strcpy(temp, ext); + MyStringCopy(temp, ext); if (item.SubType != 0) if ((item.Type != MACH_CPU_TYPE_386 && item.Type != MACH_CPU_TYPE_AMD64) @@ -140,32 +141,45 @@ case kpidPackSize: PropVarEm_Set_UInt64(value, item.Size); break; + case kpidOffset: + PropVarEm_Set_UInt64(value, item.Offset); + break; + case kpidClusterSize: + PropVarEm_Set_UInt32(value, (UInt32)1 << item.Align); + break; } return S_OK; } HRESULT CHandler::Open2(IInStream *stream) { - // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); + // RINOK(InStream_GetPos(stream, _startPos)); - const UInt32 kHeaderSize = 8; - const UInt32 kRecordSize = 5 * 4; + const UInt32 kHeaderSize = 2; + const UInt32 kRecordSize = 5; const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize; - Byte buf[kBufSize]; - size_t processed = kBufSize; - RINOK(ReadStream(stream, buf, &processed)); + UInt32 buf[kBufSize]; + size_t processed = kBufSize * 4; + RINOK(ReadStream(stream, buf, &processed)) + processed >>= 2; if (processed < kHeaderSize) return S_FALSE; bool be; - switch (GetBe32(buf)) + switch (buf[0]) { - case 0xCAFEBABE: be = true; break; - case 0xB9FAF10E: be = false; break; + case Z7_CONV_BE_TO_NATIVE_CONST32(0xCAFEBABE): be = true; break; + case Z7_CONV_BE_TO_NATIVE_CONST32(0xB9FAF10E): be = false; break; default: return S_FALSE; } _bigEndian = be; - UInt32 num = Get32(buf + 4, be); + if ( + #if defined(MY_CPU_BE) + ! + #endif + be) + z7_SwapBytes4(&buf[1], processed - 1); + const UInt32 num = buf[1]; if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize) return S_FALSE; if (num == 0) @@ -174,13 +188,14 @@ for (UInt32 i = 0; i < num; i++) { - const Byte *p = buf + kHeaderSize + i * kRecordSize; + const UInt32 *p = buf + kHeaderSize + i * kRecordSize; CItem &sb = _items[i]; - sb.Type = Get32(p, be); - sb.SubType = Get32(p + 4, be); - sb.Offset = Get32(p + 8, be); - sb.Size = Get32(p + 12, be); - UInt32 align = Get32(p + 16, be); + sb.Type = p[0]; + sb.SubType = p[1]; + sb.Offset = p[2]; + sb.Size = p[3]; + const UInt32 align = p[4]; + sb.Align = align; if (align > 31) return S_FALSE; if (sb.Offset < kHeaderSize + num * kRecordSize) @@ -189,7 +204,7 @@ (sb.SubType & ~MACH_CPU_SUBTYPE_LIB64) >= 0x100) return S_FALSE; - UInt64 endPos = (UInt64)sb.Offset + sb.Size; + const UInt64 endPos = (UInt64)sb.Offset + sb.Size; if (endPosMax < endPos) endPosMax = endPos; } @@ -198,9 +213,9 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); @@ -215,7 +230,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _stream.Release(); _numItems = 0; @@ -223,7 +238,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _numItems; return S_OK; @@ -236,7 +251,7 @@ 4, 0xB9, 0xFA, 0xF1, 0x0E }; REGISTER_ARC_I( - "Mub", "mub", 0, 0xE2, + "Mub", "mub", NULL, 0xE2, k_Signature, 0, NArcInfoFlags::kMultiSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.cpp 2017-04-18 09:42:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.cpp 2023-03-22 15:00:00.000000000 +0000 @@ -40,7 +40,7 @@ if (!_codecInStream) { - switch (Method) + switch ((int)Method) { // case NMethodType::kCopy: return E_NOTIMPL; case NMethodType::kDeflate: @@ -65,7 +65,7 @@ if (FilterFlag) { Byte flag; - RINOK(ReadStream_FALSE(inStream, &flag, 1)); + RINOK(ReadStream_FALSE(inStream, &flag, 1)) if (flag > 1) return E_NOTIMPL; useFilter = (flag != 0); @@ -79,9 +79,9 @@ { _filter = new CFilterCoder(false); _filterInStream = _filter; - _filter->Filter = new NCompress::NBcj::CCoder(false); + _filter->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec); } - RINOK(_filter->SetInStream(_codecInStream)); + RINOK(_filter->SetInStream(_codecInStream)) _decoderInStream = _filterInStream; } @@ -89,8 +89,8 @@ { const unsigned kPropsSize = LZMA_PROPS_SIZE; Byte props[kPropsSize]; - RINOK(ReadStream_FALSE(inStream, props, kPropsSize)); - RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize)); + RINOK(ReadStream_FALSE(inStream, props, kPropsSize)) + RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize)) } { @@ -98,7 +98,7 @@ _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; - RINOK(setInStream->SetInStream(inStream)); + RINOK(setInStream->SetInStream(inStream)) } { @@ -106,12 +106,12 @@ _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); if (!setOutStreamSize) return E_NOTIMPL; - RINOK(setOutStreamSize->SetOutStreamSize(NULL)); + RINOK(setOutStreamSize->SetOutStreamSize(NULL)) } if (useFilter) { - RINOK(_filter->SetOutStreamSize(NULL)); + RINOK(_filter->SetOutStreamSize(NULL)) } return S_OK; @@ -130,14 +130,14 @@ while (StreamPos < pos) { size_t size = (size_t)MyMin(pos - StreamPos, (UInt64)Buffer.Size()); - RINOK(Read(Buffer, &size)); + RINOK(Read(Buffer, &size)) if (size == 0) return S_FALSE; StreamPos += size; offset += size; const UInt64 inSize = GetInputProcessedSize() - inSizeStart; - RINOK(progress->SetRatioInfo(&inSize, &offset)); + RINOK(progress->SetRatioInfo(&inSize, &offset)) } return S_OK; } @@ -156,7 +156,7 @@ { Byte temp[4]; size_t processedSize = 4; - RINOK(Read(temp, &processedSize)); + RINOK(Read(temp, &processedSize)) StreamPos += processedSize; if (processedSize != 4) return S_FALSE; @@ -171,7 +171,7 @@ Byte temp[4]; { size_t processedSize = 4; - RINOK(ReadStream(InputStream, temp, &processedSize)); + RINOK(ReadStream(InputStream, temp, &processedSize)) StreamPos += processedSize; if (processedSize != 4) return S_FALSE; @@ -192,7 +192,7 @@ { UInt32 curSize = (UInt32)MyMin((size_t)size, Buffer.Size()); UInt32 processedSize; - RINOK(InputStream->Read(Buffer, curSize, &processedSize)); + RINOK(InputStream->Read(Buffer, curSize, &processedSize)) if (processedSize == 0) return S_FALSE; if (outBuf) @@ -202,8 +202,8 @@ StreamPos += processedSize; unpackSizeRes += processedSize; if (realOutStream) - RINOK(WriteStream(realOutStream, Buffer, processedSize)); - RINOK(progress->SetRatioInfo(&offset, &offset)); + RINOK(WriteStream(realOutStream, Buffer, processedSize)) + RINOK(progress->SetRatioInfo(&offset, &offset)) } return S_OK; @@ -217,7 +217,7 @@ limitedStreamSpec->Init(size); { bool useFilter; - RINOK(Init(limitedStream, useFilter)); + RINOK(Init(limitedStream, useFilter)) } } @@ -244,7 +244,7 @@ size_t size = Buffer.Size(); if (size > rem) size = rem; - RINOK(Read(Buffer, &size)); + RINOK(Read(Buffer, &size)) if (size == 0) { if (unpackSizeDefined) @@ -277,7 +277,7 @@ unpackSizeRes += (UInt32)size; UInt64 outSize = offset; - RINOK(progress->SetRatioInfo(&inSize, &outSize)); + RINOK(progress->SetRatioInfo(&inSize, &outSize)) if (realOutStream) { res = WriteStream(realOutStream, Buffer, size); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.h 2017-04-18 09:32:06.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisDecode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // NsisDecode.h -#ifndef __NSIS_DECODE_H -#define __NSIS_DECODE_H +#ifndef ZIP7_INC_NSIS_DECODE_H +#define ZIP7_INC_NSIS_DECODE_H #include "../../../Common/MyBuffer.h" @@ -82,7 +82,7 @@ HRESULT Read(void *data, size_t *processedSize) { - return ReadStream(_decoderInStream, data, processedSize);; + return ReadStream(_decoderInStream, data, processedSize); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.cpp 2021-03-16 19:46:04.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -61,22 +61,19 @@ IMP_IInArchive_ArcProps -static AString UInt32ToString(UInt32 val) +static void AddDictProp(AString &s, UInt32 val) { - char s[16]; - ConvertUInt32ToString(val, s); - return (AString)s; -} - -static AString GetStringForSizeValue(UInt32 val) -{ - for (int i = 31; i >= 0; i--) + for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == val) - return UInt32ToString(i); + { + s.Add_UInt32(i); + return; + } char c = 'b'; if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } - return UInt32ToString(val) + c; + s.Add_UInt32(val); + s.Add_Char(c); } static AString GetMethod(bool useFilter, NMethodType::EEnum method, UInt32 dict) @@ -87,11 +84,11 @@ s += kBcjMethod; s.Add_Space(); } - s += ((unsigned)method < ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod; + s += ((unsigned)method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod; if (method == NMethodType::kLZMA) { - s += ':'; - s += GetStringForSizeValue(dict); + s.Add_Colon(); + AddDictProp(s, dict); } return s; } @@ -105,17 +102,17 @@ s += kBcjMethod; s.Add_Space(); } - s += (method < ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod; + s += (method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod; if (method == NMethodType::kLZMA) { - s += ':'; + s.Add_Colon(); s += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary); } return s; } */ -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -162,7 +159,7 @@ if (!_archive.IsInstaller) { if (!s.IsEmpty()) - s += '.'; + s.Add_Dot(); s += "Uninstall"; } #endif @@ -190,7 +187,7 @@ } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); @@ -215,18 +212,18 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _archive.Clear(); _archive.Release(); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _archive.Items.Size() #ifdef NSIS_SCRIPT - + 1 + _archive.LicenseFiles.Size(); + + 1 + _archive.LicenseFiles.Size() #endif ; return S_OK; @@ -240,7 +237,7 @@ size = item.Size; else if (_archive.IsSolid && item.EstimatedSize_Defined) size = item.EstimatedSize; - else + else if (!item.IsEmptyFile) return false; return true; } @@ -272,7 +269,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -360,21 +357,21 @@ } -static bool UninstallerPatch(const Byte *p, size_t size, CByteBuffer &dest) +static bool UninstallerPatch(const Byte *p, size_t size, Byte *dest, size_t destSize) { for (;;) { if (size < 4) return false; - UInt32 len = Get32(p); + const UInt32 len = Get32(p); if (len == 0) return size == 4; if (size < 8) return false; - UInt32 offs = Get32(p + 4); + const UInt32 offs = Get32(p + 4); p += 8; size -= 8; - if (size < len || offs > dest.Size() || len > dest.Size() - offs) + if (size < len || offs > destSize || len > destSize - offs) return false; memcpy(dest + offs, p, len); p += len; @@ -383,11 +380,11 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) GetNumberOfItems(&numItems); if (numItems == 0) @@ -399,7 +396,7 @@ UInt32 i; for (i = 0; i < numItems; i++) { - UInt32 index = (allFilesMode ? i : indices[i]); + const UInt32 index = (allFilesMode ? i : indices[i]); #ifdef NSIS_SCRIPT if (index >= _archive.Items.Size()) @@ -430,14 +427,13 @@ extractCallback->SetTotal(totalSize + solidPosMax); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, !_archive.IsSolid); if (_archive.IsSolid) { - RINOK(_archive.SeekTo_DataStreamOffset()); - RINOK(_archive.InitDecoder()); + RINOK(_archive.SeekTo_DataStreamOffset()) + RINOK(_archive.InitDecoder()) _archive.Decoder.StreamPos = 0; } @@ -476,16 +472,16 @@ curPacked = 0; curUnpacked = 0; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) - // RINOK(extractCallback->SetCompleted(¤tTotalSize)); + // RINOK(extractCallback->SetCompleted(¤tTotalSize)) CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) bool dataError = false; @@ -511,9 +507,9 @@ curUnpacked = size; if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (realOutStream) - RINOK(WriteStream(realOutStream, data, size)); + RINOK(WriteStream(realOutStream, data, size)) } else #endif @@ -526,15 +522,20 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) dataError = solidDataError; - bool needDecompress = !solidDataError; - if (needDecompress) + bool needDecompress = false; + + if (!item.IsEmptyFile) { - if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos) - needDecompress = false; + needDecompress = !solidDataError; + if (needDecompress) + { + if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos) + needDecompress = false; + } } if (needDecompress) @@ -544,7 +545,7 @@ if (!_archive.IsSolid) { - RINOK(_archive.SeekToNonSolidItem(index)); + RINOK(_archive.SeekToNonSolidItem(index)) } else { @@ -557,7 +558,7 @@ } else { - HRESULT res = _archive.Decoder.SetToPos(pos, progress); + HRESULT res = _archive.Decoder.SetToPos(pos, lps); if (res != S_OK) { if (res != S_FALSE) @@ -566,10 +567,11 @@ } else if (!testMode && i + 1 < numItems) { - UInt32 next = allFilesMode ? i + 1 : indices[i + 1]; + const UInt32 next = allFilesMode ? i + 1 : indices[i + 1]; if (next < _archive.Items.Size()) { - UInt64 nextPos = _archive.GetPosOfSolidItem(next); + // next cannot be IsEmptyFile + const UInt64 nextPos = _archive.GetPosOfSolidItem(next); if (nextPos == pos) { writeToTemp = true; @@ -581,12 +583,16 @@ prevPos = pos; } + /* nsis 3.08 can use (PatchSize == 0) for uninstaller without patched section */ + + const bool is_PatchedUninstaller = item.Is_PatchedUninstaller(); + if (!dataError) { // UInt32 unpackSize = 0; // bool unpackSize_Defined = false; bool writeToTemp1 = writeToTemp; - if (item.IsUninstaller) + if (is_PatchedUninstaller) { // unpackSize = item.PatchSize; // unpackSize_Defined = true; @@ -603,17 +609,17 @@ if (readFromTemp) { - if (realOutStream && !item.IsUninstaller) - RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size())); + if (realOutStream && !is_PatchedUninstaller) + RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size())) } else { UInt32 curUnpacked32 = 0; - HRESULT res = _archive.Decoder.Decode( + const HRESULT res = _archive.Decoder.Decode( writeToTemp1 ? &tempBuf : NULL, - item.IsUninstaller, item.PatchSize, - item.IsUninstaller ? NULL : (ISequentialOutStream *)realOutStream, - progress, + is_PatchedUninstaller, item.PatchSize, + is_PatchedUninstaller ? NULL : (ISequentialOutStream *)realOutStream, + lps, curPacked, curUnpacked32); curUnpacked = curUnpacked32; if (_archive.IsSolid) @@ -629,21 +635,20 @@ } } - if (!dataError && item.IsUninstaller) + if (!dataError && is_PatchedUninstaller) { if (_archive.ExeStub.Size() != 0) { CByteBuffer destBuf = _archive.ExeStub; - dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf); - + dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf, destBuf.Size()); if (realOutStream) - RINOK(WriteStream(realOutStream, destBuf, destBuf.Size())); + RINOK(WriteStream(realOutStream, destBuf, destBuf.Size())) } if (readFromTemp) { if (realOutStream) - RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size())); + RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size())) } else { @@ -652,14 +657,14 @@ if (!_archive.IsSolid) { - RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked )); + RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked )) } - HRESULT res = _archive.Decoder.Decode( + const HRESULT res = _archive.Decoder.Decode( writeToTemp ? &tempBuf2 : NULL, false, 0, realOutStream, - progress, + lps, curPacked2, curUnpacked2); curPacked += curPacked2; if (!_archive.IsSolid) @@ -679,7 +684,7 @@ realOutStream.Release(); RINOK(extractCallback->SetOperationResult(dataError ? NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kOK)); + NExtract::NOperationResult::kOK)) } return S_OK; COM_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.h 2013-02-10 05:29:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // NSisHandler.h -#ifndef __NSIS_HANDLER_H -#define __NSIS_HANDLER_H +#ifndef ZIP7_INC_NSIS_HANDLER_H +#define ZIP7_INC_NSIS_HANDLER_H #include "../../../Common/MyCom.h" @@ -14,10 +14,8 @@ namespace NArchive { namespace NNsis { -class CHandler: - public IInArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_0 + CInArchive _archive; AString _methodString; @@ -25,10 +23,6 @@ bool GetCompressedSize(unsigned index, UInt32 &size) const; // AString GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const; -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.cpp 2021-11-12 16:52:52.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -6,7 +6,6 @@ #include "../../../Common/StringToInt.h" #include "../../Common/LimitedStreams.h" -#include "../../Common/StreamUtils.h" #include "NsisIn.h" @@ -32,7 +31,7 @@ static const char * const kErrorStr = "$_ERROR_STR_"; -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } /* There are several versions of NSIS: @@ -466,8 +465,8 @@ } strUsed[param] = 1; - UInt32 start = _stringsPos + (IsUnicode ? param * 2 : param); - UInt32 offset = start + (IsUnicode ? 2 : 1); + const UInt32 start = _stringsPos + (IsUnicode ? param * 2 : param); + const UInt32 offset = start + (IsUnicode ? 2 : 1); { FOR_VECTOR (i, LicenseFiles) { @@ -484,16 +483,16 @@ { fileName += "\\license-"; // LangId_To_String(fileName, langID); - UIntToString(fileName, langID); + UIntToString(fileName, (UInt32)langID); } else if (++_numRootLicenses > 1) { - fileName += '-'; + fileName.Add_Minus(); UIntToString(fileName, _numRootLicenses); } const Byte *sz = (_data + start); - unsigned marker = IsUnicode ? Get16(sz) : *sz; - bool isRTF = (marker == 2); + const unsigned marker = IsUnicode ? Get16(sz) : *sz; + const bool isRTF = (marker == 2); fileName += isRTF ? ".rtf" : ".txt"; // if (*sz == 1) it's text; Script += fileName; @@ -505,7 +504,7 @@ else { sz += 2; - UInt32 len = GetUi16Str_Len(sz); + const UInt32 len = GetUi16Str_Len(sz); lic.Size = len * 2; if (isRTF) { @@ -526,6 +525,26 @@ #endif +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_GENERIC_READ ((UInt32)1 << 31) +#endif +#define Z7_NSIS_WIN_GENERIC_WRITE ((UInt32)1 << 30) +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_GENERIC_EXECUTE ((UInt32)1 << 29) +#define Z7_NSIS_WIN_GENERIC_ALL ((UInt32)1 << 28) +#endif + +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_CREATE_NEW 1 +#endif +#define Z7_NSIS_WIN_CREATE_ALWAYS 2 +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_OPEN_EXISTING 3 +#define Z7_NSIS_WIN_OPEN_ALWAYS 4 +#define Z7_NSIS_WIN_TRUNCATE_EXISTING 5 +#endif + + // #define kVar_CMDLINE 20 #define kVar_INSTDIR 21 #define kVar_OUTDIR 22 @@ -562,9 +581,9 @@ , "_OUTDIR" // NSIS 2.04+ }; -static const unsigned kNumInternalVars = 20 + ARRAY_SIZE(kVarStrings); +static const unsigned kNumInternalVars = 20 + Z7_ARRAY_SIZE(kVarStrings); -#define GET_NUM_INTERNAL_VARS (IsNsis200 ? kNumInternalVars - 3 : IsNsis225 ? kNumInternalVars - 2 : kNumInternalVars); +#define GET_NUM_INTERNAL_VARS (IsNsis200 ? kNumInternalVars - 3 : IsNsis225 ? kNumInternalVars - 2 : kNumInternalVars) void CInArchive::GetVar2(AString &res, UInt32 index) { @@ -643,7 +662,7 @@ #define IS_NS_SPEC_CHAR(c) ((c) >= NS_CODE_SKIP) #define IS_PARK_SPEC_CHAR(c) ((c) >= PARK_CODE_SKIP && (c) <= PARK_CODE_LANG) -#define DECODE_NUMBER_FROM_2_CHARS(c0, c1) (((c0) & 0x7F) | (((unsigned)((c1) & 0x7F)) << 7)) +#define DECODE_NUMBER_FROM_2_CHARS(c0, c1) (((unsigned)(c0) & 0x7F) | (((unsigned)((c1) & 0x7F)) << 7)) #define CONVERT_NUMBER_NS_3_UNICODE(n) n = ((n & 0x7F) | (((n >> 8) & 0x7F) << 7)) #define CONVERT_NUMBER_PARK(n) n &= 0x7FFF @@ -738,7 +757,7 @@ } s += '$'; - if (index1 < ARRAY_SIZE(kShellStrings)) + if (index1 < Z7_ARRAY_SIZE(kShellStrings)) { const char *sz = kShellStrings[index1]; if (sz) @@ -747,7 +766,7 @@ return; } } - if (index2 < ARRAY_SIZE(kShellStrings)) + if (index2 < Z7_ARRAY_SIZE(kShellStrings)) { const char *sz = kShellStrings[index2]; if (sz) @@ -960,7 +979,7 @@ break; if (c < 0x80) { - Raw_UString += (char)c; + Raw_UString.Add_Char((char)c); continue; } @@ -1151,7 +1170,7 @@ Raw_AString.Empty(); Raw_UString.Empty(); if ((Int32)pos < 0) - Add_LangStr(Raw_AString, -((Int32)pos + 1)); + Add_LangStr(Raw_AString, (UInt32)-((Int32)pos + 1)); else if (pos >= NumStringChars) { Raw_AString += kErrorStr; @@ -1361,7 +1380,7 @@ { if ((Int32)pos < 0) { - Add_LangStr(s, -((Int32)pos + 1)); + Add_LangStr(s, (UInt32)-((Int32)pos + 1)); return; } @@ -1537,7 +1556,7 @@ static const UInt32 CMD_REF_OnFunc = (1 << 5); static const UInt32 CMD_REF_Section = (1 << 6); static const UInt32 CMD_REF_InitPluginDir = (1 << 7); -// static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead +// static const UInt32 CMD_REF_Creator = (1 << 5); // CMD_REF_Pre is used instead static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too static const unsigned CMD_REF_Page_NumShifts = 16; // it uses for onFunc too static const UInt32 CMD_REF_Page_Mask = 0x0FFF0000; @@ -1617,7 +1636,7 @@ { Space(); if ((Int32)param < 0) - Add_Var(-((Int32)param + 1)); + Add_Var((UInt32)-((Int32)param + 1)); else Add_LabelName(param - 1); } @@ -1647,8 +1666,8 @@ static const char * const k_REBOOTOK = " /REBOOTOK"; -#define MY__MB_ABORTRETRYIGNORE 2 -#define MY__MB_RETRYCANCEL 5 +#define Z7_NSIS_WIN_MB_ABORTRETRYIGNORE 2 +#define Z7_NSIS_WIN_MB_RETRYCANCEL 5 static const char * const k_MB_Buttons[] = { @@ -1661,7 +1680,7 @@ , "CANCELTRYCONTINUE" }; -#define MY__MB_ICONSTOP (1 << 4) +#define Z7_NSIS_WIN_MB_ICONSTOP (1 << 4) static const char * const k_MB_Icons[] = { @@ -1684,8 +1703,8 @@ // , "SERVICE_NOTIFICATION" // unsupported. That bit is used for NSIS purposes }; -#define MY__IDCANCEL 2 -#define MY__IDIGNORE 5 +#define Z7_NSIS_WIN_IDCANCEL 2 +#define Z7_NSIS_WIN_IDIGNORE 5 static const char * const k_Button_IDs[] = { @@ -1706,7 +1725,7 @@ void CInArchive::Add_ButtonID(UInt32 buttonID) { Space(); - if (buttonID < ARRAY_SIZE(k_Button_IDs)) + if (buttonID < Z7_ARRAY_SIZE(k_Button_IDs)) Script += k_Button_IDs[buttonID]; else { @@ -1774,19 +1793,8 @@ } // Win32 constants -#define MY__TRANSPARENT 1 -// #define MY__OPAQUE 2 - -#define MY__GENERIC_READ ((UInt32)1 << 31) -#define MY__GENERIC_WRITE ((UInt32)1 << 30) -#define MY__GENERIC_EXECUTE ((UInt32)1 << 29) -#define MY__GENERIC_ALL ((UInt32)1 << 28) - -#define MY__CREATE_NEW 1 -#define MY__CREATE_ALWAYS 2 -#define MY__OPEN_EXISTING 3 -#define MY__OPEN_ALWAYS 4 -#define MY__TRUNCATE_EXISTING 5 +#define Z7_NSIS_WIN_TRANSPARENT 1 +// #define Z7_NSIS_WIN_OPAQUE 2 // text/bg colors #define kColorsFlags_TEXT 1 @@ -1821,12 +1829,12 @@ Add_Color2(v); } -#define MY__SW_HIDE 0 -#define MY__SW_SHOWNORMAL 1 +#define Z7_NSIS_WIN_SW_HIDE 0 +#define Z7_NSIS_WIN_SW_SHOWNORMAL 1 -#define MY__SW_SHOWMINIMIZED 2 -#define MY__SW_SHOWMINNOACTIVE 7 -#define MY__SW_SHOWNA 8 +#define Z7_NSIS_WIN_SW_SHOWMINIMIZED 2 +#define Z7_NSIS_WIN_SW_SHOWMINNOACTIVE 7 +#define Z7_NSIS_WIN_SW_SHOWNA 8 static const char * const kShowWindow_Commands[] = { @@ -1846,7 +1854,7 @@ static void Add_ShowWindow_Cmd_2(AString &s, UInt32 cmd) { - if (cmd < ARRAY_SIZE(kShowWindow_Commands)) + if (cmd < Z7_ARRAY_SIZE(kShowWindow_Commands)) { s += "SW_"; s += kShowWindow_Commands[cmd]; @@ -1857,7 +1865,7 @@ void CInArchive::Add_ShowWindow_Cmd(UInt32 cmd) { - if (cmd < ARRAY_SIZE(kShowWindow_Commands)) + if (cmd < Z7_ARRAY_SIZE(kShowWindow_Commands)) { Script += "SW_"; Script += kShowWindow_Commands[cmd]; @@ -1877,7 +1885,7 @@ } } -#define ADD_TYPE_FROM_LIST(table, type) Add_TypeFromList(table, ARRAY_SIZE(table), type) +#define ADD_TYPE_FROM_LIST(table, type) Add_TypeFromList(table, Z7_ARRAY_SIZE(table), type) enum { @@ -1894,7 +1902,7 @@ k_ExecFlags_rtl, k_ExecFlags_ErrorLevel, k_ExecFlags_RegView, - k_ExecFlags_DetailsPrint = 13, + k_ExecFlags_DetailsPrint = 13 }; // Names for NSIS exec_flags_t structure vars @@ -2097,7 +2105,7 @@ StartCmdIndex = Get32(p + 12); NumCommands = Get32(p + 16); SizeKB = Get32(p + 20); -}; +} // used for section->flags #define SF_SELECTED (1 << 0) @@ -2182,7 +2190,7 @@ { TabString("SectionIn"); UInt32 instTypes = sect.InstallTypes; - for (int i = 0; i < 32; i++, instTypes >>= 1) + for (unsigned i = 0; i < 32; i++, instTypes >>= 1) if ((instTypes & 1) != 0) { AddParam_UInt(i + 1); @@ -2270,7 +2278,7 @@ { UInt32 v = param & 0xF; Script += " MB_"; - if (v < ARRAY_SIZE(k_MB_Buttons)) + if (v < Z7_ARRAY_SIZE(k_MB_Buttons)) Script += k_MB_Buttons[v]; else { @@ -2283,7 +2291,7 @@ if (icon != 0) { Script += "|MB_"; - if (icon < ARRAY_SIZE(k_MB_Icons) && k_MB_Icons[icon] != 0) + if (icon < Z7_ARRAY_SIZE(k_MB_Icons) && k_MB_Icons[icon]) Script += k_MB_Icons[icon]; else { @@ -2308,7 +2316,7 @@ else if (modal == 2) Script += "|MB_TASKMODAL"; else if (modal == 3) Script += "|0x3000"; UInt32 flags = (param >> 14); - for (unsigned i = 0; i < ARRAY_SIZE(k_MB_Flags); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_MB_Flags); i++) if ((flags & (1 << i)) != 0) { Script += "|MB_"; @@ -2381,7 +2389,7 @@ if (BadCmd >= 0) { AddString(s, "BadCmd="); - UIntToString(s, BadCmd); + UIntToString(s, (UInt32)BadCmd); } return s; } @@ -2455,7 +2463,7 @@ for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) { - UInt32 id = GetCmd(Get32(p)); + const UInt32 id = GetCmd(Get32(p)); if (id >= kNumCmds) continue; if (BadCmd >= 0 && id >= (unsigned)BadCmd) @@ -2465,7 +2473,7 @@ { if (id == EW_RESERVEDOPCODE) { - BadCmd = id; + BadCmd = (int)id; continue; } } @@ -2474,23 +2482,23 @@ // if (id == EW_GETLABELADDR || id == EW_GETFUNCTIONADDR) if (id == EW_RESERVEDOPCODE || id == EW_GETOSINFO) { - BadCmd = id; + BadCmd = (int)id; continue; } } for (i = 6; i != 0; i--) { - UInt32 param = Get32(p + i * 4); + const UInt32 param = Get32(p + i * 4); if (param != 0) break; } if (id == EW_FINDPROC && i == 0) { - BadCmd = id; + BadCmd = (int)id; continue; } if (k_Commands[id].NumParams < i) - BadCmd = id; + BadCmd = (int)id; } } @@ -2615,7 +2623,7 @@ for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p2 += kCmdSize) { - UInt32 cmd = Get32(p2); // we use original (not converted) command + const UInt32 cmd = Get32(p2); // we use original (not converted) command if (cmd < EW_WRITEUNINSTALLER || cmd > EW_WRITEUNINSTALLER + numInsertMax) @@ -2631,7 +2639,7 @@ params[3] <= 1) continue; - UInt32 altParam = params[3]; + const UInt32 altParam = params[3]; if (!IsGoodString(params[0]) || !IsGoodString(altParam)) continue; @@ -2641,8 +2649,8 @@ continue; if (AreTwoParamStringsEqual(altParam + additional, params[0])) { - unsigned numInserts = cmd - EW_WRITEUNINSTALLER; - mask |= (1 << numInserts); + const unsigned numInserts = cmd - EW_WRITEUNINSTALLER; + mask |= ((unsigned)1 << numInserts); } } @@ -2770,13 +2778,13 @@ else if (c != NS_CODE_VAR) return -1; - unsigned c0 = p[1]; + const unsigned c0 = p[1]; if (c0 == 0) return -1; - unsigned c1 = p[2]; + const unsigned c1 = p[2]; if (c1 == 0) return -1; - return DECODE_NUMBER_FROM_2_CHARS(c0, c1); + return (Int32)DECODE_NUMBER_FROM_2_CHARS(c0, c1); } Int32 CInArchive::GetVarIndex(UInt32 strPos, UInt32 &resOffset) const @@ -2870,18 +2878,18 @@ void CInArchive::SetItemName(CItem &item, UInt32 strPos) { ReadString2_Raw(strPos); - bool isAbs = IsAbsolutePathVar(strPos); + const bool isAbs = IsAbsolutePathVar(strPos); if (IsUnicode) { item.NameU = Raw_UString; if (!isAbs && !IsAbsolutePath(Raw_UString)) - item.Prefix = UPrefixes.Size() - 1; + item.Prefix = (int)UPrefixes.Size() - 1; } else { item.NameA = Raw_AString; if (!isAbs && !IsAbsolutePath(Raw_AString)) - item.Prefix = APrefixes.Size() - 1; + item.Prefix = (int)APrefixes.Size() - 1; } } @@ -2949,9 +2957,9 @@ for (int i = 0; i < 5; i++) params[i] = Get32(p + 44 + 4 * i); - SET_FUNC_REF(preFunc, CMD_REF_Pre); - SET_FUNC_REF(showFunc, CMD_REF_Show); - SET_FUNC_REF(leaveFunc, CMD_REF_Leave); + SET_FUNC_REF(preFunc, CMD_REF_Pre) + SET_FUNC_REF(showFunc, CMD_REF_Show) + SET_FUNC_REF(leaveFunc, CMD_REF_Leave) if (wndProcID == PWP_COMPLETED) CommentOpen(); @@ -2969,7 +2977,7 @@ else s += IsInstaller ? "Page " : "UninstPage "; - if (wndProcID < ARRAY_SIZE(kPageTypes)) + if (wndProcID < Z7_ARRAY_SIZE(kPageTypes)) s += kPageTypes[wndProcID]; else Add_UInt(wndProcID); @@ -3189,11 +3197,11 @@ } */ if (IsFunc(flg) - && bh.Num - kkk >= ARRAY_SIZE(k_InitPluginDir_Commands) - && CompareCommands(p, k_InitPluginDir_Commands, ARRAY_SIZE(k_InitPluginDir_Commands))) + && bh.Num - kkk >= Z7_ARRAY_SIZE(k_InitPluginDir_Commands) + && CompareCommands(p, k_InitPluginDir_Commands, Z7_ARRAY_SIZE(k_InitPluginDir_Commands))) { - InitPluginsDir_Start = kkk; - InitPluginsDir_End = (int)(kkk + ARRAY_SIZE(k_InitPluginDir_Commands)); + InitPluginsDir_Start = (int)kkk; + InitPluginsDir_End = (int)(kkk + Z7_ARRAY_SIZE(k_InitPluginDir_Commands)); labels[kkk] |= CMD_REF_InitPluginDir; break; } @@ -3356,7 +3364,7 @@ unsigned numSkipParams = 0; - if (commandId < ARRAY_SIZE(k_Commands) && commandId < numSupportedCommands) + if (commandId < Z7_ARRAY_SIZE(k_Commands) && commandId < numSupportedCommands) { numSkipParams = k_Commands[commandId].NumParams; const char *sz = k_CommandNames[commandId]; @@ -3505,9 +3513,9 @@ UInt32 b1 = nsisMB >> 21; // NSIS 2.06+ UInt32 b2 = nsisMB >> 20; // NSIS old Int32 asf = (Int32)nsisMB; - if (mb == (MY__MB_ABORTRETRYIGNORE | MY__MB_ICONSTOP) && (b1 == MY__IDIGNORE || b2 == MY__IDIGNORE)) + if (mb == (Z7_NSIS_WIN_MB_ABORTRETRYIGNORE | Z7_NSIS_WIN_MB_ICONSTOP) && (b1 == Z7_NSIS_WIN_IDIGNORE || b2 == Z7_NSIS_WIN_IDIGNORE)) asf = -1; - else if (mb == (MY__MB_RETRYCANCEL | MY__MB_ICONSTOP) && (b1 == MY__IDCANCEL || b2 == MY__IDCANCEL)) + else if (mb == (Z7_NSIS_WIN_MB_RETRYCANCEL | Z7_NSIS_WIN_MB_ICONSTOP) && (b1 == Z7_NSIS_WIN_IDCANCEL || b2 == Z7_NSIS_WIN_IDCANCEL)) asf = -2; else { @@ -3591,7 +3599,7 @@ #ifdef NSIS_SCRIPT AddParam(params[0]); Space(); - FlagsToString2(s, g_WinAttrib, ARRAY_SIZE(g_WinAttrib), params[1]); + FlagsToString2(s, g_WinAttrib, Z7_ARRAY_SIZE(g_WinAttrib), params[1]); #endif break; } @@ -3603,7 +3611,7 @@ NSIS installer uses alternative path, if main path from params[0] is not absolute path */ - bool pathOk = (params[0] > 0) && IsGoodString(params[0]); + const bool pathOk = (params[0] > 0) && IsGoodString(params[0]); if (!pathOk) { @@ -3613,9 +3621,11 @@ break; } + #ifdef NSIS_SCRIPT + bool altPathOk = true; - UInt32 altParam = params[3]; + const UInt32 altParam = params[3]; if (altParam != 0) { altPathOk = false; @@ -3624,9 +3634,6 @@ altPathOk = AreTwoParamStringsEqual(altParam + additional, params[0]); } - - #ifdef NSIS_SCRIPT - AddParam(params[0]); /* @@ -3640,8 +3647,6 @@ AddParam(params[3]); } - #endif - if (!altPathOk) { #ifdef NSIS_SCRIPT @@ -3649,9 +3654,11 @@ #endif } + #endif + if (BadCmd >= 0 && BadCmd <= EW_WRITEUNINSTALLER) { - /* We don't cases with incorrect installer commands. + /* We don't support cases with incorrect installer commands. Such bad installer item can break unpacking for other items. */ #ifdef NSIS_SCRIPT AddError("SKIP possible BadCmd"); @@ -3659,13 +3666,23 @@ break; } - CItem &item = Items.AddNew();; + CItem &item = Items.AddNew(); SetItemName(item, params[0]); item.Pos = params[1]; item.PatchSize = params[2]; item.IsUninstaller = true; + const UInt32 param3 = params[3]; + if (param3 != 0 && item.Prefix != -1) + { + /* (item.Prefix != -1) case means that param[0] path was not absolute. + So we use params[3] in that case, as original nsis */ + SetItemName(item, param3); + } + /* UNINSTALLER file doesn't use directory prefixes. + So we remove prefix: */ + item.Prefix = -1; /* // we can add second time to test the code @@ -3834,12 +3851,12 @@ s += "Call "; if ((Int32)params[0] < 0) - Add_Var(-((Int32)params[0] + 1)); + Add_Var((UInt32)-((Int32)params[0] + 1)); else if (params[0] == 0) s += '0'; else { - UInt32 val = params[0] - 1; + const UInt32 val = params[0] - 1; if (params[1] == 1) // it's Call :Label { s += ':'; @@ -3860,8 +3877,8 @@ case EW_CHDETAILSVIEW: { - if (params[0] == MY__SW_SHOWNA && params[1] == MY__SW_HIDE) s += " show"; - else if (params[1] == MY__SW_SHOWNA && params[0] == MY__SW_HIDE) s += " hide"; + if (params[0] == Z7_NSIS_WIN_SW_SHOWNA && params[1] == Z7_NSIS_WIN_SW_HIDE) s += " show"; + else if (params[1] == Z7_NSIS_WIN_SW_SHOWNA && params[0] == Z7_NSIS_WIN_SW_HIDE) s += " hide"; else for (int i = 0; i < 2; i++) { @@ -3935,7 +3952,7 @@ Add_ExecFlags(params[2]); Add_GotoVars2(¶ms[0]); /* - static const unsigned kIfErrors = 2; + const unsigned kIfErrors = 2; if (params[2] != kIfErrors && params[3] != 0xFFFFFFFF || params[2] == kIfErrors && params[3] != 0) { @@ -3988,7 +4005,7 @@ AddParam_Var(params[0]); AString temp; ReadString2(temp, params[1]); - if (temp != "$TEMP") + if (!temp.IsEqualTo("$TEMP")) SpaceQuStr(temp); break; } @@ -4244,7 +4261,7 @@ AString bk; bool bkc = false; - if (colors.bkmode == MY__TRANSPARENT) + if (colors.bkmode == Z7_NSIS_WIN_TRANSPARENT) bk += " transparent"; else if (colors.flags & kColorsFlags_BKB) { @@ -4305,7 +4322,7 @@ bool valDefined = false; if (StringToUInt32(sw, val)) { - if (val < ARRAY_SIZE(kShowWindow_Commands)) + if (val < Z7_ARRAY_SIZE(kShowWindow_Commands)) { sw.Empty(); sw += "${"; @@ -4338,10 +4355,10 @@ case EW_SHELLEXEC: { AddParams(params, 2); - if (params[2] != 0 || params[3] != MY__SW_SHOWNORMAL) + if (params[2] != 0 || params[3] != Z7_NSIS_WIN_SW_SHOWNORMAL) { AddParam(params[2]); - if (params[3] != MY__SW_SHOWNORMAL) + if (params[3] != Z7_NSIS_WIN_SW_SHOWNORMAL) { Space(); Add_ShowWindow_Cmd(params[3]); @@ -4393,7 +4410,7 @@ } else { - if (func == "DllUnregisterServer") + if (func.IsEqualTo("DllUnregisterServer")) { s += "UnRegDLL"; printFunc = false; @@ -4401,7 +4418,7 @@ else { s += "RegDLL"; - if (func == "DllRegisterServer") + if (func.IsEqualTo("DllRegisterServer")) printFunc = false; } AddParam(params[0]); @@ -4442,8 +4459,8 @@ UInt32 sw = (spec >> sw_shift) & sw_mask; Space(); // NSIS encoder replaces these names: - if (sw == MY__SW_SHOWMINNOACTIVE) - sw = MY__SW_SHOWMINIMIZED; + if (sw == Z7_NSIS_WIN_SW_SHOWMINNOACTIVE) + sw = Z7_NSIS_WIN_SW_SHOWMINIMIZED; if (sw == 0) AddQuotes(); else @@ -4467,7 +4484,7 @@ if (modKey & 4) s += "ALT|"; if (modKey & 8) s += "EXT|"; - static const unsigned kMy_VK_F1 = 0x70; + const unsigned kMy_VK_F1 = 0x70; if (key >= kMy_VK_F1 && key <= kMy_VK_F1 + 23) { s += 'F'; @@ -4559,7 +4576,7 @@ case EW_WRITEREG: { - const char *s2 = 0; + const char *s2 = NULL; switch (params[4]) { case 1: s2 = "Str"; break; @@ -4642,20 +4659,42 @@ break; } + #endif + case EW_FOPEN: { + /* + the pattern for empty files is following: + FileOpen $0 "file_name" w + FileClose $0 + */ + + const UInt32 acc = params[1]; // dwDesiredAccess + const UInt32 creat = params[2]; // dwCreationDisposition + if (creat == Z7_NSIS_WIN_CREATE_ALWAYS && acc == Z7_NSIS_WIN_GENERIC_WRITE) + { + if (kkk + 1 < bh.Num) + if (Get32(p + kCmdSize) == EW_FCLOSE) + if (Get32(p + kCmdSize + 4) == params[0]) + { + CItem &item = Items.AddNew(); + item.IsEmptyFile = true; + SetItemName(item, params[3]); + } + } + + #ifdef NSIS_SCRIPT + AddParam_Var(params[0]); AddParam(params[3]); - UInt32 acc = params[1]; // dwDesiredAccess - UInt32 creat = params[2]; // dwCreationDisposition if (acc == 0 && creat == 0) break; char cc = 0; - if (acc == MY__GENERIC_READ && creat == OPEN_EXISTING) + if (creat == Z7_NSIS_WIN_OPEN_EXISTING && acc == Z7_NSIS_WIN_GENERIC_READ) cc = 'r'; - else if (creat == CREATE_ALWAYS && acc == MY__GENERIC_WRITE) + else if (creat == Z7_NSIS_WIN_CREATE_ALWAYS && acc == Z7_NSIS_WIN_GENERIC_WRITE) cc = 'w'; - else if (creat == OPEN_ALWAYS && (acc == (MY__GENERIC_WRITE | MY__GENERIC_READ))) + else if (creat == Z7_NSIS_WIN_OPEN_ALWAYS && (acc == (Z7_NSIS_WIN_GENERIC_WRITE | Z7_NSIS_WIN_GENERIC_READ))) cc = 'a'; // cc = 0; if (cc != 0) @@ -4665,28 +4704,32 @@ break; } - if (acc & MY__GENERIC_READ) s += " GENERIC_READ"; - if (acc & MY__GENERIC_WRITE) s += " GENERIC_WRITE"; - if (acc & MY__GENERIC_EXECUTE) s += " GENERIC_EXECUTE"; - if (acc & MY__GENERIC_ALL) s += " GENERIC_ALL"; + if (acc & Z7_NSIS_WIN_GENERIC_READ) s += " GENERIC_READ"; + if (acc & Z7_NSIS_WIN_GENERIC_WRITE) s += " GENERIC_WRITE"; + if (acc & Z7_NSIS_WIN_GENERIC_EXECUTE) s += " GENERIC_EXECUTE"; + if (acc & Z7_NSIS_WIN_GENERIC_ALL) s += " GENERIC_ALL"; const char *s2 = NULL; switch (creat) { - case MY__CREATE_NEW: s2 = "CREATE_NEW"; break; - case MY__CREATE_ALWAYS: s2 = "CREATE_ALWAYS"; break; - case MY__OPEN_EXISTING: s2 = "OPEN_EXISTING"; break; - case MY__OPEN_ALWAYS: s2 = "OPEN_ALWAYS"; break; - case MY__TRUNCATE_EXISTING: s2 = "TRUNCATE_EXISTING"; break; + case Z7_NSIS_WIN_CREATE_NEW: s2 = "CREATE_NEW"; break; + case Z7_NSIS_WIN_CREATE_ALWAYS: s2 = "CREATE_ALWAYS"; break; + case Z7_NSIS_WIN_OPEN_EXISTING: s2 = "OPEN_EXISTING"; break; + case Z7_NSIS_WIN_OPEN_ALWAYS: s2 = "OPEN_ALWAYS"; break; + case Z7_NSIS_WIN_TRUNCATE_EXISTING: s2 = "TRUNCATE_EXISTING"; break; } Space(); if (s2) s += s2; else Add_UInt(creat); + #endif + break; } + #ifdef NSIS_SCRIPT + case EW_FPUTS: case EW_FPUTWS: { @@ -4780,7 +4823,7 @@ else { s += "Set"; - UInt32 t = -(Int32)params[2] - 1; + const UInt32 t = (UInt32)(-(Int32)params[2] - 1); Add_SectOp(t); AddParam(params[0]); AddParam(params[t == 0 ? 4 : 1]); @@ -4793,7 +4836,7 @@ case EW_INSTTYPESET: { - int numQwParams = 0; + unsigned numQwParams = 0; const char *s2; if (params[3] == 0) { @@ -4843,7 +4886,7 @@ AddParam_Var(params[1]); AddParam(params[2]); AddParam(params[4]); - // if (params[2] == "0") AddCommentAndString("GetWinVer"); + // if (params[2].IsEqualTo("0")) AddCommentAndString("GetWinVer"); } else s += "GetOsInfo"; @@ -4952,7 +4995,18 @@ { const CItem &i1 = **(const CItem *const *)p1; const CItem &i2 = **(const CItem *const *)p2; - RINOZ(MyCompare(i1.Pos, i2.Pos)); + RINOZ(MyCompare(i1.Pos, i2.Pos)) + + /* In another code we check CItem::Pos after each solid item. + So here we place empty files before all non empty files */ + if (i1.IsEmptyFile) + { + if (!i2.IsEmptyFile) + return -1; + } + else if (i2.IsEmptyFile) + return 1; + const CInArchive *inArchive = (const CInArchive *)param; if (inArchive->IsUnicode) { @@ -4962,9 +5016,9 @@ if (i2.Prefix < 0) return 1; RINOZ( inArchive->UPrefixes[i1.Prefix].Compare( - inArchive->UPrefixes[i2.Prefix])); + inArchive->UPrefixes[i2.Prefix])) } - RINOZ(i1.NameU.Compare(i2.NameU)); + RINOZ(i1.NameU.Compare(i2.NameU)) } else { @@ -4974,9 +5028,9 @@ if (i2.Prefix < 0) return 1; RINOZ(strcmp( inArchive->APrefixes[i1.Prefix], - inArchive->APrefixes[i2.Prefix])); + inArchive->APrefixes[i2.Prefix])) } - RINOZ(strcmp(i1.NameA, i2.NameA)); + RINOZ(strcmp(i1.NameA, i2.NameA)) } return 0; } @@ -4990,6 +5044,8 @@ for (i = 0; i + 1 < Items.Size(); i++) { const CItem &i1 = Items[i]; + if (i1.IsEmptyFile) + continue; const CItem &i2 = Items[i + 1]; if (i1.Pos != i2.Pos) continue; @@ -5019,10 +5075,14 @@ for (i = 0; i < Items.Size(); i++) { CItem &item = Items[i]; - UInt32 curPos = item.Pos + 4; + if (item.IsEmptyFile) + continue; + const UInt32 curPos = item.Pos + 4; for (unsigned nextIndex = i + 1; nextIndex < Items.Size(); nextIndex++) { - UInt32 nextPos = Items[nextIndex].Pos; + const CItem &nextItem = Items[nextIndex]; + // if (nextItem.IsEmptyFile) continue; + const UInt32 nextPos = nextItem.Pos; if (curPos <= nextPos) { item.EstimatedSize_Defined = true; @@ -5037,11 +5097,13 @@ for (i = 0; i < Items.Size(); i++) { CItem &item = Items[i]; - RINOK(SeekToNonSolidItem(i)); + if (item.IsEmptyFile) + continue; + RINOK(SeekToNonSolidItem(i)) const UInt32 kSigSize = 4 + 1 + 1 + 4; // size,[flag],prop,dict BYTE sig[kSigSize]; size_t processedSize = kSigSize; - RINOK(ReadStream(_stream, sig, &processedSize)); + RINOK(ReadStream(_stream, sig, &processedSize)) if (processedSize < 4) return S_FALSE; UInt32 size = Get32(sig); @@ -5218,7 +5280,7 @@ if (Method != NMethodType::kCopy) { const char *m = NULL; - switch (Method) + switch ((int)Method) { case NMethodType::kDeflate: m = "zlib"; break; case NMethodType::kBZip2: m = "bzip2"; break; @@ -5451,7 +5513,7 @@ if (val != 0) { Script += "LicenseLangString "; - Add_LangStr_Simple(licenseLangIndex); + Add_LangStr_Simple((UInt32)licenseLangIndex); AddParam_UInt(langID); AddLicense(val, langID); noParseStringIndexes.AddToUniqueSorted(val); @@ -5470,7 +5532,7 @@ const UInt16 langID = Get16(p); if (i == 0 || langID == 1033) _mainLang = p + 10; - for (unsigned k = 0; k < ARRAY_SIZE(names) && k < numStrings; k++) + for (unsigned k = 0; k < Z7_ARRAY_SIZE(names) && k < numStrings; k++) { UInt32 v = Get32(p + 10 + k * 4); if (v != 0 && (langID == 1033 || names[k] == 0)) @@ -5567,7 +5629,7 @@ } onFuncOffset = paramsOffset + 40; - numOnFunc = ARRAY_SIZE(kOnFunc); + numOnFunc = Z7_ARRAY_SIZE(kOnFunc); if (bhPages.Offset == 276) numOnFunc--; p2 += 40 + numOnFunc * 4; @@ -5629,7 +5691,7 @@ #endif - RINOK(ReadEntries(bhEntries)); + RINOK(ReadEntries(bhEntries)) #ifdef NSIS_SCRIPT @@ -5747,14 +5809,14 @@ if (IsSolid) { - RINOK(SeekTo_DataStreamOffset()); + RINOK(SeekTo_DataStreamOffset()) } else { _headerIsCompressed = ((compressedHeaderSize & kMask_IsCompressed) != 0); compressedHeaderSize &= ~kMask_IsCompressed; _nonSolidStartOffset = compressedHeaderSize; - RINOK(SeekTo(DataStreamOffset + 4)); + RINOK(SeekTo(DataStreamOffset + 4)) } if (FirstHeader.HeaderSize == 0) @@ -5775,12 +5837,12 @@ if (_headerIsCompressed) { - RINOK(Decoder.Init(_stream, UseFilter)); + RINOK(Decoder.Init(_stream, UseFilter)) if (IsSolid) { size_t processedSize = 4; Byte buf[4]; - RINOK(Decoder.Read(buf, &processedSize)); + RINOK(Decoder.Read(buf, &processedSize)) if (processedSize != 4) return S_FALSE; if (Get32((const Byte *)buf) != FirstHeader.HeaderSize) @@ -5788,7 +5850,7 @@ } { size_t processedSize = FirstHeader.HeaderSize; - RINOK(Decoder.Read(_data, &processedSize)); + RINOK(Decoder.Read(_data, &processedSize)) if (processedSize != FirstHeader.HeaderSize) return S_FALSE; } @@ -5800,7 +5862,7 @@ AfterHeaderSize = (1 << 12); _afterHeader.Alloc(AfterHeaderSize); size_t processedSize = AfterHeaderSize; - RINOK(Decoder.Read(_afterHeader, &processedSize)); + RINOK(Decoder.Read(_afterHeader, &processedSize)) AfterHeaderSize = (UInt32)processedSize; } #endif @@ -5808,7 +5870,7 @@ else { size_t processedSize = FirstHeader.HeaderSize; - RINOK(ReadStream(_stream, (Byte *)_data, &processedSize)); + RINOK(ReadStream(_stream, (Byte *)_data, &processedSize)) if (processedSize < FirstHeader.HeaderSize) return S_FALSE; } @@ -5892,7 +5954,7 @@ { Clear(); - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &StartOffset)); + RINOK(InStream_GetPos(inStream, StartOffset)) const UInt32 kStartHeaderSize = 4 * 7; const unsigned kStep = 512; // nsis start is aligned for 512 @@ -5904,7 +5966,7 @@ for (;;) { bufSize = kStep; - RINOK(ReadStream(inStream, buf, &bufSize)); + RINOK(ReadStream(inStream, buf, &bufSize)) if (bufSize < kStartHeaderSize) return S_FALSE; if (memcmp(buf + 4, kSignature, kSignatureSize) == 0) @@ -5936,8 +5998,8 @@ if (pos - posCur > (1 << 20)) break; bufSize = kStep; - RINOK(inStream->Seek(posCur, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(inStream, buf, &bufSize)); + RINOK(InStream_SeekSet(inStream, posCur)) + RINOK(ReadStream(inStream, buf, &bufSize)) if (bufSize < kStep) break; if (IsArc_Pe(buf, bufSize)) @@ -5949,8 +6011,8 @@ // restore buf to nsis header bufSize = kStep; - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(inStream, buf, &bufSize)); + RINOK(InStream_SeekSet(inStream, pos)) + RINOK(ReadStream(inStream, buf, &bufSize)) if (bufSize < kStartHeaderSize) return S_FALSE; } @@ -5990,15 +6052,15 @@ } */ - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_fileSize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, _fileSize)) IsArc = true; if (peSize != 0) { ExeStub.Alloc(peSize); - RINOK(inStream->Seek(pePos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, ExeStub, peSize)); + RINOK(InStream_SeekSet(inStream, pePos)) + RINOK(ReadStream_FALSE(inStream, ExeStub, peSize)) } HRESULT res = S_FALSE; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.h 2021-11-18 08:25:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisIn.h 2023-12-11 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // NsisIn.h -#ifndef __ARCHIVE_NSIS_IN_H -#define __ARCHIVE_NSIS_IN_H +#ifndef ZIP7_INC_ARCHIVE_NSIS_IN_H +#define ZIP7_INC_ARCHIVE_NSIS_IN_H #include "../../../../C/CpuArch.h" @@ -11,6 +11,8 @@ #include "../../../Common/StringConvert.h" #include "../../../Common/UTFConvert.h" +#include "../../Common/StreamUtils.h" + #include "NsisDecode.h" /* If NSIS_SCRIPT is defined, it will decompile NSIS script to [NSIS].nsi file. @@ -68,6 +70,7 @@ struct CItem { + bool IsEmptyFile; bool IsCompressed; bool Size_Defined; bool CompressedSize_Defined; @@ -77,7 +80,7 @@ // bool UseFilter; UInt32 Attrib; - UInt32 Pos; + UInt32 Pos; // = 0, if (IsEmptyFile == true) UInt32 Size; UInt32 CompressedSize; UInt32 EstimatedSize; @@ -89,7 +92,10 @@ AString NameA; UString NameU; + bool Is_PatchedUninstaller() const { return PatchSize != 0; } + CItem(): + IsEmptyFile(false), IsCompressed(true), Size_Defined(false), CompressedSize_Defined(false), @@ -354,7 +360,7 @@ HRESULT SeekTo(UInt64 pos) { - return _stream->Seek(pos, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(_stream, pos); } HRESULT SeekTo_DataStreamOffset() @@ -410,7 +416,7 @@ s = MultiByteToUnicodeString(APrefixes[item.Prefix]); if (s.Len() > 0) if (s.Back() != L'\\') - s += '\\'; + s.Add_Char('\\'); } if (IsUnicode) @@ -433,7 +439,7 @@ if (s[0] == L'\\') s.DeleteFrontal(1); } - if (item.IsUninstaller && ExeStub.Size() == 0) + if (item.Is_PatchedUninstaller() && ExeStub.Size() == 0) s += ".nsis"; return s; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/NsisRegister.cpp 2015-02-11 09:22:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/NsisRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -10,7 +10,7 @@ namespace NNsis { REGISTER_ARC_I( - "Nsis", "nsis", 0, 0x9, + "Nsis", "nsis", NULL, 0x9, kSignature, 4, NArcInfoFlags::kFindSignature | diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Nsis/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Nsis/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/NtfsHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/NtfsHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/NtfsHandler.cpp 2022-05-01 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/NtfsHandler.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -47,9 +47,9 @@ #define Get32(p) GetUi32(p) #define Get64(p) GetUi64(p) -#define G16(p, dest) dest = Get16(p); -#define G32(p, dest) dest = Get32(p); -#define G64(p, dest) dest = Get64(p); +#define G16(p, dest) dest = Get16(p) +#define G32(p, dest) dest = Get32(p) +#define G64(p, dest) dest = Get64(p) using namespace NWindows; @@ -71,14 +71,15 @@ { unsigned SectorSizeLog; unsigned ClusterSizeLog; + unsigned MftRecordSizeLog; // Byte MediaType; - UInt32 NumHiddenSectors; + // UInt32 NumHiddenSectors; UInt64 NumSectors; UInt64 NumClusters; UInt64 MftCluster; UInt64 SerialNumber; - UInt16 SectorsPerTrack; - UInt16 NumHeads; + // UInt16 SectorsPerTrack; + // UInt16 NumHeads; UInt64 GetPhySize_Clusters() const { return NumClusters << ClusterSizeLog; } UInt64 GetPhySize_Max() const { return (NumSectors + 1) << SectorSizeLog; } @@ -111,30 +112,42 @@ if (memcmp(p + 3, "NTFS ", 8) != 0) return false; { - int t = GetLog(Get16(p + 11)); - if (t < 9 || t > 12) - return false; - SectorSizeLog = t; - t = GetLog(p[13]); - if (t < 0) - return false; - sectorsPerClusterLog = t; - ClusterSizeLog = SectorSizeLog + sectorsPerClusterLog; - if (ClusterSizeLog > 30) - return false; + { + const int t = GetLog(Get16(p + 11)); + if (t < 9 || t > 12) + return false; + SectorSizeLog = (unsigned)t; + } + { + const unsigned v = p[13]; + if (v <= 0x80) + { + const int t = GetLog(v); + if (t < 0) + return false; + sectorsPerClusterLog = (unsigned)t; + } + else + sectorsPerClusterLog = 0x100 - v; + ClusterSizeLog = SectorSizeLog + sectorsPerClusterLog; + if (ClusterSizeLog > 30) + return false; + } } for (int i = 14; i < 21; i++) if (p[i] != 0) return false; + // F8 : a hard disk + // F0 : high-density 3.5-inch floppy disk if (p[21] != 0xF8) // MediaType = Fixed_Disk return false; if (Get16(p + 22) != 0) // NumFatSectors return false; - G16(p + 24, SectorsPerTrack); // 63 usually - G16(p + 26, NumHeads); // 255 - G32(p + 28, NumHiddenSectors); // 63 (XP) / 2048 (Vista and win7) / (0 on media that are not partitioned ?) + // G16(p + 24, SectorsPerTrack); // 63 usually + // G16(p + 26, NumHeads); // 255 + // G32(p + 28, NumHiddenSectors); // 63 (XP) / 2048 (Vista and win7) / (0 on media that are not partitioned ?) if (Get32(p + 32) != 0) // NumSectors32 return false; @@ -156,14 +169,47 @@ NumClusters = NumSectors >> sectorsPerClusterLog; - G64(p + 0x30, MftCluster); + G64(p + 0x30, MftCluster); // $MFT. // G64(p + 0x38, Mft2Cluster); - G64(p + 0x48, SerialNumber); - UInt32 numClustersInMftRec; - UInt32 numClustersInIndexBlock; - G32(p + 0x40, numClustersInMftRec); // -10 means 2 ^10 = 1024 bytes. - G32(p + 0x44, numClustersInIndexBlock); - return (numClustersInMftRec < 256 && numClustersInIndexBlock < 256); + G64(p + 0x48, SerialNumber); // $MFTMirr + + /* + numClusters_per_MftRecord: + numClusters_per_IndexBlock: + only low byte from 4 bytes is used. Another 3 high bytes are zeros. + If the number is positive (number < 0x80), + then it represents the number of clusters. + If the number is negative (number >= 0x80), + then the size of the file record is 2 raised to the absolute value of this number. + example: (0xF6 == -10) means 2^10 = 1024 bytes. + */ + { + UInt32 numClusters_per_MftRecord; + G32(p + 0x40, numClusters_per_MftRecord); + if (numClusters_per_MftRecord >= 0x100 || numClusters_per_MftRecord == 0) + return false; + if (numClusters_per_MftRecord < 0x80) + { + const int t = GetLog(numClusters_per_MftRecord); + if (t < 0) + return false; + MftRecordSizeLog = (unsigned)t + ClusterSizeLog; + } + else + MftRecordSizeLog = 0x100 - numClusters_per_MftRecord; + // what exact MFT record sizes are possible and supported by Windows? + // do we need to change this limit here? + const unsigned k_MftRecordSizeLog_MAX = 12; + if (MftRecordSizeLog > k_MftRecordSizeLog_MAX) + return false; + if (MftRecordSizeLog < SectorSizeLog) + return false; + } + { + UInt32 numClusters_per_IndexBlock; + G32(p + 0x44, numClusters_per_IndexBlock); + return (numClusters_per_IndexBlock < 0x100); + } } struct CMftRef @@ -173,6 +219,8 @@ UInt64 GetIndex() const { return Val & (((UInt64)1 << 48) - 1); } UInt16 GetNumber() const { return (UInt16)(Val >> 48); } bool IsBaseItself() const { return Val == 0; } + + CMftRef(): Val(0) {} }; #define ATNAME(n) ATTR_TYPE_ ## n @@ -233,9 +281,14 @@ bool IsWin32() const { return (NameType == kFileNameType_Win32); } bool Parse(const Byte *p, unsigned size); + + CFileNameAttr(): + Attrib(0), + NameType(0) + {} }; -static void GetString(const Byte *p, unsigned len, UString2 &res) +static void GetString(const Byte *p, const unsigned len, UString2 &res) { if (len == 0 && res.IsEmpty()) return; @@ -243,7 +296,7 @@ unsigned i; for (i = 0; i < len; i++) { - wchar_t c = Get16(p + i * 2); + const wchar_t c = Get16(p + i * 2); if (c == 0) break; s[i] = c; @@ -266,8 +319,8 @@ G32(p + 0x38, Attrib); // G16(p + 0x3C, PackedEaSize); NameType = p[0x41]; - unsigned len = p[0x40]; - if (0x42 + len > size) + const unsigned len = p[0x40]; + if (0x42 + len * 2 > size) return false; if (len != 0) GetString(p + 0x42, len, Name); @@ -292,8 +345,18 @@ // UInt64 QuotaCharged; bool Parse(const Byte *p, unsigned size); + + CSiAttr(): + CTime(0), + MTime(0), + ThisRecMTime(0), + ATime(0), + Attrib(0), + SecurityId(0) + {} }; + bool CSiAttr::Parse(const Byte *p, unsigned size) { if (size < 0x24) @@ -382,13 +445,13 @@ } }; -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } static int CompareAttr(void *const *elem1, void *const *elem2, void *) { const CAttr &a1 = *(*((const CAttr *const *)elem1)); const CAttr &a2 = *(*((const CAttr *const *)elem2)); - RINOZ(MyCompare(a1.Type, a2.Type)); + RINOZ(MyCompare(a1.Type, a2.Type)) if (a1.Name.IsEmpty()) { if (!a2.Name.IsEmpty()) @@ -398,7 +461,7 @@ return 1; else { - RINOZ(a1.Name.Compare(a2.Name.GetRawPtr())); + RINOZ(a1.Name.Compare(a2.Name.GetRawPtr())) } return MyCompare(a1.LowVcn, a2.LowVcn); } @@ -520,11 +583,11 @@ while (size > 0) { - Byte b = *p++; + const unsigned b = *p++; size--; if (b == 0) break; - UInt32 num = b & 0xF; + unsigned num = b & 0xF; if (num == 0 || num > 8 || num > size) return false; @@ -544,7 +607,7 @@ e.Virt = vcn; vcn += vSize; - num = (b >> 4) & 0xF; + num = b >> 4; if (num > 8 || num > size) return false; @@ -575,7 +638,7 @@ } p += num; size -= num; - lcn += v; + lcn = (UInt64)((Int64)lcn + v); if (lcn > numClustersMax) return false; e.Phy = lcn; @@ -597,18 +660,17 @@ static const unsigned kNumCacheChunksLog = 1; static const size_t kNumCacheChunks = (size_t)1 << kNumCacheChunksLog; -class CInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CInStream +) UInt64 _virtPos; UInt64 _physPos; UInt64 _curRem; bool _sparseMode; - - +public: + bool InUse; +private: unsigned _chunkSizeLog; - UInt64 _tags[kNumCacheChunks]; CByteBuffer _inBuf; CByteBuffer _outBuf; public: @@ -617,12 +679,13 @@ unsigned BlockSizeLog; unsigned CompressionUnit; CRecordVector Extents; - bool InUse; CMyComPtr Stream; +private: + UInt64 _tags[kNumCacheChunks]; - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } - + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } UInt32 GetCuSize() const { return (UInt32)1 << (BlockSizeLog + CompressionUnit); } +public: HRESULT InitAndSeek(unsigned compressionUnit) { CompressionUnit = compressionUnit; @@ -645,11 +708,6 @@ _physPos = e.Phy << BlockSizeLog; return SeekToPhys(); } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte *src, size_t srcLen) @@ -737,7 +795,7 @@ return destSize; } -STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -827,7 +885,7 @@ if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } UInt64 next = Extents[i + 1].Virt; if (next > virtBlock2End) @@ -870,30 +928,30 @@ break; if (e.Virt >= virtBlock2End) return S_FALSE; - UInt64 newPos = (e.Phy + (curVirt - e.Virt)) << BlockSizeLog; + const UInt64 newPos = (e.Phy + (curVirt - e.Virt)) << BlockSizeLog; if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } UInt64 numChunks = Extents[i + 1].Virt - curVirt; if (curVirt + numChunks > virtBlock2End) numChunks = virtBlock2End - curVirt; - size_t compressed = (size_t)numChunks << BlockSizeLog; - RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed)); + const size_t compressed = (size_t)numChunks << BlockSizeLog; + RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed)) curVirt += numChunks; _physPos += compressed; offs += compressed; } - size_t destLenMax = GetCuSize(); + const size_t destLenMax = GetCuSize(); size_t destLen = destLenMax; const UInt64 rem = Size - (virtBlock2 << BlockSizeLog); if (destLen > rem) destLen = (size_t)rem; Byte *dest = _outBuf + (cacheIndex << _chunkSizeLog); - size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs); + const size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs); _tags[cacheIndex] = cacheTag; // some files in Vista have destSize > destLen @@ -922,7 +980,7 @@ return res; } -STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -936,10 +994,10 @@ if (_virtPos != (UInt64)offset) { _curRem = 0; - _virtPos = offset; + _virtPos = (UInt64)offset; } if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } @@ -1002,6 +1060,15 @@ static const UInt32 kMagic_FILE = 0x454C4946; static const UInt32 kMagic_BAAD = 0x44414142; +// 22.02: we support some rare case magic values: +static const UInt32 kMagic_INDX = 0x58444e49; +static const UInt32 kMagic_HOLE = 0x454c4f48; +static const UInt32 kMagic_RSTR = 0x52545352; +static const UInt32 kMagic_RCRD = 0x44524352; +static const UInt32 kMagic_CHKD = 0x444b4843; +static const UInt32 kMagic_FFFFFFFF = 0xFFFFFFFF; + + struct CMftRec { UInt32 Magic; @@ -1033,7 +1100,7 @@ { const CFileNameAttr &next = FileNames[i]; if (next.IsWin32() && cur.ParentDirRef.Val == next.ParentDirRef.Val) - return i; + return (int)i; } return -1; } @@ -1046,7 +1113,7 @@ { const CFileNameAttr &next = FileNames[i]; if (next.IsDos() && cur.ParentDirRef.Val == next.ParentDirRef.Val) - return i; + return (int)i; } return -1; } @@ -1078,9 +1145,25 @@ bool Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector *attrs); - bool IsEmpty() const { return (Magic <= 2); } - bool IsFILE() const { return (Magic == kMagic_FILE); } - bool IsBAAD() const { return (Magic == kMagic_BAAD); } + bool Is_Magic_Empty() const + { + // what exact Magic values are possible for empty and unused records? + const UInt32 k_Magic_Unused_MAX = 5; // 22.02 + return (Magic <= k_Magic_Unused_MAX); + } + bool Is_Magic_FILE() const { return (Magic == kMagic_FILE); } + // bool Is_Magic_BAAD() const { return (Magic == kMagic_BAAD); } + bool Is_Magic_CanIgnore() const + { + return Is_Magic_Empty() + || Magic == kMagic_BAAD + || Magic == kMagic_INDX + || Magic == kMagic_HOLE + || Magic == kMagic_RSTR + || Magic == kMagic_RCRD + || Magic == kMagic_CHKD + || Magic == kMagic_FFFFFFFF; + } bool InUse() const { return (Flags & 1) != 0; } bool IsDir() const { return (Flags & 2) != 0; } @@ -1092,7 +1175,11 @@ UInt64 GetSize(unsigned dataIndex) const { return DataAttrs[DataRefs[dataIndex].Start].GetSize(); } - CMftRec(): MyNumNameLinks(0), MyItemIndex(-1) {} + CMftRec(): + SeqNumber(0), + Flags(0), + MyNumNameLinks(0), + MyItemIndex(-1) {} }; void CMftRec::ParseDataNames() @@ -1115,7 +1202,7 @@ HRESULT CMftRec::GetStream(IInStream *mainStream, int dataIndex, unsigned clusterSizeLog, UInt64 numPhysClusters, IInStream **destStream) const { - *destStream = 0; + *destStream = NULL; CBufferInStream *streamSpec = new CBufferInStream; CMyComPtr streamTemp = streamSpec; @@ -1137,13 +1224,13 @@ return S_FALSE; CInStream *ss = new CInStream; CMyComPtr streamTemp2 = ss; - RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, ss->Extents)); + RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, ss->Extents)) ss->Size = attr0.Size; ss->InitializedSize = attr0.InitializedSize; ss->Stream = mainStream; ss->BlockSizeLog = clusterSizeLog; ss->InUse = InUse(); - RINOK(ss->InitAndSeek(attr0.CompressionUnit)); + RINOK(ss->InitAndSeek(attr0.CompressionUnit)) *destStream = streamTemp2.Detach(); return S_OK; } @@ -1189,9 +1276,8 @@ CObjectVector *attrs) { G32(p, Magic); - if (!IsFILE()) - return IsEmpty() || IsBAAD(); - + if (!Is_Magic_FILE()) + return Is_Magic_CanIgnore(); { UInt32 usaOffset; @@ -1228,7 +1314,7 @@ void *pp = p + (i << sectorSizeLog) - 2; if (Get16(pp) != usn) return false; - SetUi16(pp, Get16(p + usaOffset + i * 2)); + SetUi16(pp, Get16(p + usaOffset + i * 2)) } } @@ -1236,12 +1322,12 @@ G16(p + 0x10, SeqNumber); // G16(p + 0x12, LinkCount); // PRF(printf(" L=%d", LinkCount)); - UInt32 attrOffs = Get16(p + 0x14); + const UInt32 attrOffs = Get16(p + 0x14); G16(p + 0x16, Flags); PRF(printf(" F=%4X", Flags)); - UInt32 bytesInUse = Get32(p + 0x18); - UInt32 bytesAlloc = Get32(p + 0x1C); + const UInt32 bytesInUse = Get32(p + 0x18); + const UInt32 bytesAlloc = Get32(p + 0x1C); G64(p + 0x20, BaseMftRef.Val); if (BaseMftRef.Val != 0) { @@ -1362,7 +1448,6 @@ CObjectVector Recs; CMyComPtr InStream; CHeader Header; - unsigned RecSizeLog; UInt64 PhySize; IArchiveOpenCallback *OpenCallback; @@ -1374,6 +1459,9 @@ CByteBuffer SecurData; CRecordVector SecurOffsets; + // bool _headerWarning; + bool ThereAreAltStreams; + bool _showSystemFiles; bool _showDeletedFiles; CObjectVector VirtFolderNames; @@ -1383,10 +1471,6 @@ int _lostFolderIndex_Normal; int _lostFolderIndex_Deleted; - // bool _headerWarning; - - bool ThereAreAltStreams; - void InitProps() { _showSystemFiles = true; @@ -1406,7 +1490,7 @@ HRESULT SeekToCluster(UInt64 cluster); - int FindDirItemForMtfRec(UInt64 recIndex) const + int Find_DirItem_For_MftRec(UInt64 recIndex) const { if (recIndex >= Recs.Size()) return -1; @@ -1455,7 +1539,7 @@ HRESULT CDatabase::SeekToCluster(UInt64 cluster) { - return InStream->Seek(cluster << Header.ClusterSizeLog, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(InStream, cluster << Header.ClusterSizeLog); } void CDatabase::Clear() @@ -1702,14 +1786,14 @@ */ { - static const UInt32 kHeaderSize = 512; + const UInt32 kHeaderSize = 512; Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)) if (!Header.Parse(buf)) return S_FALSE; UInt64 fileSize; - RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(InStream, fileSize)) PhySize = Header.GetPhySize_Clusters(); if (fileSize < PhySize) return S_FALSE; @@ -1717,7 +1801,7 @@ UInt64 phySizeMax = Header.GetPhySize_Max(); if (fileSize >= phySizeMax) { - RINOK(InStream->Seek(Header.NumSectors << Header.SectorSizeLog, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(InStream, Header.NumSectors << Header.SectorSizeLog)) Byte buf2[kHeaderSize]; if (ReadStream_FALSE(InStream, buf2, kHeaderSize) == S_OK) { @@ -1730,59 +1814,48 @@ SeekToCluster(Header.MftCluster); - CMftRec mftRec; - UInt32 numSectorsInRec; - + // we use ByteBuf for records reading. + // so the size of ByteBuf must be >= mftRecordSize + const size_t recSize = (size_t)1 << Header.MftRecordSizeLog; + const size_t kBufSize = MyMax((size_t)(1 << 15), recSize); + ByteBuf.Alloc(kBufSize); + RINOK(ReadStream_FALSE(InStream, ByteBuf, recSize)) + { + const UInt32 allocSize = Get32(ByteBuf + 0x1C); + if (allocSize != recSize) + return S_FALSE; + } + // MftRecordSizeLog >= SectorSizeLog + const UInt32 numSectorsInRec = 1u << (Header.MftRecordSizeLog - Header.SectorSizeLog); CMyComPtr mftStream; + CMftRec mftRec; { - UInt32 blockSize = 1 << 12; - ByteBuf.Alloc(blockSize); - RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)); - - { - UInt32 allocSize = Get32(ByteBuf + 0x1C); - int t = GetLog(allocSize); - if (t < (int)Header.SectorSizeLog) - return S_FALSE; - RecSizeLog = t; - if (RecSizeLog > 15) - return S_FALSE; - } - - numSectorsInRec = 1 << (RecSizeLog - Header.SectorSizeLog); if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, 0, NULL)) return S_FALSE; - if (!mftRec.IsFILE()) + if (!mftRec.Is_Magic_FILE()) return S_FALSE; mftRec.ParseDataNames(); if (mftRec.DataRefs.IsEmpty()) return S_FALSE; - RINOK(mftRec.GetStream(InStream, 0, Header.ClusterSizeLog, Header.NumClusters, &mftStream)); + RINOK(mftRec.GetStream(InStream, 0, Header.ClusterSizeLog, Header.NumClusters, &mftStream)) if (!mftStream) return S_FALSE; } // CObjectVector SecurityAttrs; - UInt64 mftSize = mftRec.DataAttrs[0].Size; + const UInt64 mftSize = mftRec.DataAttrs[0].Size; if ((mftSize >> 4) > Header.GetPhySize_Clusters()) return S_FALSE; - const size_t kBufSize = (1 << 15); - const size_t recSize = ((size_t)1 << RecSizeLog); - if (kBufSize < recSize) - return S_FALSE; - { - const UInt64 numFiles = mftSize >> RecSizeLog; + const UInt64 numFiles = mftSize >> Header.MftRecordSizeLog; if (numFiles > (1 << 30)) return S_FALSE; if (OpenCallback) { - RINOK(OpenCallback->SetTotal(&numFiles, &mftSize)); + RINOK(OpenCallback->SetTotal(&numFiles, &mftSize)) } - - ByteBuf.Alloc(kBufSize); Recs.ClearAndReserve((unsigned)numFiles); } @@ -1791,9 +1864,9 @@ if (OpenCallback) { const UInt64 numFiles = Recs.Size(); - if ((numFiles & 0x3FF) == 0) + if ((numFiles & 0x3FFF) == 0) { - RINOK(OpenCallback->SetCompleted(&numFiles, &pos64)); + RINOK(OpenCallback->SetCompleted(&numFiles, &pos64)) } } size_t readSize = kBufSize; @@ -1804,7 +1877,7 @@ } if (readSize < recSize) break; - RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize)); + RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize)) pos64 += readSize; for (size_t i = 0; readSize >= recSize; i += recSize, readSize -= recSize) @@ -1834,7 +1907,7 @@ for (i = 0; i < SecurityAttrs.Size(); i++) { const CAttr &attr = SecurityAttrs[i]; - if (attr.Name == L"$SII") + if (attr.Name.IsEqualTo("$SII")) { if (attr.Type == ATTR_TYPE_INDEX_ROOT) { @@ -1880,12 +1953,18 @@ for (i = 0; i < Recs.Size(); i++) { CMftRec &rec = Recs[i]; + if (!rec.Is_Magic_FILE()) + continue; + if (!rec.BaseMftRef.IsBaseItself()) { - UInt64 refIndex = rec.BaseMftRef.GetIndex(); - if (refIndex > (UInt32)Recs.Size()) + const UInt64 refIndex = rec.BaseMftRef.GetIndex(); + if (refIndex >= Recs.Size()) return S_FALSE; CMftRec &refRec = Recs[(unsigned)refIndex]; + if (!refRec.Is_Magic_FILE()) + continue; + bool moveAttrs = (refRec.SeqNumber == rec.BaseMftRef.GetNumber() && refRec.BaseMftRef.IsBaseItself()); if (rec.InUse() && refRec.InUse()) { @@ -1900,12 +1979,17 @@ } for (i = 0; i < Recs.Size(); i++) - Recs[i].ParseDataNames(); + { + CMftRec &rec = Recs[i]; + if (!rec.Is_Magic_FILE()) + continue; + rec.ParseDataNames(); + } for (i = 0; i < Recs.Size(); i++) { CMftRec &rec = Recs[i]; - if (!rec.IsFILE() || !rec.BaseMftRef.IsBaseItself()) + if (!rec.Is_Magic_FILE() || !rec.BaseMftRef.IsBaseItself()) continue; if (i < kNumSysRecs && !_showSystemFiles) continue; @@ -1927,7 +2011,7 @@ FOR_VECTOR (di, rec.DataRefs) if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty()) { - indexOfUnnamedStream = di; + indexOfUnnamedStream = (int)di; break; } } @@ -1985,14 +2069,14 @@ indexOfUnnamedStream); if (rec.MyItemIndex < 0) - rec.MyItemIndex = Items.Size(); - item.ParentHost = Items.Add(item); + rec.MyItemIndex = (int)Items.Size(); + item.ParentHost = (int)Items.Add(item); /* we can use that code to reduce the number of alt streams: it will not show how alt streams for hard links. */ // if (!isMainName) continue; isMainName = false; - unsigned numAltStreams = 0; + // unsigned numAltStreams = 0; FOR_VECTOR (di, rec.DataRefs) { @@ -2010,9 +2094,9 @@ continue; } - numAltStreams++; + // numAltStreams++; ThereAreAltStreams = true; - item.DataIndex = di; + item.DataIndex = (int)di; Items.Add(item); } } @@ -2027,10 +2111,10 @@ if (attr.Name == L"$SDS") { CMyComPtr sdsStream; - RINOK(rec.GetStream(InStream, di, Header.ClusterSizeLog, Header.NumClusters, &sdsStream)); + RINOK(rec.GetStream(InStream, (int)di, Header.ClusterSizeLog, Header.NumClusters, &sdsStream)) if (sdsStream) { - UInt64 size64 = attr.GetSize(); + const UInt64 size64 = attr.GetSize(); if (size64 < (UInt32)1 << 29) { size_t size = (size_t)size64; @@ -2060,12 +2144,12 @@ const CMftRec &rec = Recs[item.RecIndex]; const CFileNameAttr &fn = rec.FileNames[item.NameIndex]; const CMftRef &parentDirRef = fn.ParentDirRef; - UInt64 refIndex = parentDirRef.GetIndex(); + const UInt64 refIndex = parentDirRef.GetIndex(); if (refIndex == kRecIndex_RootDir) item.ParentFolder = -1; else { - int index = FindDirItemForMtfRec(refIndex); + int index = Find_DirItem_For_MftRec(refIndex); if (index < 0 || Recs[Items[index].RecIndex].SeqNumber != parentDirRef.GetNumber()) { @@ -2087,57 +2171,52 @@ unsigned virtIndex = Items.Size(); if (_showSystemFiles) { - _systemFolderIndex = virtIndex++; + _systemFolderIndex = (int)(virtIndex++); VirtFolderNames.Add(kVirtualFolder_System); } if (thereAreUnknownFolders_Normal) { - _lostFolderIndex_Normal = virtIndex++; + _lostFolderIndex_Normal = (int)(virtIndex++); VirtFolderNames.Add(kVirtualFolder_Lost_Normal); } if (thereAreUnknownFolders_Deleted) { - _lostFolderIndex_Deleted = virtIndex++; + _lostFolderIndex_Deleted = (int)(virtIndex++); VirtFolderNames.Add(kVirtualFolder_Lost_Deleted); } return S_OK; } -class CHandler: +Z7_class_CHandler_final: public IInArchive, public IArchiveGetRawProps, public IInArchiveGetStream, public ISetProperties, public CMyUnknownImp, - CDatabase + public CDatabase { -public: - MY_UNKNOWN_IMP4( + Z7_IFACES_IMP_UNK_4( IInArchive, IArchiveGetRawProps, IInArchiveGetStream, ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); }; -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { *numProps = 2; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) { *name = NULL; *propID = index == 0 ? kpidNtReparse : kpidNtSecure; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; int par = -1; @@ -2167,7 +2246,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -2236,10 +2315,10 @@ return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; if (index >= Items.Size()) return S_OK; IInStream *stream2; @@ -2323,7 +2402,7 @@ { NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidClusterSize, VT_UI4}, { NULL, kpidSectorSize, VT_UI4}, - { "Record Size", kpidRecordSize, VT_UI4}, + { "MFT Record Size", kpidRecordSize, VT_UI4}, { NULL, kpidHeadersSize, VT_UI8}, { NULL, kpidCTime, VT_FILETIME}, { NULL, kpidId, VT_UI8}, @@ -2357,7 +2436,7 @@ prop = ft; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -2415,7 +2494,7 @@ { s.Add_Space(); s.Add_UInt32(vi.MajorVer); - s += '.'; + s.Add_Dot(); s.Add_UInt32(vi.MinorVer); } break; @@ -2425,7 +2504,7 @@ break; } case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; - case kpidRecordSize: prop = (UInt32)1 << RecSizeLog; break; + case kpidRecordSize: prop = (UInt32)1 << Header.MftRecordSizeLog; break; case kpidId: prop = Header.SerialNumber; break; case kpidIsTree: prop = true; break; @@ -2461,7 +2540,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -2529,7 +2608,7 @@ { // const CMftRec &rec = Recs[item.RecIndex]; // prop = ((UInt64)rec.SeqNumber << 48) | item.RecIndex; - prop = item.RecIndex; + prop = (UInt32)item.RecIndex; break; } case kpidStreamId: @@ -2622,7 +2701,7 @@ if (!rec.IsDir() && rec.DataAttrs[rec.DataRefs[0].Start].Name.IsEmpty()) num--; if (num > 0) - prop = num; + prop = (UInt32)num; } } break; @@ -2637,7 +2716,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { @@ -2661,17 +2740,17 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { ClearAndClose(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = Items.Size(); if (numItems == 0) @@ -2680,15 +2759,15 @@ UInt64 totalSize = 0; for (i = 0; i < numItems; i++) { - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; if (index >= (UInt32)Items.Size()) continue; const CItem &item = Items[allFilesMode ? i : indices[i]]; const CMftRec &rec = Recs[item.RecIndex]; if (item.DataIndex >= 0) - totalSize += rec.GetSize(item.DataIndex); + totalSize += rec.GetSize((unsigned)item.DataIndex); } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 totalPackSize; totalSize = totalPackSize = 0; @@ -2696,32 +2775,30 @@ UInt32 clusterSize = Header.ClusterSize(); CByteBuffer buf(clusterSize); - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create outStream; - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; + CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (index >= (UInt32)Items.Size() || Items[index].IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -2729,11 +2806,11 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) - outStreamSpec->SetStream(realOutStream); + outStream->SetStream(realOutStream); realOutStream.Release(); - outStreamSpec->Init(); + outStream->Init(); const CMftRec &rec = Recs[item.RecIndex]; @@ -2745,13 +2822,13 @@ res = NExtract::NOperationResult::kUnsupportedMethod; else { - RINOK(hres); + RINOK(hres) if (inStream) { - hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + hres = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); if (hres != S_OK && hres != S_FALSE) { - RINOK(hres); + RINOK(hres) } if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK) res = NExtract::NOperationResult::kOK; @@ -2764,20 +2841,20 @@ totalPackSize += data.GetPackSize(); totalSize += data.GetSize(); } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(res)); + outStream->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = Items.Size() + VirtFolderNames.Size(); return S_OK; } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { InitProps(); @@ -2788,11 +2865,17 @@ if (StringsAreEqualNoCase_Ascii(name, "ld")) { - RINOK(PROPVARIANT_to_bool(prop, _showDeletedFiles)); + RINOK(PROPVARIANT_to_bool(prop, _showDeletedFiles)) } else if (StringsAreEqualNoCase_Ascii(name, "ls")) { - RINOK(PROPVARIANT_to_bool(prop, _showSystemFiles)); + RINOK(PROPVARIANT_to_bool(prop, _showSystemFiles)) + } + else if (IsString1PrefixedByString2_NoCase_Ascii(name, "mt")) + { + } + else if (IsString1PrefixedByString2_NoCase_Ascii(name, "memuse")) + { } else return E_INVALIDARG; @@ -2803,7 +2886,7 @@ static const Byte k_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; REGISTER_ARC_I( - "NTFS", "ntfs img", 0, 0xD9, + "NTFS", "ntfs img", NULL, 0xD9, k_Signature, 3, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/PeHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PeHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/PeHandler.cpp 2022-02-14 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PeHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -28,9 +28,10 @@ #define G16(offs, v) v = Get16(p + (offs)) #define G32(offs, v) v = Get32(p + (offs)) +#define G32_signed(offs, v) v = (Int32)Get32(p + (offs)) #define G64(offs, v) v = Get64(p + (offs)) -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } using namespace NWindows; @@ -55,7 +56,7 @@ if (rem == 0) break; size_t processed = rem; - RINOK(ReadStream(stream, buf, &processed)); + RINOK(ReadStream(stream, buf, &processed)) for (unsigned j = 0; j < 4; j++) { @@ -179,9 +180,32 @@ } }; + +// IMAGE_DIRECTORY_ENTRY_* +static const char * const g_Dir_Names[] = +{ + "EXPORT" + , "IMPORT" + , "RESOURCE" + , "EXCEPTION" + , "SECURITY" + , "BASERELOC" + , "DEBUG" + , "ARCHITECTURE" // "COPYRIGHT" + , "GLOBALPTR" + , "TLS" + , "LOAD_CONFIG" + , "BOUND_IMPORT" + , "IAT" + , "DELAY_IMPORT" + , "COM_DESCRIPTOR" +}; + enum { + kDirLink_EXCEPTION = 3, kDirLink_Certificate = 4, + kDirLink_BASERELOC = 5, kDirLink_Debug = 6 }; @@ -228,7 +252,7 @@ UInt32 UninitDataSize; // UInt32 AddressOfEntryPoint; - // UInt32 BaseOfCode; + // UInt32 BaseOfCode; // VA(.text) == 0x1000 in most cases // UInt32 BaseOfData32; UInt64 ImageBase; @@ -258,9 +282,9 @@ int GetNumFileAlignBits() const { - for (unsigned i = 0; i <= 31; i++) + for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == FileAlign) - return i; + return (int)i; return -1; } @@ -272,6 +296,7 @@ } }; +// size is 16-bit bool COptHeader::Parse(const Byte *p, UInt32 size) { if (size < k_OptHeader32_Size_MIN) @@ -333,13 +358,18 @@ pos = 92; } - G32(pos, NumDirItems); - if (NumDirItems > (1 << 16)) + UInt32 numDirItems; + G32(pos, numDirItems); + NumDirItems = numDirItems; + if (numDirItems > (1 << 13)) return false; pos += 4; - if (pos + 8 * NumDirItems > size) + if (pos + 8 * numDirItems > size) return false; - for (UInt32 i = 0; i < NumDirItems && i < kNumDirItemsMax; i++) + memset((void *)DirItems, 0, sizeof(DirItems)); + if (numDirItems > kNumDirItemsMax) + numDirItems = kNumDirItemsMax; + for (UInt32 i = 0; i < numDirItems; i++) DirItems[i].Parse(p + pos + i * 8); return true; } @@ -350,36 +380,50 @@ { AString Name; + UInt32 ExtractSize; UInt32 VSize; UInt32 Va; UInt32 PSize; UInt32 Pa; UInt32 Flags; UInt32 Time; - // UInt16 NumRelocs; + // UInt16 NumRelocs; // is set to zero for executable images bool IsRealSect; bool IsDebug; bool IsAdditionalSection; - CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} + CSection(): + ExtractSize(0), + IsRealSect(false), + IsDebug(false), + IsAdditionalSection(false) + // , NumRelocs(0) + {} - UInt32 GetSizeExtract() const { return PSize; } - UInt32 GetSizeMin() const { return MyMin(PSize, VSize); } + void Set_Size_for_all(UInt32 size) + { + PSize = VSize = ExtractSize = size; + } + + UInt32 GetSize_Extract() const + { + return ExtractSize; + } void UpdateTotalSize(UInt32 &totalSize) const { - UInt32 t = Pa + PSize; + const UInt32 t = Pa + PSize; if (totalSize < t) - totalSize = t; + totalSize = t; } void Parse(const Byte *p); int Compare(const CSection &s) const { - RINOZ(MyCompare(Pa, s.Pa)); - UInt32 size1 = GetSizeExtract(); - UInt32 size2 = s.GetSizeExtract(); + RINOZ(MyCompare(Pa, s.Pa)) + const UInt32 size1 = GetSize_Extract(); + const UInt32 size2 = s.GetSize_Extract(); return MyCompare(size1, size2); } }; @@ -400,6 +444,10 @@ G32(20, Pa); // G16(32, NumRelocs); G32(36, Flags); + // v24.08: we extract only useful data (without extra padding bytes). + // VSize == 0 is not expected, but we support that case too. + // return (VSize && VSize < PSize) ? VSize : PSize; + ExtractSize = (VSize && VSize < PSize) ? VSize : PSize; } @@ -506,6 +554,7 @@ { 0x01D3, "AM33" }, { 0x01F0, "PPC" }, { 0x01F1, "PPC-FP" }, + { 0x01F2, "PPC-BE" }, { 0x0200, "IA-64" }, { 0x0266, "MIPS-16" }, { 0x0284, "Alpha-64" }, @@ -514,8 +563,15 @@ { 0x0520, "TriCore" }, { 0x0CEF, "CEF" }, { 0x0EBC, "EFI" }, + { 0x5032, "RISCV32" }, + { 0x5064, "RISCV64" }, +// { 0x5128, "RISCV128" }, + { 0x6232, "LOONGARCH32" }, + { 0x6264, "LOONGARCH64" }, { 0x8664, "x64" }, { 0x9041, "M32R" }, + { 0xA641, "ARM64EC" }, + { 0xA64e, "ARM64X" }, { 0xAA64, "ARM64" }, { 0xC0EE, "CEE" } }; @@ -613,7 +669,7 @@ size_t FinalSize() const { return Buf.GetPos(); } - void AddChar(Byte c); + void AddChar(char c); void AddWChar(UInt16 c); void AddWChar_Smart(UInt16 c); void NewLine(); @@ -638,17 +694,17 @@ } }; -void CTextFile::AddChar(Byte c) +void CTextFile::AddChar(char c) { Byte *p = Buf.GetCurPtrAndGrow(2); - p[0] = c; + p[0] = (Byte)c; p[1] = 0; } void CTextFile::AddWChar(UInt16 c) { Byte *p = Buf.GetCurPtrAndGrow(2); - SetUi16(p, c); + SetUi16(p, c) } void CTextFile::AddWChar_Smart(UInt16 c) @@ -743,12 +799,11 @@ UString Value; }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public IArchiveAllowTail, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IInArchiveGetStream, + IArchiveAllowTail +) CMyComPtr _stream; CObjectVector _sections; CHeader _header; @@ -770,6 +825,7 @@ CUsedBitmap _usedRes; // bool _parseResources; bool _checksumError; + bool _sectionsError; bool IsOpt() const { return _header.OptHeaderSize != 0; } @@ -800,11 +856,6 @@ _coffMode(coffMode), _allowTail(coffMode) {} - - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(AllowTail)(Int32 allowTail); }; @@ -826,11 +877,11 @@ kpidStackReserve, kpidStackCommit, kpidHeapReserve, - kpidHeapCommit, - kpidImageBase - // kpidAddressOfEntryPoint, - // kpidBaseOfCode, - // kpidBaseOfData32, + kpidHeapCommit + // , kpidImageBase + // , kpidAddressOfEntryPoint + // , kpidBaseOfCode + // , kpidBaseOfData32 }; static const CStatProp kArcProps[] = @@ -860,14 +911,16 @@ { "Stack Commit", kpidStackCommit, VT_UI8}, { "Heap Reserve", kpidHeapReserve, VT_UI8}, { "Heap Commit", kpidHeapCommit, VT_UI8}, - { "Image Base", kpidImageBase, VT_UI8}, - { NULL, kpidComment, VT_BSTR}, + { NULL, kpidVa, VT_UI8 }, // "Image Base", kpidImageBase, VT_UI8 + { NULL, kpidComment, VT_BSTR} - // { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, - // { "Base Of Code", kpidBaseOfCode, VT_UI8}, - // { "Base Of Data", kpidBaseOfData32, VT_UI8}, + // , { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8} + // , { "Base Of Code", kpidBaseOfCode, VT_UI8} + // , { "Base Of Data", kpidBaseOfData32, VT_UI8} }; +// #define kpid_NumRelocs 250 + static const Byte kProps[] = { kpidPath, @@ -876,7 +929,8 @@ kpidVirtualSize, kpidCharacts, kpidOffset, - kpidVa, + kpidVa + // , kpid_NumRelocs }; IMP_IInArchive_Props @@ -888,14 +942,49 @@ PropVariant_SetFrom_UnixTime(prop, unixTime); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; switch (propID) { case kpidPhySize: prop = _totalSize; break; - case kpidComment: if (!_versionFullString.IsEmpty()) prop = _versionFullString; break; + case kpidComment: + { + UString s (_versionFullString); + s.Add_LF(); + s += "Data Directories: "; + s.Add_UInt32(_optHeader.NumDirItems); + s.Add_LF(); + s.Add_Char('{'); + s.Add_LF(); + for (unsigned i = 0; i < _optHeader.NumDirItems + && i < Z7_ARRAY_SIZE(_optHeader.DirItems); i++) + { + const CDirLink &di = _optHeader.DirItems[i]; + if (di.Va == 0 && di.Size == 0) + continue; + s += "index="; + s.Add_UInt32(i); + + if (i < Z7_ARRAY_SIZE(g_Dir_Names)) + { + s += " name="; + s += g_Dir_Names[i]; + } + s += " VA=0x"; + char temp[16]; + ConvertUInt32ToHex(di.Va, temp); + s += temp; + s += " Size="; + s.Add_UInt32(di.Size); + s.Add_LF(); + } + s.Add_Char('}'); + s.Add_LF(); + prop = s; + break; + } case kpidShortComment: if (!_versionShortString.IsEmpty()) prop = _versionShortString; @@ -911,6 +1000,15 @@ // case kpidError: case kpidWarning: if (_checksumError) prop = "Checksum error"; break; + case kpidWarningFlags: + { + UInt32 v = 0; + if (_sectionsError) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; case kpidMTime: case kpidCTime: TimeToProp(_header.Time, prop); break; @@ -956,8 +1054,7 @@ case kpidStackCommit: prop = _optHeader.StackCommit; break; case kpidHeapReserve: prop = _optHeader.HeapReserve; break; case kpidHeapCommit: prop = _optHeader.HeapCommit; break; - - case kpidImageBase: prop = _optHeader.ImageBase; break; + case kpidVa: prop = _optHeader.ImageBase; break; // kpidImageBase: // case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break; // case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break; // case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break; @@ -1029,7 +1126,7 @@ } } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -1081,7 +1178,7 @@ AddLangPrefix(s, item.Lang); { const char *p = NULL; - if (item.Type < ARRAY_SIZE(g_ResTypes)) + if (item.Type < Z7_ARRAY_SIZE(g_ResTypes)) p = g_ResTypes[item.Type]; if (p) s += p; @@ -1109,8 +1206,16 @@ const CSection &item = _sections[mixItem.SectionIndex]; switch (propID) { - case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; - case kpidSize: prop = (UInt64)item.PSize; break; + case kpidPath: + { + AString s = item.Name; + s.Replace('/', '_'); + s.Replace('\\', '_'); + prop = MultiByteToUnicodeString(s); + break; + } + case kpidSize: prop = (UInt64)item.GetSize_Extract(); break; + // case kpid_NumRelocs: prop = (UInt32)item.NumRelocs; break; case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidOffset: prop = item.Pa; break; @@ -1122,8 +1227,8 @@ if (item.IsRealSect) { UInt32 flags = item.Flags; - const UInt32 MY__IMAGE_SCN_ALIGN_MASK = 0x00F00000; - AString s = FlagsToString(g_SectFlags, ARRAY_SIZE(g_SectFlags), item.Flags & ~MY__IMAGE_SCN_ALIGN_MASK); + const UInt32 MY_IMAGE_SCN_ALIGN_MASK = 0x00F00000; + AString s = FlagsToString(g_SectFlags, Z7_ARRAY_SIZE(g_SectFlags), item.Flags & ~MY_IMAGE_SCN_ALIGN_MASK); const UInt32 align = ((flags >> 20) & 0xF); if (align != 0) { @@ -1185,8 +1290,8 @@ CByteBuffer buffer(debugLink.Size); Byte *buf = buffer; - RINOK(stream->Seek(pa, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, debugLink.Size)); + RINOK(InStream_SeekSet(stream, pa)) + RINOK(ReadStream_FALSE(stream, buf, debugLink.Size)) for (i = 0; i < numItems; i++) { @@ -1209,7 +1314,7 @@ sect.Time = de.Time; sect.Va = de.Va; sect.Pa = de.Pa; - sect.PSize = sect.VSize = de.Size; + sect.Set_Size_for_all(de.Size); } buf += kEntrySize; } @@ -1271,7 +1376,7 @@ if (size < kBitmapInfoHeader_Size || Get32(p) != kBitmapInfoHeader_Size) return false; G32( 4, XSize); - G32( 8, YSize); + G32_signed( 8, YSize); G16(12, Planes); G16(14, BitCount); G32(16, Compression); @@ -1291,21 +1396,24 @@ return 0; if (h.YSize < 0) h.YSize = -h.YSize; - if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || h.BitCount > 32) + if (h.XSize > (1 << 26) + || h.YSize > (1 << 26) + || h.YSize < 0 + || h.Planes != 1 || h.BitCount > 32) return 0; if (h.SizeImage == 0) { if (h.Compression != 0) // BI_RGB return 0; - h.SizeImage = GetImageSize(h.XSize, h.YSize, h.BitCount); + h.SizeImage = GetImageSize(h.XSize, (UInt32)h.YSize, h.BitCount); } UInt32 totalSize = kBmpHeaderSize + size; UInt32 offBits = totalSize - h.SizeImage; // BITMAPFILEHEADER - SetUi16(dest, 0x4D42); - SetUi32(dest + 2, totalSize); - SetUi32(dest + 6, 0); - SetUi32(dest + 10, offBits); + SetUi16(dest, 0x4D42) + SetUi32(dest + 2, totalSize) + SetUi32(dest + 6, 0) + SetUi32(dest + 10, offBits) return kBmpHeaderSize; } @@ -1316,11 +1424,14 @@ return 0; if (h.YSize < 0) h.YSize = -h.YSize; - if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || - h.Compression != 0) // BI_RGB + if (h.XSize > (1 << 26) + || h.YSize > (1 << 26) + || h.YSize < 0 + || h.Planes != 1 + || h.Compression != 0) // BI_RGB return 0; - UInt32 numBitCount = h.BitCount; + const UInt32 numBitCount = h.BitCount; if (numBitCount != 1 && numBitCount != 4 && numBitCount != 8 && @@ -1341,29 +1452,29 @@ // UInt32 imageSize = h.SizeImage; // if (imageSize == 0) // { - UInt32 image1Size = GetImageSize(h.XSize, h.YSize, h.BitCount); - UInt32 image2Size = GetImageSize(h.XSize, h.YSize, 1); + const UInt32 image1Size = GetImageSize(h.XSize, (UInt32)h.YSize, h.BitCount); + const UInt32 image2Size = GetImageSize(h.XSize, (UInt32)h.YSize, 1); imageSize = image1Size + image2Size; // } UInt32 numColors = 0; if (numBitCount < 16) numColors = 1 << numBitCount; - SetUi16(dest, 0); // Reserved - SetUi16(dest + 2, 1); // RES_ICON - SetUi16(dest + 4, 1); // ResCount + SetUi16(dest, 0) // Reserved + SetUi16(dest + 2, 1) // RES_ICON + SetUi16(dest + 4, 1) // ResCount dest[6] = (Byte)h.XSize; // Width dest[7] = (Byte)h.YSize; // Height dest[8] = (Byte)numColors; // ColorCount dest[9] = 0; // Reserved - SetUi32(dest + 10, 0); // Reserved1 / Reserved2 + SetUi32(dest + 10, 0) // Reserved1 / Reserved2 UInt32 numQuadsBytes = numColors * 4; UInt32 BytesInRes = kBitmapInfoHeader_Size + numQuadsBytes + imageSize; - SetUi32(dest + 14, BytesInRes); - SetUi32(dest + 18, kIconHeaderSize); + SetUi32(dest + 14, BytesInRes) + SetUi32(dest + 18, kIconHeaderSize) /* Description = DWORDToString(xSize) + @@ -1500,9 +1611,9 @@ static void PrintVersion(UString &s, UInt32 ms, UInt32 ls) { - PrintUInt32(s, HIWORD(ms)); s += '.'; - PrintUInt32(s, LOWORD(ms)); s += '.'; - PrintUInt32(s, HIWORD(ls)); s += '.'; + PrintUInt32(s, HIWORD(ms)); s.Add_Dot(); + PrintUInt32(s, LOWORD(ms)); s.Add_Dot(); + PrintUInt32(s, HIWORD(ls)); s.Add_Dot(); PrintUInt32(s, LOWORD(ls)); } @@ -1590,7 +1701,7 @@ { FOR_VECTOR (i, v) if (v[i].Key.IsEqualTo(key)) - return i; + return (int)i; return -1; } @@ -1642,7 +1753,7 @@ f.AddString("FILEFLAGS "); { bool wasPrinted = false; - for (unsigned i = 0; i < ARRAY_SIZE(k_VS_FileFlags); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_VS_FileFlags); i++) { if ((Flags & ((UInt32)1 << i)) != 0) { @@ -1653,7 +1764,7 @@ wasPrinted = true; } } - UInt32 v = Flags & ~(((UInt32)1 << ARRAY_SIZE(k_VS_FileFlags)) - 1); + UInt32 v = Flags & ~(((UInt32)1 << Z7_ARRAY_SIZE(k_VS_FileFlags)) - 1); if (v != 0 || !wasPrinted) { if (wasPrinted) @@ -1666,7 +1777,7 @@ // OS = 0x111230; f.AddString("FILEOS "); unsigned i; - for (i = 0; i < ARRAY_SIZE(k_VS_FileOS); i++) + for (i = 0; i < Z7_ARRAY_SIZE(k_VS_FileOS); i++) { const CUInt32PCharPair &pair = k_VS_FileOS[i]; if (OS == pair.Value) @@ -1677,10 +1788,10 @@ break; } } - if (i == ARRAY_SIZE(k_VS_FileOS)) + if (i == Z7_ARRAY_SIZE(k_VS_FileOS)) { UInt32 high = OS >> 16; - if (high < ARRAY_SIZE(k_VS_FileOS_High)) + if (high < Z7_ARRAY_SIZE(k_VS_FileOS_High)) f.AddString(k_VS_FileOS_High[high]); else PrintHex(f, high << 16); @@ -1688,7 +1799,7 @@ if (low != 0) { f.AddString(" | "); - if (low < ARRAY_SIZE(k_VS_FileOS_Low)) + if (low < Z7_ARRAY_SIZE(k_VS_FileOS_Low)) f.AddString(k_VS_FileOS_Low[low]); else PrintHex(f, low); @@ -1697,7 +1808,7 @@ f.NewLine(); f.AddString("FILETYPE "); - if (Type < ARRAY_SIZE(k_VS_FileType)) + if (Type < Z7_ARRAY_SIZE(k_VS_FileType)) f.AddString(k_VS_FileType[Type]); else PrintHex(f, Type); @@ -1707,7 +1818,7 @@ bool needPrintSubType = true; if (Type == kMY_VFT_DRV) { - if (Subtype != 0 && Subtype < ARRAY_SIZE(k_VS_FileSubType_DRV)) + if (Subtype != 0 && Subtype < Z7_ARRAY_SIZE(k_VS_FileSubType_DRV)) { f.AddString("VFT2_DRV_"); f.AddString(k_VS_FileSubType_DRV[Subtype]); @@ -1716,7 +1827,7 @@ } else if (Type == kMY_VFT_FONT) { - if (Subtype != 0 && Subtype < ARRAY_SIZE(k_VS_FileSubType_FONT)) + if (Subtype != 0 && Subtype < Z7_ARRAY_SIZE(k_VS_FileSubType_FONT)) { f.AddString(k_VS_FileSubType_FONT[Subtype]); needPrintSubType = false; @@ -1731,7 +1842,7 @@ { for (;;) { - wchar_t c = (wchar_t)Get16(p); + const wchar_t c = (wchar_t)Get16(p); p += 2; if (c == 0) return; @@ -1739,12 +1850,22 @@ } } +static void CopyToUString_ByLen16(const Byte *p, unsigned numChars16, UString &s) +{ + for (; numChars16; numChars16--) + { + const wchar_t c = (wchar_t)Get16(p); + p += 2; + s += c; + } +} + static bool CompareWStrStrings(const Byte *p, const char *s) { unsigned pos = 0; for (;;) { - Byte c = *s++; + const Byte c = (Byte)*s++; if (Get16(p + pos) != c) return false; pos += 2; @@ -1757,7 +1878,7 @@ { UInt32 TotalLen; UInt32 ValueLen; - bool IsTextValue; + unsigned IsTextValue; unsigned StrSize; bool Parse(const Byte *p, UInt32 size); @@ -1771,7 +1892,24 @@ if (pos + 1 >= size) return -1; if (Get16(p + pos) == 0) - return pos; + return (int)pos; + pos += 2; + } +} + +static int Get_Utf16Str_Len_InBytes_AllowNonZeroTail(const Byte *p, size_t size) +{ + unsigned pos = 0; + for (;;) + { + if (pos + 1 >= size) + { + if (pos == size) + return (int)pos; + return -1; + } + if (Get16(p + pos) == 0) + return (int)pos; pos += 2; } } @@ -1786,17 +1924,15 @@ ValueLen = Get16(p + 2); if (TotalLen < k_ResoureBlockHeader_Size || TotalLen > size) return false; - switch (Get16(p + 4)) - { - case 0: IsTextValue = false; break; - case 1: IsTextValue = true; break; - default: return false; - } + IsTextValue = Get16(p + 4); + if (IsTextValue > 1) + return false; StrSize = 0; - int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size, TotalLen - k_ResoureBlockHeader_Size); + const int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size, + TotalLen - k_ResoureBlockHeader_Size); if (t < 0) return false; - StrSize = t; + StrSize = (unsigned)t; return true; } @@ -1833,7 +1969,7 @@ // if (size != vb.TotalLen) return false; */ if (size > vb.TotalLen) - size = vb.TotalLen; + size = vb.TotalLen; CMy_VS_FIXEDFILEINFO FixedFileInfo; if (!FixedFileInfo.Parse(p + pos)) return false; @@ -1854,7 +1990,7 @@ return false; if (vb.ValueLen != 0) return false; - UInt32 endPos = pos + vb.TotalLen; + const UInt32 endPos = pos + vb.TotalLen; pos += k_ResoureBlockHeader_Size; f.AddSpaces(2); @@ -1875,7 +2011,7 @@ CVersionBlock vb2; if (!vb2.Parse(p + pos, endPos - pos)) return false; - UInt32 endPos2 = pos + vb2.TotalLen; + const UInt32 endPos2 = pos + vb2.TotalLen; if (vb2.IsTextValue) return false; pos += k_ResoureBlockHeader_Size; @@ -1893,9 +2029,9 @@ UInt32 num = (vb2.ValueLen >> 2); for (; num != 0; num--, pos += 4) { - UInt32 dw = Get32(p + pos); - UInt32 lang = LOWORD(dw); - UInt32 codePage = HIWORD(dw); + const UInt32 dw = Get32(p + pos); + const UInt32 lang = LOWORD(dw); + const UInt32 codePage = HIWORD(dw); f.AddString(", "); PrintHex(f, lang); @@ -1910,7 +2046,6 @@ if (!CompareWStrStrings(p + pos, "StringFileInfo")) return false; pos += vb.StrSize + 2; - for (;;) { pos += (4 - pos) & 3; @@ -1919,7 +2054,7 @@ CVersionBlock vb2; if (!vb2.Parse(p + pos, endPos - pos)) return false; - UInt32 endPos2 = pos + vb2.TotalLen; + const UInt32 endPos2 = pos + vb2.TotalLen; if (vb2.ValueLen != 0) return false; pos += k_ResoureBlockHeader_Size; @@ -1941,9 +2076,8 @@ CVersionBlock vb3; if (!vb3.Parse(p + pos, endPos2 - pos)) return false; - // ValueLen sometimes is a number of characters (not bytes)? - // So we don't use it. - UInt32 endPos3 = pos + vb3.TotalLen; + // ValueLen is a number of 16-bit characters (usually it includes zero tail character). + const UInt32 endPos3 = pos + vb3.TotalLen; pos += k_ResoureBlockHeader_Size; // we don't write string if it's not text @@ -1958,26 +2092,35 @@ pos += vb3.StrSize + 2; pos += (4 - pos) & 3; - if (vb3.ValueLen > 0 && pos + 2 <= endPos3) + if (vb3.ValueLen != 0 && pos /* + 2 */ <= endPos3) { f.AddChar(','); f.AddSpaces((34 - (int)vb3.StrSize) / 2); - int sLen = Get_Utf16Str_Len_InBytes(p + pos, endPos3 - pos); + // vb3.TotalLen for some PE files (not from msvc) doesn't include tail zero at the end of Value string. + // we allow that minor error. + const int sLen = Get_Utf16Str_Len_InBytes_AllowNonZeroTail(p + pos, endPos3 - pos); if (sLen < 0) return false; + /* + if (vb3.ValueLen - 1 != (unsigned)sLen / 2 && + vb3.ValueLen != (unsigned)sLen / 2) + return false; + */ AddParamString(f, p + pos, (unsigned)sLen); - CopyToUString(p + pos, value); - pos += sLen + 2; + CopyToUString_ByLen16(p + pos, (unsigned)sLen / 2, value); + // pos += (unsigned)sLen + 2; } AddToUniqueUStringVector(keys, key, value); } pos = endPos3; f.NewLine(); } + pos = endPos2; f.CloseBlock(4); } } f.CloseBlock(2); + pos = endPos; } f.CloseBlock(0); @@ -2016,10 +2159,10 @@ { const UInt64 fileSize64 = fileSize; if (callback) - RINOK(callback->SetTotal(NULL, &fileSize64)); + RINOK(callback->SetTotal(NULL, &fileSize64)) } - RINOK(stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, sect.Pa)) _buf.Alloc(fileSize); @@ -2033,7 +2176,7 @@ RINOK(callback->SetCompleted(NULL, &offset64)) } size_t rem = MyMin(fileSize - pos, (size_t)(1 << 22)); - RINOK(ReadStream(stream, _buf + pos, &rem)); + RINOK(ReadStream(stream, _buf + pos, &rem)) if (rem == 0) { if (pos < fileSizeMin) @@ -2049,7 +2192,7 @@ _usedRes.Alloc(fileSize); CRecordVector specItems; - RINOK(ReadTable(0, specItems)); + RINOK(ReadTable(0, specItems)) _oneLang = true; bool stringsOk = true; @@ -2062,7 +2205,7 @@ return S_FALSE; CRecordVector specItems2; - RINOK(ReadTable(item1.Offset & kMask, specItems2)); + RINOK(ReadTable(item1.Offset & kMask, specItems2)) FOR_VECTOR (j, specItems2) { @@ -2071,7 +2214,7 @@ return S_FALSE; CRecordVector specItems3; - RINOK(ReadTable(item2.Offset & kMask, specItems3)); + RINOK(ReadTable(item2.Offset & kMask, specItems3)) CResItem item; item.Type = item1.ID; @@ -2126,8 +2269,8 @@ if (ParseVersion((const Byte *)_buf + offset, item.Size, f, _versionKeys)) { CMixItem mixItem; - mixItem.VersionIndex = _versionFiles.Size(); - mixItem.SectionIndex = sectionIndex; // check it !!!! + mixItem.VersionIndex = (int)_versionFiles.Size(); + mixItem.SectionIndex = (int)sectionIndex; // check it !!!! CByteBuffer_WithLang &vf = _versionFiles.AddNew(); vf.Lang = item.Lang; vf.CopyFrom(f.Buf, f.Buf.GetPos()); @@ -2157,8 +2300,8 @@ if (_strings[i].FinalSize() == 0) continue; CMixItem mixItem; - mixItem.StringIndex = i; - mixItem.SectionIndex = sectionIndex; + mixItem.StringIndex = (int)i; + mixItem.SectionIndex = (int)sectionIndex; _mixItems.Add(mixItem); } } @@ -2192,7 +2335,7 @@ if (sect2.PSize != 0) { - sect2.VSize = sect2.PSize; + sect2.ExtractSize = sect2.VSize = sect2.PSize; sect2.Name = ".rsrc_1"; sect2.Time = 0; sect2.IsAdditionalSection = true; @@ -2219,7 +2362,7 @@ if (NumSections == 0 && OptHeaderSize == 0) return false; - for (unsigned i = 0; i < ARRAY_SIZE(g_MachinePairs); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_MachinePairs); i++) if (Machine == g_MachinePairs[i].Value) return true; if (Machine == 0) @@ -2263,7 +2406,7 @@ if (_coffMode) { Byte h[kCoffHeaderSize]; - RINOK(ReadStream_FALSE(stream, h, kCoffHeaderSize)); + RINOK(ReadStream_FALSE(stream, h, kCoffHeaderSize)) if (!_header.ParseCoff(h)) return S_FALSE; } @@ -2272,7 +2415,7 @@ UInt32 _peOffset; { Byte h[kStartSize]; - RINOK(ReadStream_FALSE(stream, h, kStartSize)); + RINOK(ReadStream_FALSE(stream, h, kStartSize)) if (h[0] != 'M' || h[1] != 'Z') return S_FALSE; /* most of PE files contain 0x0090 at offset 2. @@ -2285,8 +2428,8 @@ } { Byte h[kPeHeaderSize]; - RINOK(stream->Seek(_peOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, h, kPeHeaderSize)); + RINOK(InStream_SeekSet(stream, _peOffset)) + RINOK(ReadStream_FALSE(stream, h, kPeHeaderSize)) if (!_header.ParsePe(h)) return S_FALSE; } @@ -2297,8 +2440,9 @@ _totalSize = optStart + bufSize; CByteBuffer buffer(bufSize); - RINOK(ReadStream_FALSE(stream, buffer, bufSize)); + RINOK(ReadStream_FALSE(stream, buffer, bufSize)) + // memset((void *)&_optHeader, 0, sizeof(_optHeader)); if (_header.OptHeaderSize != 0) if (!_optHeader.Parse(buffer, _header.OptHeaderSize)) return S_FALSE; @@ -2310,28 +2454,56 @@ CSection § = _sections.AddNew(); sect.Parse(buffer + pos); sect.IsRealSect = true; + if (sect.Name.IsEqualTo(".reloc")) + { + const CDirLink &dl = _optHeader.DirItems[kDirLink_BASERELOC]; + if (dl.Va == sect.Va && + dl.Size <= sect.PSize) + sect.ExtractSize = dl.Size; + } + else if (sect.Name.IsEqualTo(".pdata")) + { + const CDirLink &dl = _optHeader.DirItems[kDirLink_EXCEPTION]; + if (dl.Va == sect.Va && + dl.Size <= sect.PSize) + sect.ExtractSize = dl.Size; + } /* PE pre-file in .hxs file has errors: - PSize of resource is larger tnan real size. - So it overlaps next ".its" section. - We correct it. */ - - if (i > 0) - { - CSection &prev = _sections[i - 1]; - if (prev.Pa < sect.Pa && - prev.Pa + prev.PSize > sect.Pa && - sect.PSize > 0) - { - // printf("\n !!!! Section correction: %s\n ", prev.Name); - // fflush(stdout); - prev.PSize = sect.Pa - prev.Pa; + PSize of resource is larger than real size. + So it overlaps next ".its" section. + 7-zip before 22.02: we corrected it. + + 22.02: another bad case is possible in incorrect pe (exe) file: + PSize in .rsrc section is correct, + but next .reloc section has incorrect (Pa) that overlaps with .rsrc. + */ + + if (i != 0) + { + const CSection &prev = _sections[i - 1]; + if (prev.Pa < sect.Pa + && prev.Pa + prev.PSize > sect.Pa + && sect.PSize != 0 + && prev.PSize != 0) + { + _sectionsError = true; + // PRF(printf("\n !!!! Section correction: %s\n ", prev.Name)); + + /* we corrected that case in 7-zip before 22.02: */ + // prev.PSize = sect.Pa - prev.Pa; + + /* 22.02: here we can try to change bad section position to expected postion. + but original Windows code probably will not do same things. */ + // if (prev.PSize <= sect.Va - prev.Va) sect.Pa = prev.Pa + prev.PSize; } } /* last ".its" section in hxs file has incorrect sect.PSize. - So we reduce it to real sect.VSize */ + 7-zip before 22.02: we reduced section to real sect.VSize */ + /* if (sect.VSize == 24 && sect.PSize == 512 && i == (unsigned)_header.NumSections - 1) sect.PSize = sect.VSize; + */ } for (i = 0; i < _sections.Size(); i++) @@ -2340,7 +2512,7 @@ bool thereISDebug = false; if (IsOpt()) { - RINOK(LoadDebugSections(stream, thereISDebug)); + RINOK(LoadDebugSections(stream, thereISDebug)) const CDirLink &certLink = _optHeader.DirItems[kDirLink_Certificate]; if (certLink.Size != 0) @@ -2349,7 +2521,7 @@ sect.Name = "CERTIFICATE"; sect.Va = 0; sect.Pa = certLink.Va; - sect.PSize = sect.VSize = certLink.Size; + sect.Set_Size_for_all(certLink.Size); sect.UpdateTotalSize(_totalSize); } @@ -2364,11 +2536,11 @@ if (alignPos != 0) { UInt32 size = kAlign - alignPos; - RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, _totalSize)) buffer.Alloc(kAlign); Byte *buf = buffer; size_t processed = size; - RINOK(ReadStream(stream, buf, &processed)); + RINOK(ReadStream(stream, buf, &processed)) /* if (processed != 0) @@ -2395,9 +2567,9 @@ if (_header.NumSymbols >= (1 << 24)) return S_FALSE; UInt32 size = _header.NumSymbols * 18; - RINOK(stream->Seek((UInt64)_header.PointerToSymbolTable + size, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, (UInt64)_header.PointerToSymbolTable + size)) Byte buf[4]; - RINOK(ReadStream_FALSE(stream, buf, 4)); + RINOK(ReadStream_FALSE(stream, buf, 4)) UInt32 size2 = Get32(buf); if (size2 >= (1 << 28)) return S_FALSE; @@ -2407,7 +2579,7 @@ sect.Name = "COFF_SYMBOLS"; sect.Va = 0; sect.Pa = _header.PointerToSymbolTable; - sect.PSize = sect.VSize = size; + sect.Set_Size_for_all(size); sect.UpdateTotalSize(_totalSize); } @@ -2423,11 +2595,11 @@ { CSection &s2 = _sections.AddNew(); s2.Pa = s2.Va = limit; - s2.PSize = s2.VSize = s.Pa - limit; + s2.Set_Size_for_all(s.Pa - limit); s2.IsAdditionalSection = true; - s2.Name = '['; + s2.Name.Add_Char('['); s2.Name.Add_UInt32(num++); - s2.Name += ']'; + s2.Name.Add_Char(']'); limit = s.Pa; } UInt32 next = s.Pa + s.PSize; @@ -2442,9 +2614,9 @@ if (IsOpt()) if (_optHeader.CheckSum != 0) { - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(stream)) UInt32 checkSum = 0; - RINOK(CalcCheckSum(stream, _totalSize, optStart + k_CheckSum_Field_Offset, checkSum)); + RINOK(CalcCheckSum(stream, _totalSize, optStart + k_CheckSum_Field_Offset, checkSum)) _checksumError = (checkSum != _optHeader.CheckSum); } @@ -2452,13 +2624,13 @@ if (!_allowTail) { UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) if (fileSize > _totalSize) return S_FALSE; } bool _parseResources = true; - // _parseResources = false; + // _parseResources = false; // for debug UInt64 mainSize = 0, mainSize2 = 0; @@ -2466,7 +2638,7 @@ { const CSection § = _sections[i]; if (IsOpt()) - if (_parseResources && sect.Name == ".rsrc") + if (_parseResources && sect.Name.IsEqualTo(".rsrc")) { // 20.01: we try to parse only first copy of .rsrc section. _parseResources = false; @@ -2482,15 +2654,15 @@ if (item.Enabled) { CMixItem mixItem; - mixItem.SectionIndex = i; - mixItem.ResourceIndex = j; + mixItem.SectionIndex = (int)i; + mixItem.ResourceIndex = (int)j; if (item.IsRcDataOrUnknown()) { if (item.Size >= mainSize) { mainSize2 = mainSize; mainSize = item.Size; - _mainSubfile = _mixItems.Size(); + _mainSubfile = (Int32)(int)_mixItems.Size(); } else if (item.Size >= mainSize2) mainSize2 = item.Size; @@ -2538,14 +2710,14 @@ { mainSize2 = mainSize; mainSize = sect.PSize; - _mainSubfile = _mixItems.Size(); + _mainSubfile = (Int32)(int)_mixItems.Size(); } else if (sect.PSize >= mainSize2) mainSize2 = sect.PSize; } CMixItem mixItem; - mixItem.SectionIndex = i; + mixItem.SectionIndex = (int)i; _mixItems.Add(mixItem); } @@ -2555,9 +2727,9 @@ for (i = 0; i < _mixItems.Size(); i++) { const CMixItem &mixItem = _mixItems[i]; - if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name == "_winzip_") + if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name.IsEqualTo("_winzip_")) { - _mainSubfile = i; + _mainSubfile = (Int32)(int)i; break; } } @@ -2594,11 +2766,11 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); - RINOK(Open2(inStream, callback)); + RINOK(Open2(inStream, callback)) _stream = inStream; return S_OK; COM_TRY_END @@ -2617,10 +2789,11 @@ _versionKeys.Clear(); } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _checksumError = false; + _sectionsError = false; _mainSubfile = -1; _stream.Release(); @@ -2630,17 +2803,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _mixItems.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _mixItems.Size(); if (numItems == 0) @@ -2658,36 +2831,33 @@ else if (mixItem.ResourceIndex >= 0) size = _items[mixItem.ResourceIndex].GetSize(); else - size = _sections[mixItem.SectionIndex].GetSizeExtract(); + size = _sections[mixItem.SectionIndex].GetSize_Extract(); totalSize += size; } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + RINOK(extractCallback->SetTotal(totalSize)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? + totalSize = 0; + UInt64 currentItemSize; + + for (i = 0;; i++, totalSize += currentItemSize) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) const CMixItem &mixItem = _mixItems[index]; const CSection § = _sections[mixItem.SectionIndex]; @@ -2699,9 +2869,9 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (outStream) - RINOK(WriteStream(outStream, item.Buf, item.FinalSize())); + RINOK(WriteStream(outStream, item.Buf, item.FinalSize())) } else if (mixItem.VersionIndex >= 0) { @@ -2710,9 +2880,9 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (outStream) - RINOK(WriteStream(outStream, item, item.Size())); + RINOK(WriteStream(outStream, item, item.Size())) } else if (mixItem.ResourceIndex >= 0) { @@ -2721,48 +2891,48 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) size_t offset = item.Offset - sect.Va; if (!CheckItem(sect, item, offset)) isOk = false; else if (outStream) { if (item.HeaderSize != 0) - RINOK(WriteStream(outStream, item.Header, item.HeaderSize)); - RINOK(WriteStream(outStream, _buf + offset, item.Size)); + RINOK(WriteStream(outStream, item.Header, item.HeaderSize)) + RINOK(WriteStream(outStream, _buf + offset, item.Size)) } } else { - currentItemSize = sect.GetSizeExtract(); + currentItemSize = sect.GetSize_Extract(); if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - isOk = (copyCoderSpec->TotalSize == currentItemSize); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_stream, sect.Pa)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + isOk = (copyCoder->TotalSize == currentItemSize); } outStream.Release(); RINOK(extractCallback->SetOperationResult(isOk ? NExtract::NOperationResult::kOK : - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; const CMixItem &mixItem = _mixItems[index]; const CSection § = _sections[mixItem.SectionIndex]; if (mixItem.IsSectionItem()) - return CreateLimitedInStream(_stream, sect.Pa, sect.PSize, stream); + return CreateLimitedInStream(_stream, sect.Pa, sect.GetSize_Extract(), stream); CBufInStream *inStreamSpec = new CBufInStream; CMyComPtr streamTemp = inStreamSpec; @@ -2804,7 +2974,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) { _allowTail = IntToBool(allowTail); return S_OK; @@ -2813,7 +2983,7 @@ static const Byte k_Signature[] = { 'M', 'Z' }; REGISTER_ARC_I( - "PE", "exe dll sys", 0, 0xDD, + "PE", "exe dll sys", NULL, 0xDD, k_Signature, 0, NArcInfoFlags::kPreArc, @@ -2846,7 +3016,7 @@ REGISTER_ARC_I_CLS_NO_SIG( NPe::CHandler(true), - "COFF", "obj", 0, 0xC6, + "COFF", "obj", NULL, 0xC6, // k_Signature, 0, // NArcInfoFlags::kMultiSignature | @@ -2881,8 +3051,8 @@ return false; } -#define MY_FIND_VALUE(pairs, val) FindValue(pairs, ARRAY_SIZE(pairs), val) -#define MY_FIND_VALUE_2(strings, val) (val < ARRAY_SIZE(strings) && strings[val]) +#define MY_FIND_VALUE(pairs, val) FindValue(pairs, Z7_ARRAY_SIZE(pairs), val) +#define MY_FIND_VALUE_2(strings, val) (val < Z7_ARRAY_SIZE(strings) && strings[val]) static const UInt32 kNumSection_MAX = 32; @@ -2922,7 +3092,7 @@ G32(12, BaseOfCode); G64(16, ImageBase); */ - for (int i = 0; i < 2; i++) + for (unsigned i = 0; i < 2; i++) { CDataDir &dd = DataDir[i]; dd.Parse(p + 24 + i * 8); @@ -2955,6 +3125,7 @@ { Byte Name[NPe::kNameSize]; + UInt32 ExtractSize; UInt32 VSize; UInt32 Va; UInt32 PSize; @@ -2971,6 +3142,7 @@ G32(20, Pa); // G32(p + 32, NumRelocs); G32(36, Flags); + ExtractSize = (VSize && VSize < PSize) ? VSize : PSize; } bool Check() const @@ -2980,20 +3152,24 @@ PSize <= ((UInt32)1 << 30); } + UInt32 GetSize_Extract() const + { + return ExtractSize; + } + void UpdateTotalSize(UInt32 &totalSize) { - UInt32 t = Pa + PSize; - if (t > totalSize) - totalSize = t; + const UInt32 t = Pa + PSize; + if (totalSize < t) + totalSize = t; } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public IArchiveAllowTail, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IInArchiveGetStream, + IArchiveAllowTail +) CRecordVector _items; CMyComPtr _stream; UInt32 _totalSize; @@ -3002,10 +3178,6 @@ HRESULT Open2(IInStream *stream); public: - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(AllowTail)(Int32 allowTail); CHandler(): _allowTail(false) {} }; @@ -3013,6 +3185,7 @@ { kpidPath, kpidSize, + kpidPackSize, kpidVirtualSize, kpidCharacts, kpidOffset, @@ -3036,7 +3209,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_WITH_NAME -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -3056,7 +3229,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -3071,7 +3244,7 @@ prop = MultiByteToUnicodeString(name); break; } - case kpidSize: + case kpidSize: prop = (UInt64)item.GetSize_Extract(); break; case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidOffset: prop = item.Pa; break; @@ -3087,7 +3260,7 @@ HRESULT CHandler::Open2(IInStream *stream) { Byte h[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, h, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, h, kHeaderSize)) if (h[0] != 'V' || h[1] != 'Z') return S_FALSE; if (!_h.Parse(h)) @@ -3095,7 +3268,7 @@ UInt32 headerSize = NPe::kSectionSize * (UInt32)_h.NumSections; CByteArr buf(headerSize); - RINOK(ReadStream_FALSE(stream, buf, headerSize)); + RINOK(ReadStream_FALSE(stream, buf, headerSize)) headerSize += kHeaderSize; _totalSize = headerSize; @@ -3117,7 +3290,7 @@ if (!_allowTail) { UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) if (fileSize > _totalSize) return S_FALSE; } @@ -3125,24 +3298,24 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN Close(); - try + // try { if (Open2(inStream) != S_OK) return S_FALSE; _stream = inStream; } - catch(...) { return S_FALSE; } + // catch(...) { return S_FALSE; } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _stream.Release(); @@ -3150,17 +3323,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -3168,62 +3341,62 @@ UInt64 totalSize = 0; UInt32 i; for (i = 0; i < numItems; i++) - totalSize += _items[allFilesMode ? i : indices[i]].PSize; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + totalSize += _items[allFilesMode ? i : indices[i]].GetSize_Extract(); + RINOK(extractCallback->SetTotal(totalSize)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); + totalSize = 0; - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + int opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CSection &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentTotalSize += item.PSize; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + const UInt32 size = item.GetSize_Extract(); + totalSize += size; if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - int res = NExtract::NOperationResult::kDataError; - - RINOK(_stream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.PSize); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.PSize) - res = NExtract::NOperationResult::kOK; - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_stream, item.Pa)) + inStream->Init(size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + + opRes = (copyCoder->TotalSize == size) ? + NExtract::NOperationResult::kOK : (copyCoder->TotalSize < size) ? + NExtract::NOperationResult::kUnexpectedEnd : + NExtract::NOperationResult::kDataError; + } + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN const CSection &item = _items[index]; - return CreateLimitedInStream(_stream, item.Pa, item.PSize, stream); + return CreateLimitedInStream(_stream, item.Pa, item.GetSize_Extract(), stream); COM_TRY_END } -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) { _allowTail = IntToBool(allowTail); return S_OK; @@ -3232,7 +3405,7 @@ static const Byte k_Signature[] = { 'V', 'Z' }; REGISTER_ARC_I( - "TE", "te", 0, 0xCF, + "TE", "te", NULL, 0xCF, k_Signature, 0, NArcInfoFlags::kPreArc, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/PpmdHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PpmdHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/PpmdHandler.cpp 2022-03-28 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/PpmdHandler.cpp 2023-12-11 10:00:00.000000000 +0000 @@ -33,13 +33,13 @@ { Byte *Buf; - CBuf(): Buf(0) {} + CBuf(): Buf(NULL) {} ~CBuf() { ::MidFree(Buf); } bool Alloc() { if (!Buf) Buf = (Byte *)::MidAlloc(kBufSize); - return (Buf != 0); + return (Buf != NULL); } }; @@ -59,18 +59,22 @@ unsigned Restor; HRESULT ReadHeader(ISequentialInStream *s, UInt32 &headerSize); - bool IsSupported() const { return Ver == 7 || (Ver == 8 && Restor < PPMD8_RESTORE_METHOD_UNSUPPPORTED); } + bool IsSupported() const + { + return (Ver == 7 && Order >= PPMD7_MIN_ORDER) + || (Ver == 8 && Order >= PPMD8_MIN_ORDER && Restor < PPMD8_RESTORE_METHOD_UNSUPPPORTED); + } }; HRESULT CItem::ReadHeader(ISequentialInStream *s, UInt32 &headerSize) { Byte h[kHeaderSize]; - RINOK(ReadStream_FALSE(s, h, kHeaderSize)); + RINOK(ReadStream_FALSE(s, h, kHeaderSize)) if (GetUi32(h) != kSignature) return S_FALSE; Attrib = GetUi32(h + 4); Time = GetUi32(h + 12); - unsigned info = GetUi16(h + 8); + const unsigned info = GetUi16(h + 8); Order = (info & 0xF) + 1; MemInMB = ((info >> 4) & 0xFF) + 1; Ver = info >> 12; @@ -86,17 +90,16 @@ if (nameLen > (1 << 9)) return S_FALSE; char *name = Name.GetBuf(nameLen); - HRESULT res = ReadStream_FALSE(s, name, nameLen); + const HRESULT res = ReadStream_FALSE(s, name, nameLen); Name.ReleaseBuf_CalcLen(nameLen); headerSize = kHeaderSize + nameLen; return res; } -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) CItem _item; UInt32 _headerSize; bool _packSize_Defined; @@ -104,11 +107,6 @@ CMyComPtr _stream; void GetVersion(NCOM::CPropVariant &prop); - -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); }; static const Byte kProps[] = @@ -130,12 +128,12 @@ void CHandler::GetVersion(NCOM::CPropVariant &prop) { AString s ("PPMd"); - s += (char)('A' + _item.Ver); + s.Add_Char((char)('A' + _item.Ver)); s += ":o"; s.Add_UInt32(_item.Order); s += ":mem"; s.Add_UInt32(_item.MemInMB); - s += 'm'; + s.Add_Char('m'); if (_item.Ver >= kNewHeaderVer && _item.Restor != 0) { s += ":r"; @@ -144,7 +142,7 @@ prop = s; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -157,13 +155,13 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -187,12 +185,12 @@ COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) { return OpenSeq(stream); } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { COM_TRY_BEGIN HRESULT res; @@ -210,7 +208,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _packSize = 0; _packSize_Defined = false; @@ -252,7 +250,7 @@ if (Ver == 7) Ppmd7_Init(&_ppmd7, order); else - Ppmd8_Init(&_ppmd8, order, restor);; + Ppmd8_Init(&_ppmd8, order, restor); } bool InitRc(CByteInBufWrap *inStream) @@ -278,8 +276,8 @@ }; -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { if (numItems == 0) return S_OK; @@ -288,16 +286,18 @@ // extractCallback->SetTotal(_packSize); UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) + Int32 opRes; +{ CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) CByteInBufWrap inBuf; if (!inBuf.Alloc(1 << 20)) @@ -308,15 +308,14 @@ if (!outBuf.Alloc()) return E_OUTOFMEMORY; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); CPpmdCpp ppmd(_item.Ver); if (!ppmd.Alloc(_item.MemInMB)) return E_OUTOFMEMORY; - Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod; + opRes = NExtract::NOperationResult::kUnsupportedMethod; if (_item.IsSupported()) { @@ -331,7 +330,7 @@ { lps->InSize = _packSize = inBuf.GetProcessed(); lps->OutSize = outSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) size_t i; int sym = 0; @@ -363,7 +362,7 @@ _packSize_Defined = true; if (realOutStream) { - RINOK(WriteStream(realOutStream, outBuf.Buf, i)); + RINOK(WriteStream(realOutStream, outBuf.Buf, i)) } if (inBuf.Extra) @@ -380,10 +379,9 @@ } } - RINOK(inBuf.Res); + RINOK(inBuf.Res) } - - realOutStream.Release(); +} return extractCallback->SetOperationResult(opRes); } @@ -391,7 +389,7 @@ static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 }; REGISTER_ARC_I( - "Ppmd", "pmd", 0, 0xD, + "Ppmd", "pmd", NULL, 0xD, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/QcowHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/QcowHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/QcowHandler.cpp 2021-12-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/QcowHandler.cpp 2024-06-28 10:00:00.000000000 +0000 @@ -11,6 +11,7 @@ #include "../../Common/MyBuffer2.h" #include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" #include "../Common/RegisterArc.h" #include "../Common/StreamObjects.h" @@ -20,62 +21,61 @@ #include "HandlerCont.h" -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) +#define Get32(p) GetBe32a(p) +#define Get64(p) GetBe64a(p) using namespace NWindows; namespace NArchive { namespace NQcow { -#define SIGNATURE { 'Q', 'F', 'I', 0xFB, 0, 0, 0 } - -static const Byte k_Signature[] = SIGNATURE; +static const Byte k_Signature[] = { 'Q', 'F', 'I', 0xFB, 0, 0, 0 }; /* VA to PA maps: - high bits (L1) : : in L1 Table : the reference to L1 Table - mid bits (L2) : _numMidBits : in L2 Table : the reference to cluster - low bits : _clusterBits + high bits (L1) : : index in L1 (_dir) : _dir[high_index] points to Table. + mid bits (L2) : _numMidBits : index in Table, Table[index] points to cluster start offset in arc file. + low bits : _clusterBits : offset inside cluster. */ -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { + Z7_IFACE_COM7_IMP(IInArchive_Img) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + unsigned _clusterBits; unsigned _numMidBits; UInt64 _compressedFlag; CObjArray2 _dir; CAlignedBuffer _table; - UInt64 _cacheCluster; CByteBuffer _cache; CByteBuffer _cacheCompressed; + UInt64 _cacheCluster; UInt64 _comprPos; size_t _comprSize; - UInt64 _phySize; - - CBufInStream *_bufInStreamSpec; - CMyComPtr _bufInStream; - - CBufPtrSeqOutStream *_bufOutStreamSpec; - CMyComPtr _bufOutStream; - - NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoderSpec; - CMyComPtr _deflateDecoder; - - bool _needDeflate; + bool _needCompression; bool _isArc; bool _unsupported; + Byte _compressionType; + + UInt64 _phySize; + + CMyComPtr2 _bufInStream; + CMyComPtr2 _bufOutStream; + CMyComPtr2 _deflateDecoder; UInt32 _version; UInt32 _cryptMethod; + UInt64 _incompatFlags; HRESULT Seek2(UInt64 offset) { _posInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, offset); } HRESULT InitAndSeek() @@ -84,29 +84,21 @@ return Seek2(0); } - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); - -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; }; static const UInt32 kEmptyDirItem = (UInt32)0 - 1; -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - // printf("\nRead _virtPos = %6d size = %6d\n", (UInt32)_virtPos, size); - if (_virtPos >= _size) return S_OK; { - UInt64 rem = _size - _virtPos; + const UInt64 rem = _size - _virtPos; if (size > rem) size = (UInt32)rem; if (size == 0) @@ -119,47 +111,43 @@ const size_t clusterSize = (size_t)1 << _clusterBits; const size_t lowBits = (size_t)_virtPos & (clusterSize - 1); { - size_t rem = clusterSize - lowBits; + const size_t rem = clusterSize - lowBits; if (size > rem) size = (UInt32)rem; } - if (cluster == _cacheCluster) { memcpy(data, _cache + lowBits, size); break; } - + const UInt64 high = cluster >> _numMidBits; if (high < _dir.Size()) { - const UInt32 tabl = _dir[(unsigned)high]; - + const UInt32 tabl = _dir[(size_t)high]; if (tabl != kEmptyDirItem) { - const Byte *buffer = _table + ((size_t)tabl << (_numMidBits + 3)); const size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1); - const Byte *p = (const Byte *)buffer + (midBits << 3); + const Byte *p = _table + ((((size_t)tabl << _numMidBits) + midBits) << 3); UInt64 v = Get64(p); - if (v != 0) + if (v) { - if ((v & _compressedFlag) != 0) + if (v & _compressedFlag) { if (_version <= 1) return E_FAIL; - /* - the example of table record for 12-bit clusters (4KB uncompressed). - 2 bits : isCompressed status - 4 bits : num_sectors_minus1; packSize = (num_sectors_minus1 + 1) * 512; - it uses one additional bit over unpacked cluster_bits - 49 bits : offset of 512-sector - 9 bits : offset in 512-sector + the example of table record for 12-bit clusters (4KB uncompressed): + 2 bits : isCompressed status + (4 == _clusterBits - 8) bits : (num_sectors - 1) + packSize = num_sectors * 512; + it uses one additional bit over unpacked cluster_bits. + (49 == 61 - _clusterBits) bits : offset of 512-byte sector + 9 bits : offset in 512-byte sector */ - - const unsigned numOffsetBits = (62 - (_clusterBits - 9 + 1)); + const unsigned numOffsetBits = 62 - (_clusterBits - 8); const UInt64 offset = v & (((UInt64)1 << 62) - 1); const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; UInt64 sectorOffset = offset & (((UInt64)1 << numOffsetBits) - (1 << 9)); @@ -171,7 +159,7 @@ if (sectorOffset >= _comprPos && offset2inCache < _comprSize) { - if (offset2inCache != 0) + if (offset2inCache) { _comprSize -= (size_t)offset2inCache; memmove(_cacheCompressed, _cacheCompressed + (size_t)offset2inCache, _comprSize); @@ -190,46 +178,41 @@ if (sectorOffset != _posInArc) { // printf("\nDeflate-Seek %12I64x %12I64x\n", sectorOffset, sectorOffset - _posInArc); - RINOK(Seek2(sectorOffset)); + RINOK(Seek2(sectorOffset)) } if (_cacheCompressed.Size() < dataSize) return E_FAIL; const size_t dataSize3 = dataSize - _comprSize; size_t dataSize2 = dataSize3; // printf("\n\n=======\nReadStream = %6d _comprPos = %6d \n", (UInt32)dataSize2, (UInt32)_comprPos); - RINOK(ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2)); + const HRESULT hres = ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2); _posInArc += dataSize2; + RINOK(hres) if (dataSize2 != dataSize3) return E_FAIL; _comprSize += dataSize2; } const size_t kSectorMask = (1 << 9) - 1; - const size_t offsetInSector = ((size_t)offset & kSectorMask); - _bufInStreamSpec->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector); - + const size_t offsetInSector = (size_t)offset & kSectorMask; + _bufInStream->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector); _cacheCluster = (UInt64)(Int64)-1; if (_cache.Size() < clusterSize) return E_FAIL; - _bufOutStreamSpec->Init(_cache, clusterSize); - + _bufOutStream->Init(_cache, clusterSize); // Do we need to use smaller block than clusterSize for last cluster? const UInt64 blockSize64 = clusterSize; - HRESULT res = _deflateDecoderSpec->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); - + HRESULT res = _deflateDecoder.Interface()->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); /* if (_bufOutStreamSpec->GetPos() != clusterSize) memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos()); */ - if (res == S_OK) - if (!_deflateDecoderSpec->IsFinished() - || _bufOutStreamSpec->GetPos() != clusterSize) + if (!_deflateDecoder->IsFinished() + || _bufOutStream->GetPos() != clusterSize) res = S_FALSE; - - RINOK(res); + RINOK(res) _cacheCluster = cluster; - continue; /* memcpy(data, _cache + lowBits, size); @@ -237,17 +220,17 @@ */ } - // version 3 support zero clusters + // version_3 supports zero clusters if (((UInt32)v & 511) != 1) { - v &= (_compressedFlag - 1); + v &= _compressedFlag - 1; v += lowBits; if (v != _posInArc) { // printf("\n%12I64x\n", v - _posInArc); - RINOK(Seek2(v)); + RINOK(Seek2(v)) } - HRESULT res = Stream->Read(data, size, &size); + const HRESULT res = Stream->Read(data, size, &size); _posInArc += size; _virtPos += size; if (processedSize) @@ -278,14 +261,26 @@ static const Byte kArcProps[] = { kpidClusterSize, + kpidSectorSize, // actually we need variable to show table size + kpidHeadersSize, kpidUnpackVer, - kpidMethod + kpidMethod, + kpidCharacts }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +static const CUInt32PCharPair g_IncompatFlags_Characts[] = +{ + { 0, "Dirty" }, + { 1, "Corrupt" }, + { 2, "External_Data_File" }, + { 3, "Compression" }, + { 4, "Extended_L2" } +}; + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -294,40 +289,66 @@ { case kpidMainSubfile: prop = (UInt32)0; break; case kpidClusterSize: prop = (UInt32)1 << _clusterBits; break; - case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidSectorSize: prop = (UInt32)1 << (_numMidBits + 3); break; + case kpidHeadersSize: prop = _table.Size() + (UInt64)_dir.Size() * 8; break; + case kpidPhySize: if (_phySize) prop = _phySize; break; case kpidUnpackVer: prop = _version; break; - + case kpidCharacts: + { + if (_incompatFlags) + { + AString s ("incompatible: "); + // we need to show also high 32-bits. + s += FlagsToString(g_IncompatFlags_Characts, + Z7_ARRAY_SIZE(g_IncompatFlags_Characts), (UInt32)_incompatFlags); + prop = s; + } + break; + } case kpidMethod: { AString s; - if (_needDeflate) - s = "Deflate"; + if (_compressionType) + { + if (_compressionType == 1) + s += "ZSTD"; + else + { + s += "Compression:"; + s.Add_UInt32(_compressionType); + } + } + else if (_needCompression) + s.Add_OptSpaced("Deflate"); - if (_cryptMethod != 0) + if (_cryptMethod) { s.Add_Space_if_NotEmpty(); if (_cryptMethod == 1) s += "AES"; + if (_cryptMethod == 2) + s += "LUKS"; else + { + s += "Encryption:"; s.Add_UInt32(_cryptMethod); + } } - if (!s.IsEmpty()) prop = s; - break; } case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; // if (_headerError) v |= kpv_ErrorFlags_HeadersError; - if (!Stream && v == 0 && _isArc) + if (!Stream && v == 0) v = kpv_ErrorFlags_HeadersError; - if (v != 0) + if (v) prop = v; break; } @@ -339,7 +360,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -359,76 +380,91 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback) { - const unsigned kHeaderSize = 18 * 4; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - - if (memcmp(buf, k_Signature, 4) != 0) + UInt64 buf64[0x70 / 8]; + RINOK(ReadStream_FALSE(stream, buf64, sizeof(buf64))) + const void *buf = (const void *)buf64; + // signature: { 'Q', 'F', 'I', 0xFB } + if (*(const UInt32 *)buf != Z7_CONV_BE_TO_NATIVE_CONST32(0x514649fb)) return S_FALSE; - - _version = Get32(buf + 4); + _version = Get32((const Byte *)(const void *)buf64 + 4); if (_version < 1 || _version > 3) return S_FALSE; - const UInt64 backOffset = Get64(buf + 8); - // UInt32 backSize = Get32(buf + 0x10); - - UInt64 l1Offset; - UInt32 l1Size; + const UInt64 k_UncompressedSize_MAX = (UInt64)1 << 60; + const UInt64 k_CompressedSize_MAX = (UInt64)1 << 60; + + _size = Get64((const Byte *)(const void *)buf64 + 0x18); + if (_size > k_UncompressedSize_MAX) + return S_FALSE; + size_t l1Size; + UInt32 headerSize; if (_version == 1) { - // _mTime = Get32(buf + 0x14); // is unused im most images - _size = Get64(buf + 0x18); - _clusterBits = buf[0x20]; - _numMidBits = buf[0x21]; + // _mTime = Get32((const Byte *)(const void *)buf64 + 0x14); // is unused in most images + _clusterBits = ((const Byte *)(const void *)buf64)[0x20]; + _numMidBits = ((const Byte *)(const void *)buf64)[0x21]; if (_clusterBits < 9 || _clusterBits > 30) return S_FALSE; if (_numMidBits < 1 || _numMidBits > 28) return S_FALSE; - _cryptMethod = Get32(buf + 0x24); - l1Offset = Get64(buf + 0x28); - if (l1Offset < 0x30) - return S_FALSE; - const unsigned numBits2 = (_clusterBits + _numMidBits); + _cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x24); + const unsigned numBits2 = _clusterBits + _numMidBits; const UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2; if (l1Size64 > ((UInt32)1 << 31)) return S_FALSE; - l1Size = (UInt32)l1Size64; + l1Size = (size_t)l1Size64; + headerSize = 0x30; } else { - _clusterBits = Get32(buf + 0x14); + _clusterBits = Get32((const Byte *)(const void *)buf64 + 0x14); if (_clusterBits < 9 || _clusterBits > 30) return S_FALSE; _numMidBits = _clusterBits - 3; - _size = Get64(buf + 0x18); - _cryptMethod = Get32(buf + 0x20); - l1Size = Get32(buf + 0x24); - l1Offset = Get64(buf + 0x28); // must be aligned for cluster - - const UInt64 refOffset = Get64(buf + 0x30); // must be aligned for cluster - const UInt32 refClusters = Get32(buf + 0x38); - - // UInt32 numSnapshots = Get32(buf + 0x3C); - // UInt64 snapshotsOffset = Get64(buf + 0x40); // must be aligned for cluster + _cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x20); + l1Size = Get32((const Byte *)(const void *)buf64 + 0x24); + headerSize = 0x48; + if (_version >= 3) + { + _incompatFlags = Get64((const Byte *)(const void *)buf64 + 0x48); + // const UInt64 CompatFlags = Get64((const Byte *)(const void *)buf64 + 0x50); + // const UInt64 AutoClearFlags = Get64((const Byte *)(const void *)buf64 + 0x58); + // const UInt32 RefCountOrder = Get32((const Byte *)(const void *)buf64 + 0x60); + headerSize = 0x68; + const UInt32 headerSize2 = Get32((const Byte *)(const void *)buf64 + 0x64); + if (headerSize2 > (1u << 30)) + return S_FALSE; + if (headerSize < headerSize2) + headerSize = headerSize2; + if (headerSize2 >= 0x68 + 1) + _compressionType = ((const Byte *)(const void *)buf64)[0x68]; + } + + const UInt64 refOffset = Get64((const Byte *)(const void *)buf64 + 0x30); // must be aligned for cluster + const UInt32 refClusters = Get32((const Byte *)(const void *)buf64 + 0x38); + // UInt32 numSnapshots = Get32((const Byte *)(const void *)buf64 + 0x3C); + // UInt64 snapshotsOffset = Get64((const Byte *)(const void *)buf64 + 0x40); // must be aligned for cluster /* - if (numSnapshots != 0) + if (numSnapshots) return S_FALSE; */ - - if (refClusters != 0) + if (refClusters) { - const size_t numBytes = refClusters << _clusterBits; + if (refOffset > k_CompressedSize_MAX) + return S_FALSE; + const UInt64 numBytes = (UInt64)refClusters << _clusterBits; + const UInt64 end = refOffset + numBytes; + if (end > k_CompressedSize_MAX) + return S_FALSE; /* CByteBuffer refs; refs.Alloc(numBytes); - RINOK(stream->Seek(refOffset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, refOffset)) RINOK(ReadStream_FALSE(stream, refs, numBytes)); */ - const UInt64 end = refOffset + numBytes; if (_phySize < end) - _phySize = end; + _phySize = end; /* for (size_t i = 0; i < numBytes; i += 2) { @@ -440,48 +476,76 @@ } } - _isArc = true; + const UInt64 l1Offset = Get64((const Byte *)(const void *)buf64 + 0x28); // must be aligned for cluster ? + if (l1Offset < headerSize || l1Offset > k_CompressedSize_MAX) + return S_FALSE; + if (_phySize < headerSize) + _phySize = headerSize; - if (backOffset != 0) + _isArc = true; { - _unsupported = true; - return S_FALSE; + const UInt64 backOffset = Get64((const Byte *)(const void *)buf64 + 8); + // UInt32 backSize = Get32((const Byte *)(const void *)buf64 + 0x10); + if (backOffset) + { + _unsupported = true; + return S_FALSE; + } } - const size_t clusterSize = (size_t)1 << _clusterBits; + UInt64 fileSize = 0; + RINOK(InStream_GetSize_SeekToBegin(stream, fileSize)) - CByteBuffer table; + const size_t clusterSize = (size_t)1 << _clusterBits; + const size_t t1SizeBytes = (size_t)l1Size << 3; { - const size_t t1SizeBytes = (size_t)l1Size << 3; - if ((t1SizeBytes >> 3) != l1Size) + const UInt64 end = l1Offset + t1SizeBytes; + if (end > k_CompressedSize_MAX) return S_FALSE; - table.Alloc(t1SizeBytes); - RINOK(stream->Seek(l1Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, table, t1SizeBytes)); - - { - UInt64 end = l1Offset + t1SizeBytes; - // we need to uses align end for empty qcow files - end = (end + clusterSize - 1) >> _clusterBits << _clusterBits; - if (_phySize < end) + // we need to use align end for empty qcow files + // some files has no cluster alignment padding at the end + // but has sector alignment + // end = (end + clusterSize - 1) >> _clusterBits << _clusterBits; + if (_phySize < end) _phySize = end; + if (end > fileSize) + return S_FALSE; + if (_phySize < fileSize) + { + const UInt64 end2 = (end + 511) & ~(UInt64)511; + if (end2 == fileSize) + _phySize = end2; } } + CObjArray table64(l1Size); + { + // if ((t1SizeBytes >> 3) != l1Size) return S_FALSE; + RINOK(InStream_SeekSet(stream, l1Offset)) + RINOK(ReadStream_FALSE(stream, table64, t1SizeBytes)) + } _compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62); const UInt64 offsetMask = _compressedFlag - 1; + const size_t midSize = (size_t)1 << (_numMidBits + 3); + size_t numTables = 0; + size_t i; - UInt32 numTables = 0; - UInt32 i; - for (i = 0; i < l1Size; i++) { - const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask; - if (v != 0) - numTables++; + const UInt64 v = Get64(table64 + (size_t)i) & offsetMask; + if (!v) + continue; + numTables++; + const UInt64 end = v + midSize; + if (end > k_CompressedSize_MAX) + return S_FALSE; + if (_phySize < end) + _phySize = end; + if (end > fileSize) + return S_FALSE; } - if (numTables != 0) + if (numTables) { const size_t size = (size_t)numTables << (_numMidBits + 3); if (size >> (_numMidBits + 3) != numTables) @@ -489,48 +553,38 @@ _table.Alloc(size); if (!_table.IsAllocated()) return E_OUTOFMEMORY; + if (openCallback) + { + const UInt64 totalBytes = size; + RINOK(openCallback->SetTotal(NULL, &totalBytes)) + } } - _dir.SetSize(l1Size); + _dir.SetSize((unsigned)l1Size); UInt32 curTable = 0; - if (openCallback) - { - const UInt64 totalBytes = (UInt64)numTables << (_numMidBits + 3); - RINOK(openCallback->SetTotal(NULL, &totalBytes)); - } - for (i = 0; i < l1Size; i++) { Byte *buf2; - const size_t midSize = (size_t)1 << (_numMidBits + 3); - { - const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask; + const UInt64 v = Get64(table64 + (size_t)i) & offsetMask; if (v == 0) { _dir[i] = kEmptyDirItem; continue; } - _dir[i] = curTable; - const size_t tableOffset = ((size_t)curTable << (_numMidBits + 3)); + const size_t tableOffset = (size_t)curTable << (_numMidBits + 3); buf2 = (Byte *)_table + tableOffset; curTable++; - if (openCallback && (tableOffset & 0xFFFFF) == 0) { const UInt64 numBytes = tableOffset; - RINOK(openCallback->SetCompleted(NULL, &numBytes)); + RINOK(openCallback->SetCompleted(NULL, &numBytes)) } - - RINOK(stream->Seek(v, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf2, midSize)); - - const UInt64 end = v + midSize; - if (_phySize < end) - _phySize = end; + RINOK(InStream_SeekSet(stream, v)) + RINOK(ReadStream_FALSE(stream, buf2, midSize)) } for (size_t k = 0; k < midSize; k += 8) @@ -541,33 +595,30 @@ UInt64 offset = v & offsetMask; size_t dataSize = clusterSize; - if ((v & _compressedFlag) != 0) + if (v & _compressedFlag) { if (_version <= 1) { - unsigned numOffsetBits = (63 - _clusterBits); + const unsigned numOffsetBits = 63 - _clusterBits; dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; offset &= ((UInt64)1 << numOffsetBits) - 1; - dataSize = 0; - // offset >>= 9; - // offset <<= 9; + dataSize = 0; // why ? + // offset &= ~(((UInt64)1 << 9) - 1); } else { - unsigned numOffsetBits = (62 - (_clusterBits - 8)); + const unsigned numOffsetBits = 62 - (_clusterBits - 8); dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; - offset &= ((UInt64)1 << numOffsetBits) - 1; - offset >>= 9; - offset <<= 9; + offset &= ((UInt64)1 << numOffsetBits) - (1 << 9); } - _needDeflate = true; + _needCompression = true; } else { - UInt32 low = (UInt32)v & 511; - if (low != 0) + const UInt32 low = (UInt32)v & 511; + if (low) { - // version 3 support zero clusters + // version_3 supports zero clusters if (_version < 3 || low != 1) { _unsupported = true; @@ -578,17 +629,18 @@ const UInt64 end = offset + dataSize; if (_phySize < end) - _phySize = end; + _phySize = end; } } if (curTable != numTables) return E_FAIL; - if (_cryptMethod != 0) + if (_cryptMethod) _unsupported = true; - - if (_needDeflate && _version <= 1) // that case was not implemented + if (_needCompression && _version <= 1) // that case was not implemented + _unsupported = true; + if (_compressionType) _unsupported = true; Stream = stream; @@ -596,20 +648,25 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _table.Free(); _dir.Free(); + // _cache.Free(); + // _cacheCompressed.Free(); _phySize = 0; _cacheCluster = (UInt64)(Int64)-1; _comprPos = 0; _comprSize = 0; - _needDeflate = false; + _needCompression = false; _isArc = false; _unsupported = false; + _compressionType = 0; + _incompatFlags = 0; + // CHandlerImg: Clear_HandlerImg_Vars(); Stream.Release(); @@ -617,45 +674,26 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; - - if (_unsupported) + if (_unsupported || !Stream) return S_FALSE; - - if (_needDeflate) + if (_needCompression) { - if (_version <= 1) + if (_version <= 1 || _compressionType) return S_FALSE; - - if (!_bufInStream) - { - _bufInStreamSpec = new CBufInStream; - _bufInStream = _bufInStreamSpec; - } - - if (!_bufOutStream) - { - _bufOutStreamSpec = new CBufPtrSeqOutStream(); - _bufOutStream = _bufOutStreamSpec; - } - - if (!_deflateDecoder) - { - _deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder(); - _deflateDecoder = _deflateDecoderSpec; - _deflateDecoderSpec->Set_NeedFinishInput(true); - } - + _bufInStream.Create_if_Empty(); + _bufOutStream.Create_if_Empty(); + _deflateDecoder.Create_if_Empty(); + _deflateDecoder->Set_NeedFinishInput(true); const size_t clusterSize = (size_t)1 << _clusterBits; _cache.AllocAtLeast(clusterSize); _cacheCompressed.AllocAtLeast(clusterSize * 2); } - CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); + RINOK(InitAndSeek()) *stream = streamTemp.Detach(); return S_OK; COM_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.cpp 2022-05-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.cpp 2025-06-18 07:00:00.000000000 +0000 @@ -17,6 +17,7 @@ #include "../../Common/FilterCoder.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/MethodProps.h" #include "../../Common/ProgressUtils.h" #include "../../Common/RegisterArc.h" #include "../../Common/StreamObjects.h" @@ -28,12 +29,13 @@ #include "../../Crypto/Rar5Aes.h" -#include "../Common/FindSignature.h" -#include "../Common/ItemNameUtils.h" +#include "../../Archive/Common/FindSignature.h" +#include "../../Archive/Common/ItemNameUtils.h" +#include "../../Archive/Common/HandlerOut.h" -#include "../HandlerCont.h" +#include "../../Archive/HandlerCont.h" -#include "RarVol.h" +#include "../../Archive/Rar/RarVol.h" #include "Rar5Handler.h" using namespace NWindows; @@ -45,11 +47,12 @@ static const unsigned kMarkerSize = 8; -#define SIGNATURE { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0 } +static const Byte kMarker[kMarkerSize] = + { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0 }; -static const Byte kMarker[kMarkerSize] = SIGNATURE; - -static const size_t kCommentSize_Max = (size_t)1 << 16; +// Comment length is limited to 256 KB in rar-encoder. +// So we use same limitation +static const size_t kCommentSize_Max = (size_t)1 << 18; static const char * const kHostOS[] = @@ -105,34 +108,53 @@ static const char g_ExtraTimeFlags[] = { 'u', 'M', 'C', 'A', 'n' }; -static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val) -{ - *val = 0; - - for (unsigned i = 0; i < maxSize && i < 10;) +static +Z7_NO_INLINE +unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val_ptr) +{ + if (maxSize > 10) + maxSize = 10; + UInt64 val = 0; + unsigned i; + for (i = 0; i < maxSize;) { - Byte b = p[i]; - *val |= (UInt64)(b & 0x7F) << (7 * i); + const unsigned b = p[i]; + val |= (UInt64)(b & 0x7F) << (7 * i); i++; if ((b & 0x80) == 0) + { + *val_ptr = val; return i; + } } - return 0; + *val_ptr = 0; +#if 1 + return 0; // 7zip-unrar : strict check of error +#else + return i; // original-unrar : ignore error +#endif +} + + +#define PARSE_VAR_INT(p, size, dest) \ +{ const unsigned num_ = ReadVarInt(p, size, &dest); \ + if (num_ == 0) return false; \ + p += num_; \ + size -= num_; \ } bool CLinkInfo::Parse(const Byte *p, unsigned size) { const Byte *pStart = p; - unsigned num; UInt64 len; - num = ReadVarInt(p, size, &Type); if (num == 0) { return false; } p += num; size -= num; - num = ReadVarInt(p, size, &Flags); if (num == 0) { return false; } p += num; size -= num; - num = ReadVarInt(p, size, &len); if (num == 0) { return false; } p += num; size -= num; + PARSE_VAR_INT(p, size, Type) + PARSE_VAR_INT(p, size, Flags) + PARSE_VAR_INT(p, size, len) if (size != len) return false; NameLen = (unsigned)len; - NameOffset = (unsigned)(p - pStart); + NameOffset = (unsigned)(size_t)(p - pStart); return true; } @@ -175,7 +197,7 @@ { UInt64 size; - unsigned num = ReadVarInt(Extra + offset, rem, &size); + const unsigned num = ReadVarInt(Extra + offset, rem, &size); if (num == 0) return -1; offset += num; @@ -186,7 +208,7 @@ } { UInt64 id; - unsigned num = ReadVarInt(Extra + offset, rem, &id); + const unsigned num = ReadVarInt(Extra + offset, rem, &id); if (num == 0) return -1; offset += num; @@ -252,23 +274,23 @@ rem++; s.Add_Space_if_NotEmpty(); - PrintType(s, g_ExtraTypes, ARRAY_SIZE(g_ExtraTypes), id); + PrintType(s, g_ExtraTypes, Z7_ARRAY_SIZE(g_ExtraTypes), id); if (id == NExtraID::kTime) { const Byte *p = Extra + offset; UInt64 flags; - unsigned num = ReadVarInt(p, rem, &flags); + const unsigned num = ReadVarInt(p, rem, &flags); if (num != 0) { - s += ':'; - for (unsigned i = 0; i < ARRAY_SIZE(g_ExtraTimeFlags); i++) + s.Add_Colon(); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExtraTimeFlags); i++) if ((flags & ((UInt64)1 << i)) != 0) - s += g_ExtraTimeFlags[i]; - flags &= ~(((UInt64)1 << ARRAY_SIZE(g_ExtraTimeFlags)) - 1); + s.Add_Char(g_ExtraTimeFlags[i]); + flags &= ~(((UInt64)1 << Z7_ARRAY_SIZE(g_ExtraTimeFlags)) - 1); if (flags != 0) { - s += '_'; + s.Add_Char('_'); AddHex64(s, flags); } } @@ -278,20 +300,20 @@ CLinkInfo linkInfo; if (linkInfo.Parse(Extra + offset, (unsigned)rem)) { - s += ':'; - PrintType(s, g_LinkTypes, ARRAY_SIZE(g_LinkTypes), linkInfo.Type); + s.Add_Colon(); + PrintType(s, g_LinkTypes, Z7_ARRAY_SIZE(g_LinkTypes), linkInfo.Type); UInt64 flags = linkInfo.Flags; if (flags != 0) { - s += ':'; + s.Add_Colon(); if (flags & NLinkFlags::kTargetIsDir) { - s += 'D'; + s.Add_Char('D'); flags &= ~((UInt64)NLinkFlags::kTargetIsDir); } if (flags != 0) { - s += '_'; + s.Add_Char('_'); AddHex64(s, flags); } } @@ -311,19 +333,12 @@ Algo = 0; Flags = 0; Cnt = 0; - - unsigned num = ReadVarInt(p, size, &Algo); - if (num == 0) { return false; } p += num; size -= num; - - num = ReadVarInt(p, size, &Flags); - if (num == 0) { return false; } p += num; size -= num; - + PARSE_VAR_INT(p, size, Algo) + PARSE_VAR_INT(p, size, Flags) if (size > 0) Cnt = p[0]; - if (size != 1 + 16 + 16 + (unsigned)(IsThereCheck() ? 12 : 0)) return false; - return true; } @@ -331,30 +346,26 @@ bool CItem::FindExtra_Version(UInt64 &version) const { unsigned size; - int offset = FindExtra(NExtraID::kVersion, size); + const int offset = FindExtra(NExtraID::kVersion, size); if (offset < 0) return false; const Byte *p = Extra + (unsigned)offset; UInt64 flags; - unsigned num = ReadVarInt(p, size, &flags); - if (num == 0) { return false; } p += num; size -= num; - - num = ReadVarInt(p, size, &version); - if (num == 0) { return false; } p += num; size -= num; - + PARSE_VAR_INT(p, size, flags) + PARSE_VAR_INT(p, size, version) return size == 0; } bool CItem::FindExtra_Link(CLinkInfo &link) const { unsigned size; - int offset = FindExtra(NExtraID::kLink, size); + const int offset = FindExtra(NExtraID::kLink, size); if (offset < 0) return false; if (!link.Parse(Extra + (unsigned)offset, size)) return false; - link.NameOffset += offset; + link.NameOffset += (unsigned)offset; return true; } @@ -382,6 +393,7 @@ if (!FindExtra_Link(link)) return; + bool isWindows = (HostOS == kHost_Windows); if (link.Type != linkType) { if (linkType != NLinkType::kUnixSymLink) @@ -389,8 +401,11 @@ switch ((unsigned)link.Type) { case NLinkType::kUnixSymLink: + isWindows = false; + break; case NLinkType::kWinSymLink: case NLinkType::kWinJunction: + isWindows = true; break; default: return; } @@ -398,17 +413,22 @@ AString s; s.SetFrom_CalcLen((const char *)(Extra + link.NameOffset), link.NameLen); - UString unicode; ConvertUTF8ToUnicode(s, unicode); - prop = NItemName::GetOsPath(unicode); + // rar5.0 used '\\' separator for windows symlinks and \??\ prefix for abs paths. + // rar5.1+ uses '/' separator for windows symlinks and /??/ prefix for abs paths. + // v25.00: we convert Windows slashes to Linux slashes: + if (isWindows) + unicode.Replace(L'\\', L'/'); + prop = unicode; + // prop = NItemName::GetOsPath(unicode); } bool CItem::GetAltStreamName(AString &name) const { name.Empty(); unsigned size; - int offset = FindExtra(NExtraID::kSubdata, size); + const int offset = FindExtra(NExtraID::kSubdata, size); if (offset < 0) return false; name.SetFrom_CalcLen((const char *)(Extra + (unsigned)offset), size); @@ -421,8 +441,13 @@ bool _calcCRC; UInt32 _crc; int _blakeOffset; - CBlake2sp _blake; + CAlignedBuffer1 _buf; + // CBlake2sp _blake; + CBlake2sp *BlakeObj() { return (CBlake2sp *)(void *)(Byte *)_buf; } public: + CHash(): + _buf(sizeof(CBlake2sp)) + {} void Init_NoCalc() { @@ -435,17 +460,16 @@ void Update(const void *data, size_t size); UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } - bool Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoderSpec); + bool Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoder); }; void CHash::Init(const CItem &item) { _crc = CRC_INIT_VAL; _calcCRC = item.Has_CRC(); - _blakeOffset = item.FindExtra_Blake(); if (_blakeOffset >= 0) - Blake2sp_Init(&_blake); + Blake2sp_Init(BlakeObj()); } void CHash::Update(const void *data, size_t size) @@ -453,52 +477,48 @@ if (_calcCRC) _crc = CrcUpdate(_crc, data, size); if (_blakeOffset >= 0) - Blake2sp_Update(&_blake, (const Byte *)data, size); + Blake2sp_Update(BlakeObj(), (const Byte *)data, size); } -bool CHash::Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoderSpec) +bool CHash::Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoder) { if (_calcCRC) { UInt32 crc = GetCRC(); - if (cryptoDecoderSpec) - crc = cryptoDecoderSpec->Hmac_Convert_Crc32(crc); + if (cryptoDecoder) + crc = cryptoDecoder->Hmac_Convert_Crc32(crc); if (crc != item.CRC) return false; } - if (_blakeOffset >= 0) { - Byte digest[BLAKE2S_DIGEST_SIZE]; - Blake2sp_Final(&_blake, digest); - if (cryptoDecoderSpec) - cryptoDecoderSpec->Hmac_Convert_32Bytes(digest); - if (memcmp(digest, &item.Extra[(unsigned)_blakeOffset], BLAKE2S_DIGEST_SIZE) != 0) + UInt32 digest[Z7_BLAKE2S_DIGEST_SIZE / sizeof(UInt32)]; + Blake2sp_Final(BlakeObj(), (Byte *)(void *)digest); + if (cryptoDecoder) + cryptoDecoder->Hmac_Convert_32Bytes((Byte *)(void *)digest); + if (memcmp(digest, item.Extra + (unsigned)_blakeOffset, Z7_BLAKE2S_DIGEST_SIZE) != 0) return false; } - return true; } -class COutStreamWithHash: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _size_Defined; ISequentialOutStream *_stream; UInt64 _pos; UInt64 _size; - bool _size_Defined; Byte *_destBuf; public: CHash _hash; COutStreamWithHash(): _destBuf(NULL) {} - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void Init(const CItem &item, Byte *destBuf) + void Init(const CItem &item, Byte *destBuf, bool needChecksumCheck) { _size_Defined = false; _size = 0; @@ -510,18 +530,21 @@ _destBuf = destBuf; } _pos = 0; - _hash.Init(item); + if (needChecksumCheck) + _hash.Init(item); + else + _hash.Init_NoCalc(); } UInt64 GetPos() const { return _pos; } }; -STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_size_Defined) { - UInt64 rem = _size - _pos; + const UInt64 rem = _size - _pos; if (size > rem) size = (UInt32)rem; } @@ -547,10 +570,9 @@ size_t _bufPos; ISequentialInStream *_stream; - NCrypto::NRar5::CDecoder *m_CryptoDecoderSpec; - CMyComPtr m_CryptoDecoder; + CMyComPtr2 m_CryptoDecoder; - CLASS_NO_COPY(CInArchive) + Z7_CLASS_NO_COPY(CInArchive) HRESULT ReadStream_Check(void *data, size_t size); @@ -564,6 +586,10 @@ UInt64 StreamStartPosition; UInt64 Position; + size_t Get_Buf_RemainSize() const { return _bufSize - _bufPos; } + bool Is_Buf_Finished() const { return _bufPos == _bufSize; } + const Byte *Get_Buf_Data() const { return _buf + _bufPos; } + void Move_BufPos(size_t num) { _bufPos += num; } bool ReadVar(UInt64 &val); struct CHeader @@ -588,10 +614,10 @@ }; -static HRESULT MySetPassword(ICryptoGetTextPassword *getTextPassword, NCrypto::NRar5::CDecoder *cryptoDecoderSpec) +static HRESULT MySetPassword(ICryptoGetTextPassword *getTextPassword, NCrypto::NRar5::CDecoder *cryptoDecoder) { CMyComBSTR_Wipe password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); + RINOK(getTextPassword->CryptoGetTextPassword(&password)) AString_Wipe utf8; const unsigned kPasswordLen_MAX = 127; UString_Wipe unicode; @@ -599,15 +625,15 @@ if (unicode.Len() > kPasswordLen_MAX) unicode.DeleteFrom(kPasswordLen_MAX); ConvertUnicodeToUTF8(unicode, utf8); - cryptoDecoderSpec->SetPassword((const Byte *)(const char *)utf8, utf8.Len()); + cryptoDecoder->SetPassword((const Byte *)(const char *)utf8, utf8.Len()); return S_OK; } bool CInArchive::ReadVar(UInt64 &val) { - unsigned offset = ReadVarInt(_buf + _bufPos, _bufSize - _bufPos, &val); - _bufPos += offset; + const unsigned offset = ReadVarInt(Get_Buf_Data(), Get_Buf_RemainSize(), &val); + Move_BufPos(offset); return (offset != 0); } @@ -615,7 +641,7 @@ HRESULT CInArchive::ReadStream_Check(void *data, size_t size) { size_t size2 = size; - RINOK(ReadStream(_stream, data, &size2)); + RINOK(ReadStream(_stream, data, &size2)) if (size2 == size) return S_OK; UnexpectedEnd = true; @@ -630,61 +656,70 @@ h.ExtraSize = 0; h.DataSize = 0; - const unsigned kStartSize = 4 + 3; - const unsigned kBufSize = AES_BLOCK_SIZE + AES_BLOCK_SIZE; // must be >= kStartSize; - Byte buf[kBufSize]; + Byte buf[AES_BLOCK_SIZE]; unsigned filled; if (m_CryptoMode) { - RINOK(ReadStream_Check(buf, kBufSize)); - memcpy(m_CryptoDecoderSpec->_iv, buf, AES_BLOCK_SIZE); - RINOK(m_CryptoDecoderSpec->Init()); - - _buf.AllocAtLeast(1 << 12); + _buf.AllocAtLeast(1 << 12); // at least (AES_BLOCK_SIZE * 2) if (!(Byte *)_buf) return E_OUTOFMEMORY; - - memcpy(_buf, buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); - if (m_CryptoDecoderSpec->Filter(_buf, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) + RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2)) + memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE); + RINOK(m_CryptoDecoder->Init()) + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // data_size == 16 + if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) return E_FAIL; - memcpy(buf, _buf, AES_BLOCK_SIZE); + memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); filled = AES_BLOCK_SIZE; } else { - RINOK(ReadStream_Check(buf, kStartSize)); + const unsigned kStartSize = 4 + 3; + RINOK(ReadStream_Check(buf, kStartSize)) filled = kStartSize; } - UInt64 val; - unsigned offset = ReadVarInt(buf + 4, 3, &val); - if (offset == 0) - return S_FALSE; { + UInt64 val; + unsigned offset = ReadVarInt(buf + 4, 3, &val); + if (offset == 0) + return S_FALSE; size_t size = (size_t)val; - _bufPos = (4 + offset); - _bufSize = _bufPos + size; if (size < 2) return S_FALSE; - } - - size_t allocSize = _bufSize; - if (m_CryptoMode) - allocSize = (allocSize + AES_BLOCK_SIZE - 1) & ~(size_t)(AES_BLOCK_SIZE - 1); - _buf.AllocAtLeast(allocSize); - if (!(Byte *)_buf) - return E_OUTOFMEMORY; - - memcpy(_buf, buf, filled); - - size_t rem = allocSize - filled; - AddToSeekValue(allocSize + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); - RINOK(ReadStream_Check(_buf + filled, rem)); - if (m_CryptoMode) - { - if (m_CryptoDecoderSpec->Filter(_buf + filled, (UInt32)rem) != rem) - return E_FAIL; + offset += 4; + _bufPos = offset; + size += offset; + _bufSize = size; + if (m_CryptoMode) + size = (size + AES_BLOCK_SIZE - 1) & ~(size_t)(AES_BLOCK_SIZE - 1); + _buf.AllocAtLeast(size); + if (!(Byte *)_buf) + return E_OUTOFMEMORY; + memcpy(_buf, buf, filled); + const size_t rem = size - filled; + // if (m_CryptoMode), we add AES_BLOCK_SIZE here, because _iv is not included to size. + AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); + RINOK(ReadStream_Check(_buf + filled, rem)) + if (m_CryptoMode) + { + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // (rem) can be big + if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem) + return E_FAIL; +#if 1 + // optional 7zip-unrar check : remainder must contain zeros. + const size_t pad = size - _bufSize; + const Byte *p = _buf + _bufSize; + for (size_t i = 0; i < pad; i++) + if (p[i]) + return S_FALSE; +#endif + } } if (CrcCalc(_buf + 4, _bufSize - 4) != Get32(buf)) @@ -698,7 +733,7 @@ UInt64 extraSize; if (!ReadVar(extraSize)) return S_FALSE; - if (extraSize > _bufSize) + if (extraSize >= (1u << 21)) return S_FALSE; h.ExtraSize = (size_t)extraSize; } @@ -709,85 +744,117 @@ return S_FALSE; } + if (h.ExtraSize > Get_Buf_RemainSize()) + return S_FALSE; return S_OK; } -/* -int CInArcInfo::FindExtra(unsigned extraID, unsigned &recordDataSize) const +bool CInArcInfo::CLocator::Parse(const Byte *p, size_t size) { - recordDataSize = 0; - size_t offset = 0; - - for (;;) - { - size_t rem = Extra.Size() - offset; - if (rem == 0) - return -1; - - { - UInt64 size; - unsigned num = ReadVarInt(Extra + offset, rem, &size); - if (num == 0) - return -1; - offset += num; - rem -= num; - if (size > rem) - return -1; - rem = (size_t)size; - } - { - UInt64 id; - unsigned num = ReadVarInt(Extra + offset, rem, &id); - if (num == 0) - return -1; - offset += num; - rem -= num; + Flags = 0; + QuickOpen = 0; + Recovery = 0; - if (id == extraID) - { - recordDataSize = (unsigned)rem; - return (int)offset; - } + PARSE_VAR_INT(p, size, Flags) - offset += rem; - } + if (Is_QuickOpen()) + { + PARSE_VAR_INT(p, size, QuickOpen) + } + if (Is_Recovery()) + { + PARSE_VAR_INT(p, size, Recovery) } +#if 0 + // another records are possible in future rar formats. + if (size != 0) + return false; +#endif + return true; } -bool CInArcInfo::FindExtra_Locator(CLocator &locator) const +bool CInArcInfo::CMetadata::Parse(const Byte *p, size_t size) { - locator.Flags = 0; - locator.QuickOpen = 0; - locator.Recovery = 0; - - unsigned size; - int offset = FindExtra(kArcExtraRecordType_Locator, size); - if (offset < 0) - return false; - const Byte *p = Extra + (unsigned)offset; - - unsigned num; - - num = ReadVarInt(p, size, &locator.Flags); - if (num == 0) return false; p += num; size -= num; - - if (locator.Is_QuickOpen()) + PARSE_VAR_INT(p, size, Flags) + if (Flags & NMetadataFlags::kArcName) { - num = ReadVarInt(p, size, &locator.QuickOpen); - if (num == 0) return false; p += num; size -= num; + UInt64 nameLen; + PARSE_VAR_INT(p, size, nameLen) + if (nameLen > size) + return false; + ArcName.SetFrom_CalcLen((const char *)(const void *)p, (unsigned)nameLen); + p += (size_t)nameLen; + size -= (size_t)nameLen; + } + if (Flags & NMetadataFlags::kCTime) + { + if ((Flags & NMetadataFlags::kUnixTime) && + (Flags & NMetadataFlags::kNanoSec) == 0) + { + if (size < 4) + return false; + CTime = GetUi32(p); + p += 4; + size -= 4; + } + else + { + if (size < 8) + return false; + CTime = GetUi64(p); + p += 8; + size -= 8; + } } +#if 0 + // another records are possible in future rar formats. + if (size != 0) + return false; +#endif + return true; +} + - if (locator.Is_Recovery()) +bool CInArcInfo::ParseExtra(const Byte *p, size_t size) +{ + for (;;) { - num = ReadVarInt(p, size, &locator.Recovery); - if (num == 0) return false; p += num; size -= num; + if (size == 0) + return true; + UInt64 recSize64, id; + PARSE_VAR_INT(p, size, recSize64) + if (recSize64 > size) + return false; + size_t recSize = (size_t)recSize64; + size -= recSize; + // READ_VAR_INT(p, recSize, recSize) + { + const unsigned num = ReadVarInt(p, recSize, &id); + if (num == 0) + return false; + p += num; + recSize -= num; + } + if (id == kArcExtraRecordType_Metadata) + { + Metadata_Defined = true; + if (!Metadata.Parse(p, recSize)) + Metadata_Error = true; + } + else if (id == kArcExtraRecordType_Locator) + { + Locator_Defined = true; + if (!Locator.Parse(p, recSize)) + Locator_Error = true; + } + else + UnknownExtraRecord = true; + p += recSize; } - - return true; } -*/ + HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit, ICryptoGetTextPassword *getTextPassword, @@ -804,19 +871,19 @@ UInt64 arcStartPos = StreamStartPosition; { Byte marker[kMarkerSize]; - RINOK(ReadStream_FALSE(stream, marker, kMarkerSize)); + RINOK(ReadStream_FALSE(stream, marker, kMarkerSize)) if (memcmp(marker, kMarker, kMarkerSize) == 0) Position += kMarkerSize; else { if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) return S_FALSE; - RINOK(stream->Seek(StreamStartPosition, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, StreamStartPosition)) RINOK(FindSignatureInStream(stream, kMarker, kMarkerSize, - searchHeaderSizeLimit, arcStartPos)); + searchHeaderSizeLimit, arcStartPos)) arcStartPos += StreamStartPosition; Position = arcStartPos + kMarkerSize; - RINOK(stream->Seek(Position, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, Position)) } } @@ -824,7 +891,7 @@ _stream = stream; CHeader h; - RINOK(ReadBlockHeader(h)); + RINOK(ReadBlockHeader(h)) info.IsEncrypted = false; if (h.Type == NHeaderType::kArcEncrypt) @@ -833,27 +900,17 @@ IsArc = true; if (!getTextPassword) return E_NOTIMPL; - m_CryptoMode = true; - - if (!m_CryptoDecoder) - { - m_CryptoDecoderSpec = new NCrypto::NRar5::CDecoder; - m_CryptoDecoder = m_CryptoDecoderSpec; - } - - RINOK(m_CryptoDecoderSpec->SetDecoderProps( - _buf + _bufPos, (unsigned)(_bufSize - _bufPos), false, false)); - - RINOK(MySetPassword(getTextPassword, m_CryptoDecoderSpec)); - - if (!m_CryptoDecoderSpec->CalcKey_and_CheckPassword()) + m_CryptoDecoder.Create_if_Empty(); + RINOK(m_CryptoDecoder->SetDecoderProps( + Get_Buf_Data(), (unsigned)Get_Buf_RemainSize(), false, false)) + RINOK(MySetPassword(getTextPassword, m_CryptoDecoder.ClsPtr())) + if (!m_CryptoDecoder->CalcKey_and_CheckPassword()) { WrongPassword = True; return S_FALSE; } - - RINOK(ReadBlockHeader(h)); + RINOK(ReadBlockHeader(h)) } if (h.Type != NHeaderType::kArc) @@ -869,42 +926,29 @@ if (!ReadVar(info.VolNumber)) return S_FALSE; - if (h.ExtraSize != 0) + if (h.ExtraSize != Get_Buf_RemainSize()) + return S_FALSE; + if (h.ExtraSize) { - if (_bufSize - _bufPos < h.ExtraSize) - return S_FALSE; - /* - info.Extra.Alloc(h.ExtraSize); - memcpy(info.Extra, _buf + _bufPos, h.ExtraSize); - */ - _bufPos += h.ExtraSize; - - /* - CInArcInfo::CLocator locator; - if (info.FindExtra_Locator(locator)) - locator.Flags = locator.Flags; - */ + if (!info.ParseExtra(Get_Buf_Data(), h.ExtraSize)) + info.Extra_Error = true; } - - if (_bufPos != _bufSize) - return S_FALSE; - return S_OK; } bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item) { - item.UnixMTime = 0; - item.CRC = 0; - item.Flags = 0; - item.CommonFlags = (UInt32)header.Flags; item.PackSize = header.DataSize; + item.UnixMTime = 0; + item.CRC = 0; - UInt64 flags64; - if (!ReadVar(flags64)) return false; - item.Flags = (UInt32)flags64; + { + UInt64 flags64; + if (!ReadVar(flags64)) return false; + item.Flags = (UInt32)flags64; + } if (!ReadVar(item.Size)) return false; @@ -913,23 +957,20 @@ if (!ReadVar(attrib)) return false; item.Attrib = (UInt32)attrib; } - if (item.Has_UnixMTime()) { - if (_bufSize - _bufPos < 4) + if (Get_Buf_RemainSize() < 4) return false; - item.UnixMTime = Get32(_buf + _bufPos); - _bufPos += 4; + item.UnixMTime = Get32(Get_Buf_Data()); + Move_BufPos(4); } - if (item.Has_CRC()) { - if (_bufSize - _bufPos < 4) + if (Get_Buf_RemainSize() < 4) return false; - item.CRC = Get32(_buf + _bufPos); - _bufPos += 4; + item.CRC = Get32(Get_Buf_Data()); + Move_BufPos(4); } - { UInt64 method; if (!ReadVar(method)) return false; @@ -941,25 +982,24 @@ { UInt64 len; if (!ReadVar(len)) return false; - if (len > _bufSize - _bufPos) + if (len > Get_Buf_RemainSize()) return false; - item.Name.SetFrom_CalcLen((const char *)(_buf + _bufPos), (unsigned)len); - _bufPos += (unsigned)len; + item.Name.SetFrom_CalcLen((const char *)Get_Buf_Data(), (unsigned)len); + Move_BufPos((size_t)len); } item.Extra.Free(); - size_t extraSize = header.ExtraSize; + const size_t extraSize = header.ExtraSize; if (extraSize != 0) { - if (_bufSize - _bufPos < extraSize) + if (Get_Buf_RemainSize() < extraSize) return false; item.Extra.Alloc(extraSize); - memcpy(item.Extra, _buf + _bufPos, extraSize); - _bufPos += extraSize; + memcpy(item.Extra, Get_Buf_Data(), extraSize); + Move_BufPos(extraSize); } - - return (_bufPos == _bufSize); + return Is_Buf_Finished(); } @@ -978,94 +1018,84 @@ struct CUnpacker { - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr copyCoder; - + CMyComPtr2 copyCoder; CMyComPtr LzCoders[2]; bool SolidAllowed; - + bool NeedCrc; CFilterCoder *filterStreamSpec; CMyComPtr filterStream; - - NCrypto::NRar5::CDecoder *cryptoDecoderSpec; - CMyComPtr cryptoDecoder; - + CMyComPtr2 cryptoDecoder; CMyComPtr getTextPassword; - - COutStreamWithHash *outStreamSpec; - CMyComPtr outStream; + CMyComPtr2 outStream; CByteBuffer _tempBuf; - CLinkFile *linkFile; - CUnpacker(): linkFile(NULL) { SolidAllowed = false; } + CUnpacker(): linkFile(NULL) { SolidAllowed = false; NeedCrc = true; } - HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword); + HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, bool isSolid, bool &wrongPassword); HRESULT Code(const CItem &item, const CItem &lastItem, UInt64 packSize, ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress, bool &isCrcOK); - HRESULT DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer); + HRESULT DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer); }; static const unsigned kLzMethodMax = 5; -HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword) +HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, bool isSolid, bool &wrongPassword) { wrongPassword = false; - if (item.GetAlgoVersion() != 0) + if (item.Get_AlgoVersion_RawBits() > 1) return E_NOTIMPL; - if (!outStream) - { - outStreamSpec = new COutStreamWithHash; - outStream = outStreamSpec; - } + outStream.Create_if_Empty(); - unsigned method = item.GetMethod(); + const unsigned method = item.Get_Method(); if (method == 0) - { - if (!copyCoder) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } - } + copyCoder.Create_if_Empty(); else { if (method > kLzMethodMax) return E_NOTIMPL; - /* if (item.IsSplitBefore()) return S_FALSE; */ - - int lzIndex = item.IsService() ? 1 : 0; + const unsigned lzIndex = item.IsService() ? 1 : 0; CMyComPtr &lzCoder = LzCoders[lzIndex]; - if (!lzCoder) { const UInt32 methodID = 0x40305; - RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder)); + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder)) if (!lzCoder) return E_NOTIMPL; } CMyComPtr csdp; - RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)); - - Byte props[2] = { (Byte)(item.GetDictSize()), (Byte)(isSolid ? 1 : 0) }; - RINOK(csdp->SetDecoderProperties2(props, 2)); + RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)) + if (!csdp) + return E_NOTIMPL; + const unsigned ver = item.Get_AlgoVersion_HuffRev(); + if (ver > 1) + return E_NOTIMPL; + const Byte props[2] = + { + (Byte)item.Get_DictSize_Main(), + (Byte)((item.Get_DictSize_Frac() << 3) + (ver << 1) + (isSolid ? 1 : 0)) + }; + RINOK(csdp->SetDecoderProperties2(props, 2)) } unsigned cryptoSize = 0; - int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); + const int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); if (cryptoOffset >= 0) { @@ -1075,13 +1105,9 @@ filterStream = filterStreamSpec; } - if (!cryptoDecoder) - { - cryptoDecoderSpec = new NCrypto::NRar5::CDecoder; - cryptoDecoder = cryptoDecoderSpec; - } + cryptoDecoder.Create_if_Empty(); - RINOK(cryptoDecoderSpec->SetDecoderProps(item.Extra + (unsigned)cryptoOffset, cryptoSize, true, item.IsService())); + RINOK(cryptoDecoder->SetDecoderProps(item.Extra + (unsigned)cryptoOffset, cryptoSize, true, item.IsService())) if (!getTextPassword) { @@ -1089,9 +1115,9 @@ return E_NOTIMPL; } - RINOK(MySetPassword(getTextPassword, cryptoDecoderSpec)); + RINOK(MySetPassword(getTextPassword, cryptoDecoder.ClsPtr())) - if (!cryptoDecoderSpec->CalcKey_and_CheckPassword()) + if (!cryptoDecoder->CalcKey_and_CheckPassword()) wrongPassword = True; } @@ -1105,15 +1131,15 @@ { isCrcOK = true; - unsigned method = item.GetMethod(); + const unsigned method = item.Get_Method(); if (method > kLzMethodMax) return E_NOTIMPL; - bool needBuf = (linkFile && linkFile->NumLinks != 0); + const bool needBuf = (linkFile && linkFile->NumLinks != 0); if (needBuf && !lastItem.Is_UnknownSize()) { - size_t dataSize = (size_t)lastItem.Size; + const size_t dataSize = (size_t)lastItem.Size; if (dataSize != lastItem.Size) return E_NOTIMPL; linkFile->Data.Alloc(dataSize); @@ -1133,10 +1159,12 @@ else inStream = volsInStream; - ICompressCoder *commonCoder = (method == 0) ? copyCoder : LzCoders[item.IsService() ? 1 : 0]; + ICompressCoder *commonCoder = (method == 0) ? + copyCoder.Interface() : + LzCoders[item.IsService() ? 1 : 0].Interface(); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL)); + outStream->SetStream(realOutStream); + outStream->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL), NeedCrc); HRESULT res = S_OK; if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0) @@ -1154,25 +1182,24 @@ if (isCryptoMode) filterStreamSpec->ReleaseInStream(); - UInt64 processedSize = outStreamSpec->GetPos(); + const UInt64 processedSize = outStream->GetPos(); if (res == S_OK && !lastItem.Is_UnknownSize() && processedSize != lastItem.Size) res = S_FALSE; // if (res == S_OK) { unsigned cryptoSize = 0; - int cryptoOffset = lastItem.FindExtra(NExtraID::kCrypto, cryptoSize); + const int cryptoOffset = lastItem.FindExtra(NExtraID::kCrypto, cryptoSize); NCrypto::NRar5::CDecoder *crypto = NULL; - if (cryptoOffset >= 0) { CCryptoInfo cryptoInfo; if (cryptoInfo.Parse(lastItem.Extra + (unsigned)cryptoOffset, cryptoSize)) if (cryptoInfo.UseMAC()) - crypto = cryptoDecoderSpec; + crypto = cryptoDecoder.ClsPtr(); } - - isCrcOK = outStreamSpec->_hash.Check(lastItem, crypto); + if (NeedCrc) + isCrcOK = outStream->_hash.Check(lastItem, crypto); } if (linkFile) @@ -1189,12 +1216,14 @@ } -HRESULT CUnpacker::DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer) +HRESULT CUnpacker::DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, UInt64 packSize, + ISequentialInStream *inStream, + CByteBuffer &buffer) { - CBufPtrSeqOutStream *outSpec = new CBufPtrSeqOutStream; - CMyComPtr out = outSpec; + CMyComPtr2_Create out; _tempBuf.AllocAtLeast((size_t)item.Size); - outSpec->Init(_tempBuf, (size_t)item.Size); + out->Init(_tempBuf, (size_t)item.Size); bool wrongPassword; @@ -1208,16 +1237,15 @@ if (wrongPassword) return S_FALSE; - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; - CMyComPtr limitedStream(limitedStreamSpec); - limitedStreamSpec->SetStream(inStream); - limitedStreamSpec->Init(packSize); + CMyComPtr2_Create limitedStream; + limitedStream->SetStream(inStream); + limitedStream->Init(packSize); bool crcOK = true; res = Code(item, item, packSize, limitedStream, out, NULL, crcOK); if (res == S_OK) { - if (!crcOK || outSpec->GetPos() != item.Size) + if (!crcOK || out->GetPos() != item.Size) res = S_FALSE; else buffer.CopyFrom(_tempBuf, (size_t)item.Size); @@ -1244,7 +1272,9 @@ HRESULT Decode(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, - ISequentialInStream *inStream, CUnpacker &unpacker, CByteBuffer &destBuf); + ISequentialInStream *inStream, + CUnpacker &unpacker, + CByteBuffer &destBuf); }; @@ -1273,7 +1303,7 @@ _buf.ChangeSize_KeepData(newSize, _offset); Byte *data = (Byte *)_buf + _offset; - RINOK(ReadStream_FALSE(inStream, data, packSize)); + RINOK(ReadStream_FALSE(inStream, data, packSize)) _offset += packSize; @@ -1293,15 +1323,14 @@ if (_offset == 0) { RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS - item, item.PackSize, inStream, destBuf)); + item, item.PackSize, inStream, destBuf)) } else { - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - bufInStreamSpec->Init(_buf, _offset); + CMyComPtr2_Create bufInStream; + bufInStream->Init(_buf, _offset); RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS - item, _offset, bufInStream, destBuf)); + item, _offset, bufInStream, destBuf)) } } } @@ -1321,6 +1350,7 @@ kpidCTime, kpidATime, kpidAttrib, + // kpidPosixAttrib, // for debug kpidIsAltStream, kpidEncrypted, @@ -1343,12 +1373,15 @@ { kpidTotalPhySize, kpidCharacts, + kpidEncrypted, kpidSolid, kpidNumBlocks, - kpidEncrypted, + kpidMethod, kpidIsVolume, kpidVolumeIndex, kpidNumVolumes, + kpidName, + kpidCTime, kpidComment }; @@ -1367,12 +1400,23 @@ size += item.PackSize; if (item.NextItem < 0) return size; - index = item.NextItem; + index = (unsigned)item.NextItem; } } +static char *PrintDictSize(char *s, UInt64 w) +{ + char c = 'K'; w >>= 10; + if ((w & ((1 << 10) - 1)) == 0) { c = 'M'; w >>= 10; + if ((w & ((1 << 10) - 1)) == 0) { c = 'G'; w >>= 10; }} + s = ConvertUInt64ToString(w, s); + *s++ = c; + *s = 0; + return s; +} + -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN @@ -1388,10 +1432,69 @@ case kpidSolid: if (arcInfo) prop = arcInfo->IsSolid(); break; case kpidCharacts: { - if (!_arcs.IsEmpty()) + AString s; + if (arcInfo) + { + s = FlagsToString(k_ArcFlags, Z7_ARRAY_SIZE(k_ArcFlags), (UInt32)arcInfo->Flags); + if (arcInfo->Extra_Error) + s.Add_OptSpaced("Extra-ERROR"); + if (arcInfo->UnsupportedFeature) + s.Add_OptSpaced("unsupported-feature"); + if (arcInfo->Metadata_Defined) + { + s.Add_OptSpaced("Metadata"); + if (arcInfo->Metadata_Error) + s += "-ERROR"; + else + { + if (arcInfo->Metadata.Flags & NMetadataFlags::kArcName) + s.Add_OptSpaced("arc-name"); + if (arcInfo->Metadata.Flags & NMetadataFlags::kCTime) + { + s.Add_OptSpaced("ctime-"); + s += + (arcInfo->Metadata.Flags & NMetadataFlags::kUnixTime) ? + (arcInfo->Metadata.Flags & NMetadataFlags::kNanoSec) ? + "1ns" : "1s" : "win"; + } + } + } + if (arcInfo->Locator_Defined) + { + s.Add_OptSpaced("Locator"); + if (arcInfo->Locator_Error) + s += "-ERROR"; + else + { + if (arcInfo->Locator.Is_QuickOpen()) + { + s.Add_OptSpaced("QuickOpen:"); + s.Add_UInt64(arcInfo->Locator.QuickOpen); + } + if (arcInfo->Locator.Is_Recovery()) + { + s.Add_OptSpaced("Recovery:"); + s.Add_UInt64(arcInfo->Locator.Recovery); + } + } + } + if (arcInfo->UnknownExtraRecord) + s.Add_OptSpaced("Unknown-Extra-Record"); + + } + if (_comment_WasUsedInArc) { - FLAGS_TO_PROP(k_ArcFlags, (UInt32)arcInfo->Flags, prop); + s.Add_OptSpaced("Comment"); + // s.Add_UInt32((UInt32)_comment.Size()); } + // + if (_acls.Size() != 0) + { + s.Add_OptSpaced("ACL"); + // s.Add_UInt32(_acls.Size()); + } + if (!s.IsEmpty()) + prop = s; break; } case kpidEncrypted: if (arcInfo) prop = arcInfo->IsEncrypted; break; // it's for encrypted names. @@ -1418,13 +1521,55 @@ break; } + case kpidName: + if (arcInfo) + if (!arcInfo->Metadata_Error + && !arcInfo->Metadata.ArcName.IsEmpty()) + { + UString s; + if (ConvertUTF8ToUnicode(arcInfo->Metadata.ArcName, s)) + prop = s; + } + break; + + case kpidCTime: + if (arcInfo) + if (!arcInfo->Metadata_Error + && (arcInfo->Metadata.Flags & NMetadataFlags::kCTime)) + { + const UInt64 ct = arcInfo->Metadata.CTime; + if (arcInfo->Metadata.Flags & NMetadataFlags::kUnixTime) + { + if (arcInfo->Metadata.Flags & NMetadataFlags::kNanoSec) + { + const UInt64 sec = ct / 1000000000; + const UInt64 ns = ct % 1000000000; + UInt64 wt = NTime::UnixTime64_To_FileTime64((Int64)sec); + wt += ns / 100; + const unsigned ns100 = (unsigned)(ns % 100); + FILETIME ft; + ft.dwLowDateTime = (DWORD)(UInt32)wt; + ft.dwHighDateTime = (DWORD)(UInt32)(wt >> 32); + prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, ns100); + } + else + { + const UInt64 wt = NTime::UnixTime64_To_FileTime64((Int64)ct); + prop.SetAsTimeFrom_Ft64_Prec(wt, k_PropVar_TimePrec_Unix); + } + } + else + prop.SetAsTimeFrom_Ft64_Prec(ct, k_PropVar_TimePrec_100ns); + } + break; + case kpidComment: { // if (!_arcs.IsEmpty()) { // const CArc &arc = _arcs[0]; const CByteBuffer &cmt = _comment; - if (cmt.Size() != 0 && cmt.Size() < (1 << 16)) + if (cmt.Size() != 0 /* && cmt.Size() < (1 << 16) */) { AString s; s.SetFrom_CalcLen((const char *)(const Byte *)cmt, (unsigned)cmt.Size()); @@ -1438,11 +1583,48 @@ case kpidNumBlocks: { - UInt32 numBlocks = 0; - FOR_VECTOR (i, _refs) - if (!_items[_refs[i].Item].IsSolid()) - numBlocks++; - prop = (UInt32)numBlocks; + prop = (UInt32)_numBlocks; + break; + } + + case kpidMethod: + { + AString s; + + UInt64 algo = _algo_Mask; + for (unsigned v = 0; algo != 0; v++, algo >>= 1) + { + if ((algo & 1) == 0) + continue; + s.Add_OptSpaced("v"); + s.Add_UInt32(v + 6); + if (v < Z7_ARRAY_SIZE(_methodMasks)) + { + const UInt64 dict = _dictMaxSizes[v]; + if (dict) + { + char temp[24]; + temp[0] = ':'; + PrintDictSize(temp + 1, dict); + s += temp; + } + unsigned method = _methodMasks[v]; + for (unsigned m = 0; method; m++, method >>= 1) + { + if ((method & 1) == 0) + continue; + s += ":m"; + s.Add_UInt32(m); + } + } + } + if (_rar5comapt_mask & 2) + { + s += ":c"; + if (_rar5comapt_mask & 1) + s.Add_Char('n'); + } + prop = s; break; } @@ -1462,6 +1644,10 @@ UInt32 v = _errorFlags; if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_error_in_ACL) + v |= kpv_ErrorFlags_HeadersError; + if (_split_Error) + v |= kpv_ErrorFlags_HeadersError; prop = v; break; } @@ -1483,7 +1669,7 @@ AString s ("part"); UInt32 v = (UInt32)arcInfo->GetVolIndex() + 1; if (v < 10) - s += '0'; + s.Add_Char('0'); s.Add_UInt32(v); s += ".rar"; prop = s; @@ -1501,9 +1687,9 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { - *numItems = _refs.Size(); + *numItems = (UInt32)_refs.Size(); return S_OK; } @@ -1515,20 +1701,20 @@ }; -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { - *numProps = ARRAY_SIZE(kRawProps); + *numProps = Z7_ARRAY_SIZE(kRawProps); return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) { *propID = kRawProps[index]; - *name = 0; + *name = NULL; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; @@ -1549,7 +1735,7 @@ } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -1574,13 +1760,21 @@ if (propID == kpidChecksum) { - int hashRecOffset = item.FindExtra_Blake(); + const int hashRecOffset = item.FindExtra_Blake(); if (hashRecOffset >= 0) { - *dataSize = BLAKE2S_DIGEST_SIZE; + *dataSize = Z7_BLAKE2S_DIGEST_SIZE; + *propType = NPropDataType::kRaw; + *data = item.Extra + (unsigned)hashRecOffset; + } + /* + else if (item.Has_CRC() && item.IsEncrypted()) + { + *dataSize = 4; *propType = NPropDataType::kRaw; - *data = &item.Extra[hashRecOffset]; + *data = &item->CRC; // we must show same value for big/little endian here } + */ return S_OK; } @@ -1597,6 +1791,7 @@ const Byte *p = item.Extra + (unsigned)offset; UInt64 flags; + // PARSE_VAR_INT(p, size, flags) { const unsigned num = ReadVarInt(p, size, &flags); if (num == 0) @@ -1660,7 +1855,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN @@ -1680,14 +1875,14 @@ AString s; if (ref.Parent >= 0) { - CItem &mainItem = _items[_refs[ref.Parent].Item]; + const CItem &mainItem = _items[_refs[ref.Parent].Item]; s = mainItem.Name; } AString name; item.GetAltStreamName(name); if (name[0] != ':') - s += ':'; + s.Add_Colon(); s += name; ConvertUTF8ToUnicode(s, unicodeName); } @@ -1717,7 +1912,7 @@ case kpidIsDir: prop = item.IsDir(); break; case kpidSize: if (!lastItem.Is_UnknownSize()) prop = lastItem.Size; break; - case kpidPackSize: prop = GetPackSize(index); break; + case kpidPackSize: prop = GetPackSize((unsigned)index); break; case kpidMTime: { @@ -1760,6 +1955,11 @@ case kpidCopyLink: item.Link_to_Prop(NLinkType::kFileCopy, prop); break; case kpidAttrib: prop = item.GetWinAttrib(); break; + case kpidPosixAttrib: + if (item.HostOS == kHost_Unix) + prop = (UInt32)item.Attrib; + break; + case kpidEncrypted: prop = item.IsEncrypted(); break; case kpidSolid: prop = item.IsSolid(); break; @@ -1780,7 +1980,9 @@ case kpidCRC: { const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem); - if (item2->Has_CRC()) + // we don't want to show crc for encrypted file here, + // because crc is also encrrypted. + if (item2->Has_CRC() && !item2->IsEncrypted()) prop = item2->CRC; break; } @@ -1788,56 +1990,61 @@ case kpidMethod: { char temp[128]; - unsigned algo = item.GetAlgoVersion(); + const unsigned algo = item.Get_AlgoVersion_RawBits(); char *s = temp; - if (algo != 0) + // if (algo != 0) { - ConvertUInt32ToString(algo, s); - s += MyStringLen(s); + *s++ = 'v'; + s = ConvertUInt32ToString((UInt32)algo + 6, s); + if (item.Is_Rar5_Compat()) + *s++ = 'c'; *s++ = ':'; } - unsigned m = item.GetMethod(); { - s[0] = 'm'; - s[1] = (char)(m + '0'); - s[2] = 0; + const unsigned m = item.Get_Method(); + *s++ = 'm'; + *s++ = (char)(m + '0'); if (!item.IsDir()) { - s[2] = ':'; - ConvertUInt32ToString(item.GetDictSize() + 17, s + 3); + *s++ = ':'; + const unsigned dictMain = item.Get_DictSize_Main(); + const unsigned frac = item.Get_DictSize_Frac(); + /* + if (frac == 0 && algo == 0) + s = ConvertUInt32ToString(dictMain + 17, s); + else + */ + s = PrintDictSize(s, (UInt64)(32 + frac) << (12 + dictMain)); + if (item.Is_Rar5_Compat()) + { + *s++ = ':'; + *s++ = 'c'; + } } } - unsigned cryptoSize = 0; - int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); + const int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); if (cryptoOffset >= 0) { - s = temp + strlen(temp); *s++ = ' '; - CCryptoInfo cryptoInfo; - - bool isOK = cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize); - + const bool isOK = cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize); if (cryptoInfo.Algo == 0) s = MyStpCpy(s, "AES"); else { s = MyStpCpy(s, "Crypto_"); - ConvertUInt64ToString(cryptoInfo.Algo, s); - s += strlen(s); + s = ConvertUInt64ToString(cryptoInfo.Algo, s); } - if (isOK) { *s++ = ':'; - ConvertUInt32ToString(cryptoInfo.Cnt, s); - s += strlen(s); + s = ConvertUInt32ToString(cryptoInfo.Cnt, s); *s++ = ':'; - ConvertUInt64ToString(cryptoInfo.Flags, s); + s = ConvertUInt64ToString(cryptoInfo.Flags, s); } } - + *s = 0; prop = temp; break; } @@ -1847,20 +2054,14 @@ AString s; if (item.ACL >= 0) - { s.Add_OptSpaced("ACL"); - } - - UInt32 flags = item.Flags; - // flags &= ~(6); // we don't need compression related bits here. + const UInt32 flags = item.Flags; if (flags != 0) { - AString s2 = FlagsToString(k_FileFlags, ARRAY_SIZE(k_FileFlags), flags); + const AString s2 = FlagsToString(k_FileFlags, Z7_ARRAY_SIZE(k_FileFlags), flags); if (!s2.IsEmpty()) - { s.Add_OptSpaced(s2); - } } item.PrintInfo(s); @@ -1872,7 +2073,7 @@ case kpidHostOS: - if (item.HostOS < ARRAY_SIZE(kHostOS)) + if (item.HostOS < Z7_ARRAY_SIZE(kHostOS)) prop = kHostOS[(size_t)item.HostOS]; else prop = (UInt64)item.HostOS; @@ -1898,7 +2099,7 @@ { if (!item2.Version_Defined) return -1; - int res = MyCompare(item1.Version, item2.Version); + const int res = MyCompare(item1.Version, item2.Version); if (res != 0) return res; } @@ -1912,7 +2113,7 @@ static int CompareItemsPaths2(const CHandler &handler, unsigned p1, unsigned p2, const AString *name1) { - int res = CompareItemsPaths(handler, p1, p2, name1); + const int res = CompareItemsPaths(handler, p1, p2, name1); if (res != 0) return res; return MyCompare(p1, p2); @@ -1933,24 +2134,24 @@ { if (left > 0) { - unsigned refIndex = sorted[left - 1]; + const unsigned refIndex = sorted[left - 1]; if (CompareItemsPaths(handler, index, refIndex, &s) == 0) - return refIndex; + return (int)refIndex; } if (right < sorted.Size()) { - unsigned refIndex = sorted[right]; + const unsigned refIndex = sorted[right]; if (CompareItemsPaths(handler, index, refIndex, &s) == 0) - return refIndex; + return (int)refIndex; } return -1; } - unsigned mid = (left + right) / 2; - unsigned refIndex = sorted[mid]; - int compare = CompareItemsPaths2(handler, index, refIndex, &s); + const unsigned mid = (left + right) / 2; + const unsigned refIndex = sorted[mid]; + const int compare = CompareItemsPaths2(handler, index, refIndex, &s); if (compare == 0) - return refIndex; + return (int)refIndex; if (compare < 0) right = mid; else @@ -1961,15 +2162,34 @@ void CHandler::FillLinks() { unsigned i; - + + bool need_FillLinks = false; + for (i = 0; i < _refs.Size(); i++) { const CItem &item = _items[_refs[i].Item]; - if (!item.IsDir() && !item.IsService() && item.NeedUse_as_CopyLink()) - break; + if (!item.IsDir() + && !item.IsService() + && item.NeedUse_as_CopyLink()) + need_FillLinks = true; + + if (!item.IsSolid()) + _numBlocks++; + + const unsigned algo = item.Get_AlgoVersion_RawBits(); + _algo_Mask |= (UInt64)1 << algo; + _rar5comapt_mask |= 1u << item.Get_Rar5_CompatBit(); + if (!item.IsDir() && algo < Z7_ARRAY_SIZE(_methodMasks)) + { + _methodMasks[algo] |= 1u << (item.Get_Method()); + UInt64 d = 32 + item.Get_DictSize_Frac(); + d <<= (12 + item.Get_DictSize_Main()); + if (_dictMaxSizes[algo] < d) + _dictMaxSizes[algo] = d; + } } - if (i == _refs.Size()) + if (!need_FillLinks) return; CUIntVector sorted; @@ -1997,7 +2217,7 @@ if (!item.FindExtra_Link(linkInfo) || linkInfo.Type != NLinkType::kFileCopy) continue; link.SetFrom_CalcLen((const char *)(item.Extra + linkInfo.NameOffset), linkInfo.NameLen); - int linkIndex = FindLink(*this, sorted, link, i); + const int linkIndex = FindLink(*this, sorted, link, i); if (linkIndex < 0) continue; if ((unsigned)linkIndex >= i) @@ -2021,30 +2241,24 @@ IArchiveOpenCallback *openCallback) { CMyComPtr openVolumeCallback; - CMyComPtr getTextPassword; - + // CMyComPtr getTextPassword; NRar::CVolumeName seqName; - - UInt64 totalBytes = 0; - UInt64 curBytes = 0; + CTempBuf tempBuf; + CUnpacker unpacker; if (openCallback) { openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&unpacker.getTextPassword); } + // unpacker.getTextPassword = getTextPassword; - CTempBuf tempBuf; - - CUnpacker unpacker; - unpacker.getTextPassword = getTextPassword; - + CInArchive arch; int prevSplitFile = -1; int prevMainFile = -1; - + UInt64 totalBytes = 0; + UInt64 curBytes = 0; bool nextVol_is_Required = false; - - CInArchive arch; for (;;) { @@ -2056,13 +2270,12 @@ { if (!openVolumeCallback) break; - if (_arcs.Size() == 1) { UString baseName; { NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) break; baseName = prop.bstrVal; @@ -2070,14 +2283,10 @@ if (!seqName.InitName(baseName)) break; } - const UString volName = seqName.GetNextName(); - - HRESULT result = openVolumeCallback->GetStream(volName, &inStream); - + const HRESULT result = openVolumeCallback->GetStream(volName, &inStream); if (result != S_OK && result != S_FALSE) return result; - if (!inStream || result != S_OK) { if (nextVol_is_Required) @@ -2087,39 +2296,34 @@ } UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &arch.StreamStartPosition)); - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(arch.StreamStartPosition, STREAM_SEEK_SET, NULL)); + RINOK(InStream_GetPos_GetSize(inStream, arch.StreamStartPosition, endPos)) if (openCallback) { totalBytes += endPos; - RINOK(openCallback->SetTotal(NULL, &totalBytes)); - } - - CInArcInfo arcInfoOpen; - { - HRESULT res = arch.Open(inStream, maxCheckStartPosition, getTextPassword, arcInfoOpen); - if (arch.IsArc && arch.UnexpectedEnd) - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - if (_arcs.IsEmpty()) - { - _isArc = arch.IsArc; + RINOK(openCallback->SetTotal(NULL, &totalBytes)) } - if (res != S_OK) + CInArcInfo arcInfo_Open; { - if (res != S_FALSE) - return res; + const HRESULT res = arch.Open(inStream, maxCheckStartPosition, unpacker.getTextPassword, arcInfo_Open); + if (arch.IsArc && arch.UnexpectedEnd) + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; if (_arcs.IsEmpty()) - return res; - break; - } + _isArc = arch.IsArc; + if (res != S_OK) + { + if (res != S_FALSE) + return res; + if (_arcs.IsEmpty()) + return res; + break; + } } CArc &arc = _arcs.AddNew(); CInArcInfo &arcInfo = arc.Info; - arcInfo = arcInfoOpen; + arcInfo = arcInfo_Open; arc.Stream = inStream; CItem item; @@ -2129,18 +2333,16 @@ item.Clear(); arcInfo.EndPos = arch.Position; - if (arch.Position > endPos) { _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; break; } - - RINOK(inStream->Seek(arch.Position, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, arch.Position)) { CInArchive::CHeader h; - HRESULT res = arch.ReadBlockHeader(h); + const HRESULT res = arch.ReadBlockHeader(h); if (res != S_OK) { if (res != S_FALSE) @@ -2149,9 +2351,9 @@ { _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; if (arcInfo.EndPos < arch.Position) - arcInfo.EndPos = arch.Position; + arcInfo.EndPos = arch.Position; if (arcInfo.EndPos < endPos) - arcInfo.EndPos = endPos; + arcInfo.EndPos = endPos; } else _errorFlags |= kpv_ErrorFlags_HeadersError; @@ -2164,15 +2366,17 @@ arcInfo.EndOfArchive_was_Read = true; if (!arch.ReadVar(arcInfo.EndFlags)) _errorFlags |= kpv_ErrorFlags_HeadersError; + if (!arch.Is_Buf_Finished() || h.ExtraSize || h.DataSize) + arcInfo.UnsupportedFeature = true; if (arcInfo.IsVolume()) { // for multivolume archives RAR can add ZERO bytes at the end for alignment. // We must skip these bytes to prevent phySize warning. - RINOK(inStream->Seek(arcInfo.EndPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, arcInfo.EndPos)) bool areThereNonZeros; UInt64 numZeros; const UInt64 maxSize = 1 << 12; - RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); + RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)) if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) arcInfo.EndPos += numZeros; } @@ -2187,14 +2391,11 @@ } item.RecordType = (Byte)h.Type; - if (!arch.ReadFileHeader(h, item)) { _errorFlags |= kpv_ErrorFlags_HeadersError; break; } - - // item.MainPartSize = (UInt32)(Position - item.Position); item.DataPos = arch.Position; } @@ -2206,7 +2407,7 @@ isOk_packSize = false; _errorFlags |= kpv_ErrorFlags_HeadersError; if (arcInfo.EndPos < endPos) - arcInfo.EndPos = endPos; + arcInfo.EndPos = endPos; } else { @@ -2216,29 +2417,32 @@ } bool needAdd = true; - + + if (!_comment_WasUsedInArc + && _comment.Size() == 0 + && item.Is_CMT()) { - if (_comment.Size() == 0 - && item.Is_CMT() - && item.PackSize < kCommentSize_Max + _comment_WasUsedInArc = true; + if ( item.PackSize <= kCommentSize_Max && item.PackSize == item.Size && item.PackSize != 0 - && item.GetMethod() == 0 + && item.Get_Method() == 0 && !item.IsSplit()) { - RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_VARS item, item.PackSize, inStream, _comment)); + RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_VARS item, item.PackSize, inStream, _comment)) needAdd = false; + // item.RecordType = (Byte)NHeaderType::kFile; // for debug } } + + CRefItem ref; + ref.Item = _items.Size(); + ref.Last = ref.Item; + ref.Parent = -1; + ref.Link = -1; if (needAdd) { - CRefItem ref; - ref.Item = _items.Size(); - ref.Last = ref.Item; - ref.Parent = -1; - ref.Link = -1; - if (item.IsService()) { if (item.Is_STM()) @@ -2249,8 +2453,16 @@ else { needAdd = false; - if (item.Is_ACL() && (!item.IsEncrypted() || arch.m_CryptoMode)) + if (item.Is_ACL()) { + _acl_Used = true; + if (item.IsEncrypted() && !arch.m_CryptoMode) + _error_in_ACL = true; + else if (item.IsSolid() + || prevMainFile < 0 + || item.Size >= (1 << 24) + || item.Size == 0) + _error_in_ACL = true; if (prevMainFile >= 0 && item.Size < (1 << 24) && item.Size != 0) { CItem &mainItem = _items[_refs[prevMainFile].Item]; @@ -2258,7 +2470,7 @@ if (mainItem.ACL < 0) { CByteBuffer acl; - HRESULT res = tempBuf.Decode(EXTERNAL_CODECS_VARS item, inStream, unpacker, acl); + const HRESULT res = tempBuf.Decode(EXTERNAL_CODECS_VARS item, inStream, unpacker, acl); if (!item.IsSplitAfter()) tempBuf.Clear(); if (res != S_OK) @@ -2266,20 +2478,19 @@ tempBuf.Clear(); if (res != S_FALSE && res != E_NOTIMPL) return res; + _error_in_ACL = true; } - // RINOK(); - - if (res == S_OK && acl.Size() != 0) + else if (acl.Size() != 0) { if (_acls.IsEmpty() || acl != _acls.Back()) _acls.Add(acl); - mainItem.ACL = _acls.Size() - 1; + mainItem.ACL = (int)_acls.Size() - 1; } } } } } - } + } // item.IsService() if (needAdd) { @@ -2292,20 +2503,21 @@ if (item.IsNextForItem(prevItem)) { ref2.Last = _items.Size(); - prevItem.NextItem = ref2.Last; + prevItem.NextItem = (int)ref2.Last; needAdd = false; } } + else + _split_Error = true; } } if (needAdd) { if (item.IsSplitAfter()) - prevSplitFile = _refs.Size(); + prevSplitFile = (int)_refs.Size(); if (!item.IsService()) - prevMainFile = _refs.Size(); - _refs.Add(ref); + prevMainFile = (int)_refs.Size(); } } @@ -2320,12 +2532,14 @@ item.VolIndex = _arcs.Size() - 1; _items.Add(item); + if (needAdd) + _refs.Add(ref); if (openCallback && (_items.Size() & 0xFF) == 0) { - UInt64 numFiles = _items.Size(); - UInt64 numBytes = curBytes + item.DataPos; - RINOK(openCallback->SetCompleted(&numFiles, &numBytes)); + const UInt64 numFiles = _refs.Size(); // _items.Size() + const UInt64 numBytes = curBytes + item.DataPos; + RINOK(openCallback->SetCompleted(&numFiles, &numBytes)) } if (!isOk_packSize) @@ -2348,14 +2562,14 @@ } FillLinks(); - return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) + IArchiveOpenCallback *openCallback)) { COM_TRY_BEGIN Close(); @@ -2363,13 +2577,26 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { COM_TRY_BEGIN _missingVolName.Empty(); _errorFlags = 0; // _warningFlags = 0; _isArc = false; + _comment_WasUsedInArc = false; + _acl_Used = false; + _error_in_ACL = false; + _split_Error = false; + _numBlocks = 0; + _rar5comapt_mask = 0; + _algo_Mask = 0; // (UInt64)0u - 1; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(_methodMasks); i++) + { + _methodMasks[i] = 0; + _dictMaxSizes[i] = 0; + } + _refs.Clear(); _items.Clear(); _arcs.Clear(); @@ -2380,10 +2607,10 @@ } -class CVolsInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CVolsInStream + , ISequentialInStream +) UInt64 _rem; ISequentialInStream *_stream; const CObjectVector *_arcs; @@ -2394,22 +2621,19 @@ private: CHash _hash; public: - MY_UNKNOWN_IMP void Init(const CObjectVector *arcs, const CObjectVector *items, unsigned itemIndex) { _arcs = arcs; _items = items; - _itemIndex = itemIndex; + _itemIndex = (int)itemIndex; _stream = NULL; CrcIsOK = true; } - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -2423,7 +2647,7 @@ break; const CItem &item = (*_items)[_itemIndex]; IInStream *s = (*_arcs)[item.VolIndex].Stream; - RINOK(s->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(s, item.GetDataPosition())) _stream = s; if (CrcIsOK && item.IsSplitAfter()) _hash.Init(item); @@ -2435,7 +2659,7 @@ UInt32 cur = size; if (cur > _rem) cur = (UInt32)_rem; - UInt32 num = cur; + const UInt32 num = cur; HRESULT res = _stream->Read(data, cur, &cur); _hash.Update(data, cur); realProcessedSize += cur; @@ -2472,10 +2696,10 @@ { if (left == right) return -1; - unsigned mid = (left + right) / 2; - unsigned linkIndex = linkFiles[mid].Index; + const unsigned mid = (left + right) / 2; + const unsigned linkIndex = linkFiles[mid].Index; if (index == linkIndex) - return mid; + return (int)mid; if (index < linkIndex) right = mid; else @@ -2500,41 +2724,35 @@ static HRESULT CopyData_with_Progress(const Byte *data, size_t size, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - size_t pos = 0; - - while (pos < size) + UInt64 pos64 = 0; + while (size) { - const UInt32 kStepSize = ((UInt32)1 << 24); - UInt32 cur32; - { - size_t cur = size - pos; - if (cur > kStepSize) - cur = kStepSize; - cur32 = (UInt32)cur; - } - RINOK(outStream->Write(data + pos, cur32, &cur32)); - if (cur32 == 0) + const UInt32 kStepSize = (UInt32)1 << 24; + UInt32 cur = kStepSize; + if (cur > size) + cur = (UInt32)size; + RINOK(outStream->Write(data, cur, &cur)) + if (cur == 0) return E_FAIL; - pos += cur32; + size -= cur; + data += cur; + pos64 += cur; if (progress) { - UInt64 pos64 = pos; - RINOK(progress->SetRatioInfo(&pos64, &pos64)); + RINOK(progress->SetRatioInfo(&pos64, &pos64)) } } - return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) - numItems = _refs.Size(); + numItems = (UInt32)_refs.Size(); if (numItems == 0) return S_OK; @@ -2563,12 +2781,11 @@ UInt64 total = 0; bool isThereUndefinedSize = false; bool thereAreLinks = false; - { unsigned solidLimit = 0; for (UInt32 t = 0; t < numItems; t++) { - unsigned index = allFilesMode ? t : indices[t]; + const unsigned index = (unsigned)(allFilesMode ? t : indices[t]); const CRefItem &ref = _refs[index]; const CItem &item = _items[ref.Item]; const CItem &lastItem = _items[ref.Last]; @@ -2697,16 +2914,16 @@ if (!testMode) for (UInt32 t = 0; t < numItems; t++) { - unsigned index = allFilesMode ? t : indices[t]; + const unsigned index = (unsigned)(allFilesMode ? t : indices[t]); const CRefItem &ref = _refs[index]; - int linkIndex = ref.Link; + const int linkIndex = ref.Link; if (linkIndex < 0 || (unsigned)linkIndex >= index) continue; const CItem &linkItem = _items[_refs[(unsigned)linkIndex].Item]; if (!linkItem.IsSolid() || linkItem.Size > k_CopyLinkFile_MaxSize) continue; - int bufIndex = FindLinkBuf(linkFiles, linkIndex); + const int bufIndex = FindLinkBuf(linkFiles, (unsigned)linkIndex); if (bufIndex < 0) return E_FAIL; linkFiles[bufIndex].NumLinks++; @@ -2715,43 +2932,144 @@ if (total != 0 || !isThereUndefinedSize) { - RINOK(extractCallback->SetTotal(total)); + RINOK(extractCallback->SetTotal(total)) } } + + // ---------- MEMORY REQUEST ---------- + { + UInt64 dictMaxSize = 0; + for (UInt32 i = 0; i < _refs.Size(); i++) + { + if (extractStatuses[i] == 0) + continue; + const CRefItem &ref = _refs[i]; + const CItem &item = _items[ref.Item]; +/* + if (!item.IsDir() && !item.IsService() && item.NeedUse_as_CopyLink()) + { + } +*/ + const unsigned algo = item.Get_AlgoVersion_RawBits(); + if (!item.IsDir() && algo < Z7_ARRAY_SIZE(_methodMasks)) + { + const UInt64 d = item.Get_DictSize64(); + if (dictMaxSize < d) + dictMaxSize = d; + } + } + // we use callback, if dict exceeds (1 GB), because + // client code can set low limit (1 GB) for allowed memory usage. + const UInt64 k_MemLimit_for_Callback = (UInt64)1 << 30; + if (dictMaxSize > (_memUsage_WasSet ? + _memUsage_Decompress : k_MemLimit_for_Callback)) + { + { + CMyComPtr requestMem; + extractCallback->QueryInterface(IID_IArchiveRequestMemoryUseCallback, (void **)&requestMem); + if (!requestMem) + { + if (_memUsage_WasSet) + return E_OUTOFMEMORY; + } + else + { + UInt64 allowedSize = _memUsage_WasSet ? + _memUsage_Decompress : + (UInt64)1 << 32; // 4 GB is default allowed limit for RAR7 + + const UInt32 flags = (_memUsage_WasSet ? + NRequestMemoryUseFlags::k_AllowedSize_WasForced | + NRequestMemoryUseFlags::k_MLimit_Exceeded : + (dictMaxSize > allowedSize) ? + NRequestMemoryUseFlags::k_DefaultLimit_Exceeded: + 0) + | NRequestMemoryUseFlags::k_SkipArc_IsExpected + // | NRequestMemoryUseFlags::k_NoErrorMessage // for debug + ; + + // we set "Allow" for default case, if requestMem doesn't process anything. + UInt32 answerFlags = + (_memUsage_WasSet && dictMaxSize > allowedSize) ? + NRequestMemoryAnswerFlags::k_Limit_Exceeded + | NRequestMemoryAnswerFlags::k_SkipArc + : NRequestMemoryAnswerFlags::k_Allow; + + RINOK(requestMem->RequestMemoryUse( + flags, + NEventIndexType::kNoIndex, + // NEventIndexType::kInArcIndex, // for debug + 0, // index + NULL, // path + dictMaxSize, &allowedSize, &answerFlags)) + if ( (answerFlags & NRequestMemoryAnswerFlags::k_Allow) == 0 + || (answerFlags & NRequestMemoryAnswerFlags::k_Stop) + || (answerFlags & NRequestMemoryAnswerFlags::k_SkipArc) + ) + { + return E_OUTOFMEMORY; + } +/* + if ((answerFlags & NRequestMemoryAnswerFlags::k_AskForBigFile) == 0 && + (answerFlags & NRequestMemoryAnswerFlags::k_ReportForBigFile) == 0) + { + // requestMem.Release(); + } +*/ + } + } + } + } + + + + // ---------- UNPACK ---------- + UInt64 totalUnpacked = 0; UInt64 totalPacked = 0; - UInt64 curUnpackSize = 0; - UInt64 curPackSize = 0; + UInt64 curUnpackSize; + UInt64 curPackSize; CUnpacker unpacker; - - CVolsInStream *volsInStreamSpec = new CVolsInStream; - CMyComPtr volsInStream = volsInStreamSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + unpacker.NeedCrc = _needChecksumCheck; + CMyComPtr2_Create volsInStream; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - // bool needClearSolid = true; +/* + bool prevSolidWasSkipped = false; + UInt64 solidDictSize_Skip = 0; +*/ - FOR_VECTOR (i, _refs) + for (unsigned i = 0;; i++, + totalUnpacked += curUnpackSize, + totalPacked += curPackSize) { - if (extractStatuses[i] == 0) - continue; - - totalUnpacked += curUnpackSize; - totalPacked += curPackSize; lps->InSize = totalPacked; lps->OutSize = totalUnpacked; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + { + const unsigned num = _refs.Size(); + if (i >= num) + break; + for (;;) + { + if (extractStatuses[i] != 0) + break; + i++; + if (i >= num) + break; + } + if (i >= num) + break; + } + curUnpackSize = 0; + curPackSize = 0; - CMyComPtr realOutStream; - // isExtract means that we don't skip that item. So we need read data. - - bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0); + const bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0); Int32 askMode = isExtract ? (testMode ? NExtract::NAskMode::kTest : @@ -2763,14 +3081,13 @@ // if (!testMode) if ((extractStatuses[i] & kStatus_Link) != 0) { - int bufIndex = FindLinkBuf(linkFiles, i); + const int bufIndex = FindLinkBuf(linkFiles, i); if (bufIndex < 0) return E_FAIL; unpacker.linkFile = &linkFiles[bufIndex]; } - UInt32 index = i; - + const unsigned index = i; const CRefItem *ref = &_refs[index]; const CItem *item = &_items[ref->Item]; const CItem &lastItem = _items[ref->Last]; @@ -2781,8 +3098,6 @@ curPackSize = GetPackSize(index); - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - bool isSolid = false; if (!item->IsService()) { @@ -2791,14 +3106,60 @@ unpacker.SolidAllowed = isSolid; } + + // ----- request mem ----- +/* + // link files are complicated cases. (ref->Link >= 0) + // link file can refer to non-solid file that can have big dictionary + // link file can refer to solid files that requres buffer + if (!item->IsDir() && requestMem && ref->Link < 0) + { + bool needSkip = false; + if (isSolid) + needSkip = prevSolidWasSkipped; + else + { + // isSolid == false + const unsigned algo = item->Get_AlgoVersion_RawBits(); + // const unsigned m = item.Get_Method(); + if (algo < Z7_ARRAY_SIZE(_methodMasks)) + { + solidDictSize_Skip = item->Get_DictSize64(); + if (solidDictSize_Skip > allowedSize) + needSkip = true; + } + } + if (needSkip) + { + UInt32 answerFlags = 0; + UInt64 allowedSize_File = allowedSize; + RINOK(requestMem->RequestMemoryUse( + NRequestMemoryUseFlags::k_Limit_Exceeded | + NRequestMemoryUseFlags::k_IsReport, + NEventIndexType::kInArcIndex, + index, + NULL, // path + solidDictSize_Skip, &allowedSize_File, &answerFlags)) + if (!item->IsService()) + prevSolidWasSkipped = true; + continue; + } + } + if (!item->IsService() && item->IsDir()) + prevSolidWasSkipped = false; +*/ + + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream((UInt32)index, &realOutStream, askMode)) + if (item->IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } - int index2 = ref->Link; + const int index2 = ref->Link; int bufIndex = -1; @@ -2815,12 +3176,12 @@ curUnpackSize = lastItem2.Size; else curUnpackSize = 0; - curPackSize = GetPackSize(index2); + curPackSize = GetPackSize((unsigned)index2); } else { if ((unsigned)index2 < index) - bufIndex = FindLinkBuf(linkFiles, index2); + bufIndex = FindLinkBuf(linkFiles, (unsigned)index2); } } @@ -2839,8 +3200,8 @@ opRes = DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK); } - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(opRes)) continue; } } @@ -2874,7 +3235,7 @@ if (needCallback) { - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) } if (bufIndex >= 0) @@ -2889,7 +3250,7 @@ if (needCallback) if (realOutStream) { - RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress)); + RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, lps)) } if (--linkFile.NumLinks == 0) @@ -2898,7 +3259,7 @@ if (needCallback) { - RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))); + RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))) } continue; } @@ -2908,17 +3269,17 @@ if (item->NeedUse_as_CopyLink()) { - int opRes = realOutStream ? + const int opRes = realOutStream ? NExtract::NOperationResult::kUnsupportedMethod: NExtract::NOperationResult::kOK; realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) continue; } - volsInStreamSpec->Init(&_arcs, &_items, ref->Item); + volsInStream->Init(&_arcs, &_items, ref->Item); - UInt64 packSize = curPackSize; + const UInt64 packSize = curPackSize; if (item->IsEncrypted()) if (!unpacker.getTextPassword) @@ -2930,15 +3291,15 @@ if (wrongPassword) { realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kWrongPassword)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kWrongPassword)) continue; } bool crcOK = true; if (result == S_OK) - result = unpacker.Code(*item, _items[ref->Last], packSize, volsInStream, realOutStream, progress, crcOK); + result = unpacker.Code(*item, _items[ref->Last], packSize, volsInStream, realOutStream, lps, crcOK); realOutStream.Release(); - if (!volsInStreamSpec->CrcIsOK) + if (!volsInStream->CrcIsOK) crcOK = false; int opRes = crcOK ? @@ -2955,25 +3316,79 @@ return result; } - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } { - FOR_VECTOR (i, linkFiles) - if (linkFiles[i].NumLinks != 0) + FOR_VECTOR (k, linkFiles) + if (linkFiles[k].NumLinks != 0) return E_FAIL; } return S_OK; - COM_TRY_END } +CHandler::CHandler() +{ + InitDefaults(); +} + +void CHandler::InitDefaults() +{ + _needChecksumCheck = true; + _memUsage_WasSet = false; + _memUsage_Decompress = (UInt64)1 << 32; +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + InitDefaults(); + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + } + else if (name.IsPrefixedBy_Ascii_NoCase("memx")) + { + size_t memAvail; + if (!NWindows::NSystem::GetRamSize(memAvail)) + memAvail = (size_t)sizeof(size_t) << 28; + UInt64 v; + if (!ParseSizeString(name.Ptr(4), prop, memAvail, v)) + return E_INVALIDARG; + _memUsage_Decompress = v; + _memUsage_WasSet = true; + } + else if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 1; + RINOK(ParsePropToUInt32(name, prop, crcSize)) + _needChecksumCheck = (crcSize != 0); + } + else + { + return E_INVALIDARG; + } + } + return S_OK; +} + + IMPL_ISetCompressCodecsInfo REGISTER_ARC_I( - "Rar5", "rar r00", 0, 0xCC, + "Rar5", "rar r00", NULL, 0xCC, kMarker, 0, NArcInfoFlags::kFindSignature, @@ -2982,33 +3397,78 @@ }} -class CBlake2spHasher: - public IHasher, - public CMyUnknownImp -{ - CBlake2sp _blake; - Byte mtDummy[1 << 7]; - +Z7_CLASS_IMP_COM_2( + CBlake2spHasher + , IHasher + , ICompressSetCoderProperties +) + CAlignedBuffer1 _buf; + // CBlake2sp _blake; + #define Z7_BLACK2S_ALIGN_OBJECT_OFFSET 0 + CBlake2sp *Obj() { return (CBlake2sp *)(void *)((Byte *)_buf + Z7_BLACK2S_ALIGN_OBJECT_OFFSET); } public: - CBlake2spHasher() { Init(); } - - MY_UNKNOWN_IMP - INTERFACE_IHasher(;) + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + CBlake2spHasher(): + _buf(sizeof(CBlake2sp) + Z7_BLACK2S_ALIGN_OBJECT_OFFSET) + { + Blake2sp_SetFunction(Obj(), 0); + Blake2sp_InitState(Obj()); + } }; -STDMETHODIMP_(void) CBlake2spHasher::Init() throw() +Z7_COM7F_IMF2(void, CBlake2spHasher::Init()) { - Blake2sp_Init(&_blake); + Blake2sp_InitState(Obj()); } -STDMETHODIMP_(void) CBlake2spHasher::Update(const void *data, UInt32 size) throw() +Z7_COM7F_IMF2(void, CBlake2spHasher::Update(const void *data, UInt32 size)) { - Blake2sp_Update(&_blake, (const Byte *)data, size); +#if 1 + Blake2sp_Update(Obj(), (const Byte *)data, (size_t)size); +#else + // for debug: + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 800; + // UInt32 size2 = size / 2; + if (size2 == 0) + size2 = 1; + Blake2sp_Update(Obj(), (const Byte *)data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +#endif } -STDMETHODIMP_(void) CBlake2spHasher::Final(Byte *digest) throw() +Z7_COM7F_IMF2(void, CBlake2spHasher::Final(Byte *digest)) { - Blake2sp_Final(&_blake, digest); + Blake2sp_Final(Obj(), digest); } -REGISTER_HASHER(CBlake2spHasher, 0x202, "BLAKE2sp", BLAKE2S_DIGEST_SIZE) +Z7_COM7F_IMF(CBlake2spHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + /* + if (prop.ulVal > Z7_BLAKE2S_ALGO_MAX) + return E_NOTIMPL; + */ + algo = (unsigned)prop.ulVal; + } + } + if (!Blake2sp_SetFunction(Obj(), algo)) + return E_NOTIMPL; + return S_OK; +} + +REGISTER_HASHER(CBlake2spHasher, 0x202, "BLAKE2sp", Z7_BLAKE2S_DIGEST_SIZE) + +static struct CBlake2sp_Prepare { CBlake2sp_Prepare() { z7_Black2sp_Prepare(); } } g_Blake2sp_Prepare; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.h 2018-04-01 08:10:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/Rar5Handler.h 2025-06-16 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Rar5Handler.h -#ifndef __RAR5_HANDLER_H -#define __RAR5_HANDLER_H +#ifndef ZIP7_INC_RAR5_HANDLER_H +#define ZIP7_INC_RAR5_HANDLER_H #include "../../../../C/Blake2.h" @@ -48,7 +48,8 @@ // const unsigned kLocked = 1 << 4; } -const unsigned kArcExtraRecordType_Locator = 1; +const unsigned kArcExtraRecordType_Locator = 1; +const unsigned kArcExtraRecordType_Metadata = 2; namespace NLocatorFlags { @@ -56,6 +57,14 @@ const unsigned kRecovery = 1 << 1; } +namespace NMetadataFlags +{ + const unsigned kArcName = 1 << 0; + const unsigned kCTime = 1 << 1; + const unsigned kUnixTime = 1 << 2; + const unsigned kNanoSec = 1 << 3; +} + namespace NFileFlags { const unsigned kIsDir = 1 << 0; @@ -68,6 +77,7 @@ { // const unsigned kVersionMask = 0x3F; const unsigned kSolid = 1 << 6; + const unsigned kRar5_Compat = 1u << 20; } namespace NArcEndFlags @@ -181,7 +191,7 @@ AString Name; unsigned VolIndex; - int NextItem; + int NextItem; // in _items{} UInt32 UnixMTime; UInt32 CRC; @@ -201,9 +211,12 @@ void Clear() { - CommonFlags = 0; - Flags = 0; + // CommonFlags = 0; + // Flags = 0; + // UnixMTime = 0; + // CRC = 0; + VolIndex = 0; NextItem = -1; @@ -230,17 +243,53 @@ // && false; } - bool IsSolid() const { return ((UInt32)Method & NMethodFlags::kSolid) != 0; } - unsigned GetAlgoVersion() const { return (unsigned)Method & 0x3F; } - unsigned GetMethod() const { return ((unsigned)Method >> 7) & 0x7; } - UInt32 GetDictSize() const { return (((UInt32)Method >> 10) & 0xF); } + // rar docs: Solid flag can be set only for file headers and is never set for service headers. + bool IsSolid() const { return ((UInt32)Method & NMethodFlags::kSolid) != 0; } + bool Is_Rar5_Compat() const { return ((UInt32)Method & NMethodFlags::kRar5_Compat) != 0; } + unsigned Get_Rar5_CompatBit() const { return ((UInt32)Method >> 20) & 1; } + + unsigned Get_AlgoVersion_RawBits() const { return (unsigned)Method & 0x3F; } + unsigned Get_AlgoVersion_HuffRev() const + { + unsigned w = (unsigned)Method & 0x3F; + if (w == 1 && Is_Rar5_Compat()) + w = 0; + return w; + } + unsigned Get_Method() const { return ((unsigned)Method >> 7) & 0x7; } + + unsigned Get_DictSize_Main() const + { return ((UInt32)Method >> 10) & (Get_AlgoVersion_RawBits() == 0 ? 0xf : 0x1f); } + unsigned Get_DictSize_Frac() const + { + // original-unrar ignores Frac, if (algo==0) (rar5): + if (Get_AlgoVersion_RawBits() == 0) + return 0; + return ((UInt32)Method >> 15) & 0x1f; + } + UInt64 Get_DictSize64() const + { + // ver 6.* check + // return (((UInt32)Method >> 10) & 0xF); + UInt64 winSize = 0; + const unsigned algo = Get_AlgoVersion_RawBits(); + if (algo <= 1) + { + UInt32 w = 32; + if (algo == 1) + w += Get_DictSize_Frac(); + winSize = (UInt64)w << (12 + Get_DictSize_Main()); + } + return winSize; + } + bool IsService() const { return RecordType == NHeaderType::kService; } - bool Is_STM() const { return IsService() && Name == "STM"; } - bool Is_CMT() const { return IsService() && Name == "CMT"; } - bool Is_ACL() const { return IsService() && Name == "ACL"; } - // bool Is_QO() const { return IsService() && Name == "QO"; } + bool Is_STM() const { return IsService() && Name.IsEqualTo("STM"); } + bool Is_CMT() const { return IsService() && Name.IsEqualTo("CMT"); } + bool Is_ACL() const { return IsService() && Name.IsEqualTo("ACL"); } + // bool Is_QO() const { return IsService() && Name.IsEqualTo("QO"); } int FindExtra(unsigned extraID, unsigned &recordDataSize) const; void PrintInfo(AString &s) const; @@ -255,9 +304,9 @@ int FindExtra_Blake() const { unsigned size = 0; - int offset = FindExtra(NExtraID::kHash, size); + const int offset = FindExtra(NExtraID::kHash, size); if (offset >= 0 - && size == BLAKE2S_DIGEST_SIZE + 1 + && size == Z7_BLAKE2S_DIGEST_SIZE + 1 && Extra[(unsigned)offset] == kHashID_Blake2sp) return offset + 1; return -1; @@ -282,11 +331,17 @@ UInt32 a; switch (HostOS) { - case kHost_Windows: a = Attrib; break; - case kHost_Unix: a = (Attrib << 16); break; - default: a = 0; + case kHost_Windows: + a = Attrib; + break; + case kHost_Unix: + a = Attrib << 16; + a |= 0x8000; // add posix mode marker + break; + default: + a = 0; } - // if (IsDir()) a |= FILE_ATTRIBUTE_DIRECTORY; + if (IsDir()) a |= FILE_ATTRIBUTE_DIRECTORY; return a; } @@ -305,10 +360,14 @@ bool EndOfArchive_was_Read; bool IsEncrypted; + bool Locator_Defined; + bool Locator_Error; + bool Metadata_Defined; + bool Metadata_Error; + bool UnknownExtraRecord; + bool Extra_Error; + bool UnsupportedFeature; - // CByteBuffer Extra; - - /* struct CLocator { UInt64 Flags; @@ -317,11 +376,32 @@ bool Is_QuickOpen() const { return (Flags & NLocatorFlags::kQuickOpen) != 0; } bool Is_Recovery() const { return (Flags & NLocatorFlags::kRecovery) != 0; } + + bool Parse(const Byte *p, size_t size); + CLocator(): + Flags(0), + QuickOpen(0), + Recovery(0) + {} }; - int FindExtra(unsigned extraID, unsigned &recordDataSize) const; - bool FindExtra_Locator(CLocator &locator) const; - */ + struct CMetadata + { + UInt64 Flags; + UInt64 CTime; + AString ArcName; + + bool Parse(const Byte *p, size_t size); + CMetadata(): + Flags(0), + CTime(0) + {} + }; + + CLocator Locator; + CMetadata Metadata; + + bool ParseExtra(const Byte *p, size_t size); CInArcInfo(): Flags(0), @@ -330,7 +410,14 @@ EndPos(0), EndFlags(0), EndOfArchive_was_Read(false), - IsEncrypted(false) + IsEncrypted(false), + Locator_Defined(false), + Locator_Error(false), + Metadata_Defined(false), + Metadata_Error(false), + UnknownExtraRecord(false), + Extra_Error(false), + UnsupportedFeature(false) {} /* @@ -342,7 +429,6 @@ EndPos = 0; EndFlags = 0; EndOfArchive_was_Read = false; - Extra.Free(); } */ @@ -360,10 +446,10 @@ struct CRefItem { - unsigned Item; - unsigned Last; - int Parent; - int Link; + unsigned Item; // First item in _items[] + unsigned Last; // Last item in _items[] + int Parent; // in _refs[], if alternate stream + int Link; // in _refs[] }; @@ -374,25 +460,57 @@ }; -class CHandler: +class CHandler Z7_final: public IInArchive, public IArchiveGetRawProps, - PUBLIC_ISetCompressCodecsInfo + public ISetProperties, + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(ISetProperties) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(ISetProperties) + DECL_ISetCompressCodecsInfo + + void InitDefaults(); + + bool _isArc; + bool _needChecksumCheck; + bool _memUsage_WasSet; + bool _comment_WasUsedInArc; + bool _acl_Used; + bool _error_in_ACL; + bool _split_Error; public: CRecordVector _refs; CObjectVector _items; + + CHandler(); private: CObjectVector _arcs; CObjectVector _acls; UInt32 _errorFlags; // UInt32 _warningFlags; - bool _isArc; + + UInt32 _numBlocks; + unsigned _rar5comapt_mask; + unsigned _methodMasks[2]; + UInt64 _algo_Mask; + UInt64 _dictMaxSizes[2]; + CByteBuffer _comment; UString _missingVolName; + UInt64 _memUsage_Decompress; + DECL_EXTERNAL_CODECS_VARS UInt64 GetPackSize(unsigned refIndex) const; @@ -402,18 +520,6 @@ HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback); - -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - - DECL_ISetCompressCodecsInfo }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.cpp 2022-05-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -44,9 +44,8 @@ namespace NArchive { namespace NRar { -#define SIGNATURE { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 } - -static const Byte kMarker[NHeader::kMarkerSize] = SIGNATURE; +static const Byte kMarker[NHeader::kMarkerSize] = + { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; const unsigned kPasswordLen_MAX = 127; @@ -184,35 +183,33 @@ { HeaderErrorWarning = false; m_CryptoMode = false; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileSize)); - RINOK(stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + RINOK(InStream_GetPos_GetSize(stream, m_StreamStartPosition, ArcInfo.FileSize)) m_Position = m_StreamStartPosition; UInt64 arcStartPos = m_StreamStartPosition; { Byte marker[NHeader::kMarkerSize]; - RINOK(ReadStream_FALSE(stream, marker, NHeader::kMarkerSize)); + RINOK(ReadStream_FALSE(stream, marker, NHeader::kMarkerSize)) if (memcmp(marker, kMarker, NHeader::kMarkerSize) == 0) m_Position += NHeader::kMarkerSize; else { if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) return S_FALSE; - RINOK(stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, m_StreamStartPosition)) RINOK(FindSignatureInStream(stream, kMarker, NHeader::kMarkerSize, - searchHeaderSizeLimit, arcStartPos)); + searchHeaderSizeLimit, arcStartPos)) m_Position = arcStartPos + NHeader::kMarkerSize; - RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, m_Position)) } } Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1]; - RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)); + RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)) AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); - UInt32 blockSize = Get16(buf + 5); + const UInt32 blockSize = Get16(buf + 5); ArcInfo.EncryptVersion = 0; ArcInfo.Flags = Get16(buf + 3); @@ -238,7 +235,7 @@ size_t commentSize = blockSize - headerSize; _comment.Alloc(commentSize); - RINOK(ReadStream_FALSE(stream, _comment, commentSize)); + RINOK(ReadStream_FALSE(stream, _comment, commentSize)) AddToSeekValue(commentSize); m_Stream = stream; ArcInfo.StartPos = arcStartPos; @@ -368,7 +365,7 @@ return -1; for (unsigned i = 0; i < numDigits; i++) rarTime.SubTime[3 - numDigits + i] = p[i]; - return numDigits; + return (int)numDigits; } #define READ_TIME(_mask_, _ttt_) \ @@ -438,13 +435,13 @@ size -= sizeof(item.Salt); p += sizeof(item.Salt); } - if (item.Name == "ACL" && size == 0) + if (item.Name.IsEqualTo("ACL") && size == 0) { item.IsAltStream = true; item.Name.Empty(); item.UnicodeName.SetFromAscii(".ACL"); } - else if (item.Name == "STM" && size != 0 && (size & 1) == 0) + else if (item.Name.IsEqualTo("STM") && size != 0 && (size & 1) == 0) { item.IsAltStream = true; item.Name.Empty(); @@ -480,10 +477,10 @@ Byte cMask = (Byte)(b & 0xF); if ((mMask & 8) != 0) { - READ_TIME(mMask, item.MTime); + READ_TIME(mMask, item.MTime) } - READ_TIME_2(cMask, item.CTimeDefined, item.CTime); - READ_TIME_2(aMask, item.ATimeDefined, item.ATime); + READ_TIME_2(cMask, item.CTimeDefined, item.CTime) + READ_TIME_2(aMask, item.ATimeDefined, item.ATime) } unsigned fileHeaderWithNameSize = 7 + (unsigned)(p - pStart); @@ -508,13 +505,13 @@ error = k_ErrorType_OK; for (;;) { - m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); + RINOK(InStream_SeekSet(m_Stream, m_Position)) ArcInfo.EndPos = m_Position; if (!m_CryptoMode && (ArcInfo.Flags & NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) { m_CryptoMode = false; - if (getTextPassword == 0) + if (!getTextPassword) { error = k_ErrorType_DecryptionError; return S_OK; // return S_FALSE; @@ -565,9 +562,9 @@ if (!m_DecryptedDataAligned.IsAllocated()) return E_OUTOFMEMORY; } - RINOK(m_RarAES->Init()); + RINOK(m_RarAES->Init()) size_t decryptedDataSizeT = kDecryptedBufferSize; - RINOK(ReadStream(m_Stream, m_DecryptedDataAligned, &decryptedDataSizeT)); + RINOK(ReadStream(m_Stream, m_DecryptedDataAligned, &decryptedDataSizeT)) m_DecryptedDataSize = (UInt32)decryptedDataSizeT; m_DecryptedDataSize = m_RarAES->Filter(m_DecryptedDataAligned, m_DecryptedDataSize); @@ -577,7 +574,7 @@ m_FileHeaderData.AllocAtLeast(7); size_t processed = 7; - RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed)); + RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed)) if (processed != 7) { if (processed != 0) @@ -715,7 +712,7 @@ FinishCryptoBlock(); m_CryptoMode = false; // Move Position to compressed Data; - m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); + RINOK(InStream_SeekSet(m_Stream, m_Position)) AddToSeekValue(item.PackSize); // m_Position points to next header; // if (okItem) return S_OK; @@ -828,7 +825,7 @@ return item.IsSolid(); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -838,7 +835,7 @@ case kpidSolid: prop = _arcInfo.IsSolid(); break; case kpidCharacts: { - AString s (FlagsToString(k_Flags, ARRAY_SIZE(k_Flags), _arcInfo.Flags)); + AString s (FlagsToString(k_Flags, Z7_ARRAY_SIZE(k_Flags), _arcInfo.Flags)); // FLAGS_TO_PROP(k_Flags, _arcInfo.Flags, prop); if (_arcInfo.Is_DataCRC_Defined()) { @@ -935,7 +932,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _refItems.Size(); return S_OK; @@ -969,7 +966,7 @@ */ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -1087,7 +1084,7 @@ UString baseName; { NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) break; baseName = prop.bstrVal; @@ -1119,16 +1116,15 @@ else inStream = stream; - UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(inStream, endPos)) if (openCallback) { totalBytes += endPos; - RINOK(openCallback->SetTotal(NULL, &totalBytes)); + RINOK(openCallback->SetTotal(NULL, &totalBytes)) } - RINOK(archive.Open(inStream, maxCheckStartPosition)); + RINOK(archive.Open(inStream, maxCheckStartPosition)) _isArc = true; CItem item; @@ -1157,7 +1153,7 @@ // AddErrorMessage(errorMessageLoc); } - RINOK(result); + RINOK(result) if (!filled) { @@ -1169,11 +1165,11 @@ /* if there is recovery record for multivolume archive, RAR adds 18 bytes (ZERO bytes) at the end for alignment. We must skip these bytes to prevent phySize warning. */ - RINOK(inStream->Seek(archive.ArcInfo.EndPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, archive.ArcInfo.EndPos)) bool areThereNonZeros; UInt64 numZeros; const UInt64 maxSize = 1 << 12; - RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); + RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)) if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) archive.ArcInfo.EndPos += numZeros; } @@ -1210,7 +1206,7 @@ { UInt64 numFiles = _items.Size(); UInt64 numBytes = curBytes + item.Position; - RINOK(openCallback->SetCompleted(&numFiles, &numBytes)); + RINOK(openCallback->SetCompleted(&numFiles, &numBytes)) } } @@ -1260,9 +1256,9 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) + IArchiveOpenCallback *openCallback)) { COM_TRY_BEGIN Close(); @@ -1281,7 +1277,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { COM_TRY_BEGIN // _errorMessage.Empty(); @@ -1303,10 +1299,10 @@ }; -class CVolsInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CVolsInStream + , ISequentialInStream +) UInt64 _rem; ISequentialInStream *_stream; const CObjectVector *_arcs; @@ -1317,10 +1313,6 @@ bool _calcCrc; public: - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - void Init(const CObjectVector *arcs, const CObjectVector *items, const CRefItem &refItem) @@ -1337,7 +1329,7 @@ }; -STDMETHODIMP CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -1357,7 +1349,7 @@ // return S_FALSE; } IInStream *s = (*_arcs)[volIndex].Stream; - RINOK(s->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(s, item.GetDataPosition())) _stream = s; _calcCrc = (CrcIsOK && item.IsSplitAfter()); _crc = CRC_INIT_VAL; @@ -1397,16 +1389,16 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN CMyComPtr getTextPassword; - UInt64 censoredTotalUnPacked = 0, + UInt64 // censoredTotalUnPacked = 0, // censoredTotalPacked = 0, importantTotalUnPacked = 0; // importantTotalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _refItems.Size(); if (numItems == 0) @@ -1426,7 +1418,9 @@ const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; if (item.Is_Size_Defined()) - censoredTotalUnPacked += item.Size; + { + // censoredTotalUnPacked += item.Size; + } else isThereUndefinedSize = true; @@ -1458,7 +1452,7 @@ if (importantTotalUnPacked != 0 || !isThereUndefinedSize) { - RINOK(extractCallback->SetTotal(importantTotalUnPacked)); + RINOK(extractCallback->SetTotal(importantTotalUnPacked)) } UInt64 currentImportantTotalUnPacked = 0; @@ -1494,7 +1488,7 @@ { lps->InSize = currentImportantTotalPacked; lps->OutSize = currentImportantTotalUnPacked; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) if (i >= importantIndexes.Size()) break; @@ -1528,14 +1522,14 @@ if (item.IgnoreItem()) continue; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!IsSolid(index)) solidStart = true; if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } @@ -1554,7 +1548,7 @@ if (!realOutStream && !testMode) askMode = NExtract::NAskMode::kSkip; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; CMyComPtr outStream(outStreamSpec); @@ -1594,7 +1588,7 @@ RINOK(rar3CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &cryptoProperties)); */ - RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); + RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)) filterStreamSpec->Filter = rar3CryptoDecoder; } else if (item.UnPackVersion >= 20) @@ -1609,7 +1603,7 @@ else { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } @@ -1621,14 +1615,14 @@ if (!getTextPassword) { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } // if (getTextPassword) { CMyComBSTR_Wipe password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); + RINOK(getTextPassword->CryptoGetTextPassword(&password)) if (item.UnPackVersion >= 29) { @@ -1710,13 +1704,13 @@ methodID += 2; else methodID += 3; - RINOK(CreateCoder_Id(EXTERNAL_CODECS_VARS methodID, false, mi.Coder)); + RINOK(CreateCoder_Id(EXTERNAL_CODECS_VARS methodID, false, mi.Coder)) } - if (mi.Coder == 0) + if (!mi.Coder) { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } @@ -1726,7 +1720,7 @@ CMyComPtr compressSetDecoderProperties; RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, - &compressSetDecoderProperties)); + &compressSetDecoderProperties)) Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); if (solidStart) @@ -1736,14 +1730,14 @@ } - RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)); + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)) commonCoder = decoder; break; } default: outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) continue; } @@ -1769,7 +1763,7 @@ else return result; } - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -1779,7 +1773,7 @@ IMPL_ISetCompressCodecsInfo REGISTER_ARC_I( - "Rar", "rar r00", 0, 3, + "Rar", "rar r00", NULL, 3, kMarker, 0, NArcInfoFlags::kFindSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.h 2020-09-28 09:29:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHandler.h 2024-01-05 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RarHandler.h -#ifndef __RAR_HANDLER_H -#define __RAR_HANDLER_H +#ifndef ZIP7_INC_RAR_HANDLER_H +#define ZIP7_INC_RAR_HANDLER_H #include "../IArchive.h" @@ -67,11 +67,21 @@ unsigned NumItems; }; -class CHandler: +class CHandler Z7_final: public IInArchive, - PUBLIC_ISetCompressCodecsInfo + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + DECL_ISetCompressCodecsInfo + + bool _isArc; + CRecordVector _refItems; CObjectVector _items; CObjectVector _arcs; @@ -79,7 +89,6 @@ // AString _errorMessage; UInt32 _errorFlags; UInt32 _warningFlags; - bool _isArc; UString _missingVolName; DECL_EXTERNAL_CODECS_VARS @@ -91,7 +100,7 @@ void AddErrorMessage(const AString &s) { if (!_errorMessage.IsEmpty()) - _errorMessage += '\n'; + _errorMessage.Add_LF(); _errorMessage += s; } */ @@ -99,16 +108,6 @@ HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback); - -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - - DECL_ISetCompressCodecsInfo }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarHeader.h 2016-05-20 11:31:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/RarHeader.h -#ifndef __ARCHIVE_RAR_HEADER_H -#define __ARCHIVE_RAR_HEADER_H +#ifndef ZIP7_INC_ARCHIVE_RAR_HEADER_H +#define ZIP7_INC_ARCHIVE_RAR_HEADER_H #include "../../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarItem.h 2016-02-23 10:00:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RarItem.h -#ifndef __ARCHIVE_RAR_ITEM_H -#define __ARCHIVE_RAR_ITEM_H +#ifndef ZIP7_INC_ARCHIVE_RAR_ITEM_H +#define ZIP7_INC_ARCHIVE_RAR_ITEM_H #include "../../../Common/StringConvert.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarVol.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarVol.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/RarVol.h 2022-02-15 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/RarVol.h 2023-01-17 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RarVol.h -#ifndef __ARCHIVE_RAR_VOL_H -#define __ARCHIVE_RAR_VOL_H +#ifndef ZIP7_INC_ARCHIVE_RAR_VOL_H +#define ZIP7_INC_ARCHIVE_RAR_VOL_H #include "../../../Common/StringConvert.h" @@ -22,7 +22,7 @@ UString _changed; UString _after; public: - CVolumeName(): _needChangeForNext(true) {}; + CVolumeName(): _needChangeForNext(true) {} bool InitName(const UString &name, bool newStyle = true) { @@ -52,7 +52,7 @@ ext.IsEqualTo_Ascii_NoCase("r01")) { _changed = ext; - _before.SetFrom(name.Ptr(), dotPos + 1); + _before.SetFrom(name.Ptr(), (unsigned)dotPos + 1); return true; } } @@ -83,7 +83,7 @@ _after.Empty(); _before = base; - _before += '.'; + _before.Add_Dot(); _changed = "r00"; _needChangeForNext = false; return true; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Rar/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Rar/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/RpmHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/RpmHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/RpmHandler.cpp 2022-02-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/RpmHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -19,7 +19,7 @@ #include "HandlerCont.h" -// #define _SHOW_RPM_METADATA +// #define Z7_RPM_SHOW_METADATA using namespace NWindows; @@ -97,7 +97,15 @@ , "ppc64" , "sh" , "xtensa" - , "aarch64" // 19 + , "aarch64" // 19 + , "mipsr6" // 20 + , "mips64r6" // 21 + , "riscv64" // 22 + , "loongarch64" // 23 + // , "24" + // , "25" + // , "loongarch64" // 26 : why 23 and 26 for loongarch64? + // 255 for some non specified arch }; static const char * const k_OS[] = @@ -128,8 +136,8 @@ struct CLead { - unsigned char Major; - unsigned char Minor; + Byte Major; + // Byte Minor; UInt16 Type; UInt16 Cpu; UInt16 Os; @@ -140,7 +148,7 @@ void Parse(const Byte *p) { Major = p[4]; - Minor = p[5]; + // Minor = p[5]; Type = Get16(p + 6); Cpu= Get16(p + 8); memcpy(Name, p + 10, kNameSize); @@ -169,7 +177,7 @@ }; -#ifdef _SHOW_RPM_METADATA +#ifdef Z7_RPM_SHOW_METADATA struct CMetaFile { UInt32 Tag; @@ -178,8 +186,10 @@ }; #endif -class CHandler: public CHandlerCont +Z7_class_CHandler_final: public CHandlerCont { + Z7_IFACE_COM7_IMP(IInArchive_Cont) + UInt64 _headersSize; // is equal to start offset of payload data UInt64 _payloadSize; UInt64 _size; @@ -203,11 +213,11 @@ AString _os; // linux AString _format; // cpio - AString _compressor; // xz, gzip, bzip2 + AString _compressor; // xz, gzip, bzip2, lzma, zstd CLead _lead; - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA AString _metadata; CRecordVector _metaFiles; #endif @@ -234,15 +244,12 @@ HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader); HRESULT Open2(ISequentialInStream *stream); - virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const + virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const Z7_override { pos = _headersSize; size = _size; return NExtract::NOperationResult::kOK; } - -public: - INTERFACE_IInArchive_Cont(;) }; static const Byte kArcProps[] = @@ -251,7 +258,7 @@ kpidCpu, kpidHostOS, kpidCTime - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA , kpidComment #endif }; @@ -274,7 +281,7 @@ { if (_lead.Type == kRpmType_Bin) { - if (_lead.Cpu < ARRAY_SIZE(k_CPUs)) + if (_lead.Cpu < Z7_ARRAY_SIZE(k_CPUs)) s += k_CPUs[_lead.Cpu]; else s.Add_UInt32(_lead.Cpu); @@ -290,19 +297,19 @@ s = _name; if (!_version.IsEmpty()) { - s += '-'; + s.Add_Minus(); s += _version; } if (!_release.IsEmpty()) { - s += '-'; + s.Add_Minus(); s += _release; } } else s.SetFrom_CalcLen(_lead.Name, kNameSize); - s += '.'; + s.Add_Dot(); if (_lead.Type == kRpmType_Src) s += "src"; else @@ -316,27 +323,31 @@ res += _format; else res += "cpio"; - res += '.'; + res.Add_Dot(); const char *s; if (!_compressor.IsEmpty()) { s = _compressor; - if (_compressor == "bzip2") + if (_compressor.IsEqualTo("bzip2")) s = "bz2"; - else if (_compressor == "gzip") + else if (_compressor.IsEqualTo("gzip")) s = "gz"; + else if (_compressor.IsEqualTo("zstd")) + s = "zst"; } else { const Byte *p = _payloadSig; - if (p[0] == 0x1F && p[1] == 0x8B) + if (p[0] == 0x1F && p[1] == 0x8B && p[2] == 8) s = "gz"; else if (p[0] == 0xFD && p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' && p[5] == 0) s = "xz"; else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h' && p[3] >= '1' && p[3] <= '9') s = "bz2"; + else if (p[0] == 0x28 && p[1] == 0xb5 && p[2] == 0x2f && p[3] == 0xfd) + s = "zst"; else s = "lzma"; } @@ -344,7 +355,7 @@ res += s; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -383,7 +394,7 @@ break; } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA // case kpidComment: SetStringProp(_metadata, prop); break; #endif @@ -399,7 +410,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; if (index == 0) @@ -418,7 +429,7 @@ case kpidPath: { AString s (GetBaseName()); - s += '.'; + s.Add_Dot(); AddSubFileExtension(s); SetStringProp(s, prop); break; @@ -432,7 +443,7 @@ } */ } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA else { index--; @@ -467,12 +478,6 @@ return S_OK; } -#ifdef _SHOW_RPM_METADATA -static inline char GetHex(unsigned value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} -#endif HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader) { @@ -480,7 +485,7 @@ UInt32 dataLen; { char buf[k_HeaderSig_Size]; - RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size)); + RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size)) if (Get32(buf) != 0x8EADE801) // buf[3] = 0x01 - is version return S_FALSE; // reserved = Get32(buf + 4); @@ -494,7 +499,7 @@ if (headerSize < dataLen) return S_FALSE; CByteBuffer buffer(headerSize); - RINOK(ReadStream_FALSE(stream, buffer, headerSize)); + RINOK(ReadStream_FALSE(stream, buffer, headerSize)) for (UInt32 i = 0; i < numEntries; i++) { @@ -520,7 +525,7 @@ } else { - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA { _metadata.Add_UInt32(entry.Tag); _metadata += ": "; @@ -547,7 +552,7 @@ case RPMTAG_PAYLOADCOMPRESSOR: _compressor = s; break; } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA _metadata += s; #endif } @@ -563,7 +568,7 @@ _time_Defined = true; } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA for (UInt32 t = 0; t < entry.Count; t++) { if (t != 0) @@ -573,7 +578,7 @@ #endif } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA else if ( entry.Type == k_EntryType_STRING_ARRAY || @@ -586,7 +591,7 @@ if (rem2 == 0) return S_FALSE; if (t != 0) - _metadata += '\n'; + _metadata.Add_LF(); size_t j; for (j = 0; j < rem2 && p2[j] != 0; j++); if (j == rem2) @@ -615,8 +620,8 @@ for (UInt32 t = 0; t < entry.Count; t++) { const unsigned b = p[t]; - _metadata += GetHex((b >> 4) & 0xF); - _metadata += GetHex(b & 0xF); + _metadata += GET_HEX_CHAR_UPPER(b >> 4); + _metadata += GET_HEX_CHAR_UPPER(b & 0xF); } } else @@ -624,11 +629,11 @@ // p = p; } - _metadata += '\n'; + _metadata.Add_LF(); #endif } - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA CMetaFile meta; meta.Offset = entry.Offset; meta.Tag = entry.Tag; @@ -656,7 +661,7 @@ { { Byte buf[kLeadSize]; - RINOK(ReadStream_FALSE(stream, buf, kLeadSize)); + RINOK(ReadStream_FALSE(stream, buf, kLeadSize)) if (Get32(buf) != 0xEDABEEDB) return S_FALSE; _lead.Parse(buf); @@ -668,22 +673,22 @@ if (_lead.SignatureType == RPMSIG_NONE) { - ; + } else if (_lead.SignatureType == RPMSIG_PGP262_1024) { Byte temp[256]; - RINOK(ReadStream_FALSE(stream, temp, sizeof(temp))); + RINOK(ReadStream_FALSE(stream, temp, sizeof(temp))) } else if (_lead.SignatureType == RPMSIG_HEADERSIG) { - RINOK(ReadHeader(stream, false)); + RINOK(ReadHeader(stream, false)) unsigned pos = (unsigned)_headersSize & 7; if (pos != 0) { Byte temp[8]; unsigned num = 8 - pos; - RINOK(ReadStream_FALSE(stream, temp, num)); + RINOK(ReadStream_FALSE(stream, temp, num)) _headersSize += num; } } @@ -694,20 +699,20 @@ } -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)) { COM_TRY_BEGIN { Close(); - RINOK(Open2(inStream)); + RINOK(Open2(inStream)) // start of payload is allowed to be unaligned - RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig))); + RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig))) if (!_payloadSize_Defined) { UInt64 endPos; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(InStream_GetSize_SeekToEnd(inStream, endPos)) _size = endPos - _headersSize; } _stream = inStream; @@ -716,7 +721,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _headersSize = 0; _payloadSize = 0; @@ -738,7 +743,7 @@ _format.Empty(); _compressor.Empty(); - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA _metadata.Empty(); _metaFiles.Size(); #endif @@ -747,10 +752,10 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1 - #ifdef _SHOW_RPM_METADATA + #ifdef Z7_RPM_SHOW_METADATA + _metaFiles.Size() #endif ; @@ -761,7 +766,7 @@ static const Byte k_Signature[] = { 0xED, 0xAB, 0xEE, 0xDB}; REGISTER_ARC_I( - "Rpm", "rpm", 0, 0xEB, + "Rpm", "rpm", NULL, 0xEB, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/SparseHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SparseHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/SparseHandler.cpp 2022-02-01 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SparseHandler.cpp 2024-02-17 10:00:00.000000000 +0000 @@ -42,11 +42,11 @@ { // G16 (4, major_version); // G16 (6, minor_version); - G16 (8, file_hdr_sz); - G16 (10, chunk_hdr_sz); - G32 (12, BlockSize); - G32 (16, NumBlocks); - G32 (20, NumChunks); + G16 (8, file_hdr_sz) + G16 (10, chunk_hdr_sz) + G32 (12, BlockSize) + G32 (16, NumBlocks) + G32 (20, NumChunks) // G32 (24, image_checksum); } }; @@ -58,9 +58,9 @@ #define CHUNK_TYPE_DONT_CARE 0xCAC3 #define CHUNK_TYPE_CRC32 0xCAC4 -#define MY__CHUNK_TYPE_FILL 0 -#define MY__CHUNK_TYPE_DONT_CARE 1 -#define MY__CHUNK_TYPE_RAW__START 2 +#define MY_CHUNK_TYPE_FILL 0 +#define MY_CHUNK_TYPE_DONT_CARE 1 +#define MY_CHUNK_TYPE_RAW_START 2 static const char * const g_Methods[] = { @@ -77,13 +77,27 @@ UInt32 VirtBlock; Byte Fill [kFillSize]; UInt64 PhyOffset; + + CChunk() + { + Fill[0] = + Fill[1] = + Fill[2] = + Fill[3] = + 0; + } }; static const Byte k_Signature[] = { 0x3a, 0xff, 0x26, 0xed, 1, 0 }; -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + CRecordVector Chunks; UInt64 _virtSize_fromChunks; unsigned _blockSizeLog; @@ -101,7 +115,7 @@ HRESULT Seek2(UInt64 offset) { _posInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, offset); } void InitSeekPositions() @@ -115,25 +129,19 @@ } // virtual functions - bool Init_PackSizeProcessed() + bool Init_PackSizeProcessed() Z7_override { _packSizeProcessed = 0; return true; } - bool Get_PackSizeProcessed(UInt64 &size) + bool Get_PackSizeProcessed(UInt64 &size) Z7_override { size = _packSizeProcessed; return true; } - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size, UInt32 &processed); - -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; @@ -154,7 +162,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -193,7 +201,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -228,7 +236,7 @@ CHeader h; { Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)) if (memcmp(buf, k_Signature, 6) != 0) return S_FALSE; h.Parse(buf); @@ -262,13 +270,13 @@ const UInt32 mask = ((UInt32)1 << 16) - 1; if ((i & mask) == mask && openCallback) { - RINOK(openCallback->SetCompleted(NULL, &offset)); + RINOK(openCallback->SetCompleted(NULL, &offset)) } } Byte buf[kChunkHeaderSize]; { size_t processed = kChunkHeaderSize; - RINOK(ReadStream(stream, buf, &processed)); + RINOK(ReadStream(stream, buf, &processed)) if (kChunkHeaderSize != processed) { offset += kChunkHeaderSize; @@ -301,7 +309,7 @@ return S_FALSE; { size_t processed = kFillSize; - RINOK(ReadStream(stream, c.Fill, &processed)); + RINOK(ReadStream(stream, c.Fill, &processed)) if (kFillSize != processed) break; } @@ -316,15 +324,15 @@ { if (size != 0) return S_FALSE; - c.PhyOffset = MY__CHUNK_TYPE_DONT_CARE; + c.PhyOffset = MY_CHUNK_TYPE_DONT_CARE; } else if (type == CHUNK_TYPE_FILL) { if (size != kFillSize) return S_FALSE; - c.PhyOffset = MY__CHUNK_TYPE_FILL; + c.PhyOffset = MY_CHUNK_TYPE_FILL; size_t processed = kFillSize; - RINOK(ReadStream(stream, c.Fill, &processed)); + RINOK(ReadStream(stream, c.Fill, &processed)) if (kFillSize != processed) break; } @@ -343,7 +351,7 @@ virtBlock += numBlocks; Chunks.AddInReserved(c); if (type == CHUNK_TYPE_RAW) - RINOK(stream->Seek(offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, offset)) } } @@ -367,7 +375,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { Chunks.Clear(); _isArc = false; @@ -388,7 +396,7 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; @@ -436,7 +444,7 @@ } -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -486,7 +494,7 @@ const UInt64 phyOffset = c.PhyOffset; - if (phyOffset >= MY__CHUNK_TYPE_RAW__START) + if (phyOffset >= MY_CHUNK_TYPE_RAW_START) { UInt32 processed = 0; const HRESULT res = ReadPhy(phyOffset + offset, data, size, processed); @@ -496,9 +504,9 @@ return res; } - unsigned b = 0; + Byte b = 0; - if (phyOffset == MY__CHUNK_TYPE_FILL) + if (phyOffset == MY_CHUNK_TYPE_FILL) { const Byte b0 = c.Fill [0]; const Byte b1 = c.Fill [1]; @@ -528,7 +536,7 @@ } b = b0; } - else if (phyOffset != MY__CHUNK_TYPE_DONT_CARE) + else if (phyOffset != MY_CHUNK_TYPE_DONT_CARE) return S_FALSE; memset(data, b, size); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/SplitHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SplitHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/SplitHandler.cpp 2022-05-15 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SplitHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -9,6 +9,7 @@ #include "../Common/ProgressUtils.h" #include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" #include "../Compress/CopyCoder.h" @@ -31,27 +32,22 @@ kpidTotalPhySize }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CObjectVector > _streams; CRecordVector _sizes; UString _subName; UInt64 _totalSize; HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -60,6 +56,7 @@ case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break; case kpidTotalPhySize: prop = _totalSize; break; case kpidNumVolumes: prop = (UInt32)_streams.Size(); break; + default: break; } prop.Detach(value); return S_OK; @@ -121,27 +118,29 @@ } }; + HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { Close(); if (!callback) return S_FALSE; - CMyComPtr volumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + volumeCallback, callback) if (!volumeCallback) return S_FALSE; UString name; { NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidName, &prop)); + RINOK(volumeCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) return S_FALSE; name = prop.bstrVal; } - int dotPos = name.ReverseFind_Dot(); + const int dotPos = name.ReverseFind_Dot(); const UString prefix = name.Left((unsigned)(dotPos + 1)); const UString ext = name.Ptr((unsigned)(dotPos + 1)); UString ext2 = ext; @@ -192,14 +191,13 @@ { /* NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); + RINOK(volumeCallback->GetProperty(kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; */ - RINOK(stream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } + RINOK(InStream_AtBegin_GetSize(stream, size)) _totalSize += size; _sizes.Add(size); @@ -207,7 +205,7 @@ { const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, NULL)) } for (;;) @@ -216,30 +214,20 @@ if (!seqName.GetNextName(fullName)) break; CMyComPtr nextStream; - HRESULT result = volumeCallback->GetStream(fullName, &nextStream); + const HRESULT result = volumeCallback->GetStream(fullName, &nextStream); if (result == S_FALSE) break; if (result != S_OK) return result; if (!nextStream) break; - { - /* - NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - */ - RINOK(nextStream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(nextStream->Seek(0, STREAM_SEEK_SET, NULL)); - } + RINOK(InStream_AtBegin_GetSize(nextStream, size)) _totalSize += size; _sizes.Add(size); _streams.Add(nextStream); { const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, NULL)) } } @@ -251,17 +239,17 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN - HRESULT res = Open2(stream, callback); + const HRESULT res = Open2(stream, callback); if (res != S_OK) Close(); return res; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _subName.Empty(); @@ -270,13 +258,13 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _streams.IsEmpty() ? 0 : 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -286,13 +274,14 @@ case kpidPackSize: prop = _totalSize; break; + default: break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -301,15 +290,15 @@ return E_INVALIDARG; UInt64 currentTotalSize = 0; - RINOK(extractCallback->SetTotal(_totalSize)); + RINOK(extractCallback->SetTotal(_totalSize)) CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &outStream, askMode)); + RINOK(extractCallback->GetStream(0, &outStream, askMode)) if (!testMode && !outStream) return S_OK; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr copyCoder = copyCoderSpec; @@ -318,13 +307,15 @@ CMyComPtr progress = lps; lps->Init(extractCallback, false); - FOR_VECTOR (i, _streams) + for (unsigned i = 0;; i++) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i == _streams.Size()) + break; IInStream *inStream = _streams[i]; - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(InStream_SeekToBegin(inStream)) + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) currentTotalSize += copyCoderSpec->TotalSize; } outStream.Release(); @@ -332,12 +323,12 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN if (index != 0) return E_INVALIDARG; - *stream = 0; + *stream = NULL; CMultiStream *streamSpec = new CMultiStream; CMyComPtr streamTemp = streamSpec; FOR_VECTOR (i, _streams) @@ -354,7 +345,7 @@ } REGISTER_ARC_I_NO_SIG( - "Split", "001", 0, 0xEA, + "Split", "001", NULL, 0xEA, 0, 0, NULL) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/SquashfsHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SquashfsHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/SquashfsHandler.cpp 2022-05-02 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SquashfsHandler.cpp 2023-12-19 11:00:00.000000000 +0000 @@ -3,9 +3,10 @@ #include "StdAfx.h" #include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" #include "../../../C/LzmaDec.h" #include "../../../C/Xz.h" +#include "../../../C/ZstdDec.h" +#include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" #include "../../Common/MyLinux.h" @@ -30,8 +31,8 @@ namespace NArchive { namespace NSquashfs { -static const UInt32 kNumFilesMax = (1 << 28); -static const unsigned kNumDirLevelsMax = (1 << 10); +static const UInt32 kNumFilesMax = 1 << 28; +static const unsigned kNumDirLevelsMax = 1 << 10; // Layout: Header, Data, inodes, Directories, Fragments, UIDs, GIDs @@ -49,13 +50,13 @@ #define Get32(p) Get32b(p, be) #define Get64(p) Get64b(p, be) -#define LE_16(offs, dest) dest = GetUi16(p + (offs)); -#define LE_32(offs, dest) dest = GetUi32(p + (offs)); -#define LE_64(offs, dest) dest = GetUi64(p + (offs)); - -#define GET_16(offs, dest) dest = Get16(p + (offs)); -#define GET_32(offs, dest) dest = Get32(p + (offs)); -#define GET_64(offs, dest) dest = Get64(p + (offs)); +#define LE_16(offs, dest) dest = GetUi16(p + (offs)) +#define LE_32(offs, dest) dest = GetUi32(p + (offs)) +#define LE_64(offs, dest) dest = GetUi64(p + (offs)) + +#define GET_16(offs, dest) dest = Get16(p + (offs)) +#define GET_32(offs, dest) dest = Get32(p + (offs)) +#define GET_64(offs, dest) dest = Get64(p + (offs)) static const UInt32 kSignature32_LE = 0x73717368; static const UInt32 kSignature32_BE = 0x68737173; @@ -66,6 +67,8 @@ #define kMethod_LZMA 2 #define kMethod_LZO 3 #define kMethod_XZ 4 +// #define kMethod_LZ4 5 +#define kMethod_ZSTD 6 static const char * const k_Methods[] = { @@ -74,6 +77,8 @@ , "LZMA" , "LZO" , "XZ" + , "LZ4" + , "ZSTD" }; static const unsigned kMetadataBlockSizeLog = 13; @@ -127,8 +132,8 @@ , "UNCOMPRESSED_IDS" }; -static const UInt32 kNotCompressedBit16 = (1 << 15); -static const UInt32 kNotCompressedBit32 = (1 << 24); +static const UInt32 kNotCompressedBit16 = 1 << 15; +static const UInt32 kNotCompressedBit32 = 1 << 24; #define GET_COMPRESSED_BLOCK_SIZE(size) ((size) & ~kNotCompressedBit32) #define IS_COMPRESSED_BLOCK(size) (((size) & kNotCompressedBit32) == 0) @@ -831,11 +836,13 @@ UInt32 Size; }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + bool _noPropsLZMA; + bool _needCheckLzma; + CRecordVector _items; CRecordVector _nodes; CRecordVector _nodesPos; @@ -846,16 +853,13 @@ CByteBuffer _uids; CByteBuffer _gids; CHeader _h; - bool _noPropsLZMA; - bool _needCheckLzma; - UInt32 _openCodePage; - - CMyComPtr _stream; UInt64 _sizeCalculated; + CMyComPtr _stream; IArchiveOpenCallback *_openCallback; + UInt32 _openCodePage; int _nodeIndex; CRecordVector _blockCompressed; CRecordVector _blockOffsets; @@ -865,25 +869,18 @@ UInt32 _cachedPackBlockSize; UInt32 _cachedUnpackBlockSize; - CLimitedSequentialInStream *_limitedInStreamSpec; - CMyComPtr _limitedInStream; - - CBufPtrSeqOutStream *_outStreamSpec; - CMyComPtr _outStream; - - // NCompress::NLzma::CDecoder *_lzmaDecoderSpec; - // CMyComPtr _lzmaDecoder; + CMyComPtr2_Create _limitedInStream; + CMyComPtr2_Create _outStream; + CMyComPtr2_Create _dynOutStream; - NCompress::NZlib::CDecoder *_zlibDecoderSpec; - CMyComPtr _zlibDecoder; + // CMyComPtr2 _lzmaDecoder; + CMyComPtr2 _zlibDecoder; CXzUnpacker _xz; + CZstdDecHandle _zstd; CByteBuffer _inputBuffer; - CDynBufSeqOutStream *_dynOutStreamSpec; - CMyComPtr _dynOutStream; - void ClearCache() { _cachedBlockStartPos = 0; @@ -893,7 +890,7 @@ HRESULT Seek2(UInt64 offset) { - return _stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(_stream, offset); } HRESULT Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize, @@ -906,35 +903,26 @@ HRESULT ScanInodes(UInt64 ptr); HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids); HRESULT Open2(IInStream *inStream); - AString GetPath(int index) const; - bool GetPackSize(int index, UInt64 &res, bool fillOffsets); + AString GetPath(unsigned index) const; + bool GetPackSize(unsigned index, UInt64 &res, bool fillOffsets); public: CHandler(); ~CHandler() { XzUnpacker_Free(&_xz); + if (_zstd) + ZstdDec_Destroy(_zstd); } - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); }; -CHandler::CHandler() + +CHandler::CHandler(): + _zstd(NULL) { XzUnpacker_Construct(&_xz, &g_Alloc); - - _limitedInStreamSpec = new CLimitedSequentialInStream; - _limitedInStream = _limitedInStreamSpec; - - _outStreamSpec = new CBufPtrSeqOutStream(); - _outStream = _outStreamSpec; - - _dynOutStreamSpec = new CDynBufSeqOutStream; - _dynOutStream = _dynOutStreamSpec; } static const Byte kProps[] = @@ -1044,7 +1032,7 @@ } srcRem--; - back = (b >> 2) + (*src++ << 2); + back = (b >> 2) + ((UInt32)*src++ << 2); len = 2; if (mode == 4) { @@ -1086,8 +1074,8 @@ back += ((bOld & 8) << 11); if (back == 0) { - *destLen = dest - destStart; - *srcLen = src - srcStart; + *destLen = (size_t)(dest - destStart); + *srcLen = (size_t)(src - srcStart); return S_OK; } back += (1 << 14) - 1; @@ -1137,16 +1125,16 @@ if (_h.SeveralMethods) { Byte b; - RINOK(ReadStream_FALSE(_stream, &b, 1)); - RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)); + RINOK(ReadStream_FALSE(_stream, &b, 1)) + RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)) method = (b == 0x5D ? kMethod_LZMA : kMethod_ZLIB); } if (method == kMethod_ZLIB && _needCheckLzma) { Byte b; - RINOK(ReadStream_FALSE(_stream, &b, 1)); - RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)); + RINOK(ReadStream_FALSE(_stream, &b, 1)) + RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)) if (b == 0) { _noPropsLZMA = true; @@ -1157,24 +1145,16 @@ if (method == kMethod_ZLIB) { - if (!_zlibDecoder) - { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); - _zlibDecoder = _zlibDecoderSpec; - } - RINOK(_zlibDecoder->Code(_limitedInStream, outStream, NULL, NULL, NULL)); - if (inSize != _zlibDecoderSpec->GetInputProcessedSize()) + _zlibDecoder.Create_if_Empty(); + RINOK(_zlibDecoder.Interface()->Code(_limitedInStream, outStream, NULL, NULL, NULL)) + if (inSize != _zlibDecoder->GetInputProcessedSize()) return S_FALSE; } /* else if (method == kMethod_LZMA) { - if (!_lzmaDecoder) - { - _lzmaDecoderSpec = new NCompress::NLzma::CDecoder(); - // _lzmaDecoderSpec->FinishStream = true; - _lzmaDecoder = _lzmaDecoderSpec; - } + _lzmaDecoder.Create_if_Empty(); + // _lzmaDecoder->FinishStream = true; const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; Byte props[kPropsSize]; UInt32 propsSize; @@ -1204,12 +1184,12 @@ { if (_inputBuffer.Size() < inSize) _inputBuffer.Alloc(inSize); - RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize)); + RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize)) Byte *dest = outBuf; if (!outBuf) { - dest = _dynOutStreamSpec->GetBufPtrForWriting(outSizeMax); + dest = _dynOutStream->GetBufPtrForWriting(outSizeMax); if (!dest) return E_OUTOFMEMORY; } @@ -1218,7 +1198,7 @@ if (method == kMethod_LZO) { - RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen)); + RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen)) } else if (method == kMethod_LZMA) { @@ -1228,7 +1208,7 @@ if (_noPropsLZMA) { props[0] = 0x5D; - SetUi32(&props[1], _h.BlockSize); + SetUi32(&props[1], _h.BlockSize) } else { @@ -1257,10 +1237,67 @@ && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) return S_FALSE; } + else if (method == kMethod_ZSTD) + { + const Byte *src = _inputBuffer; + + if (!_zstd) + { + _zstd = ZstdDec_Create(&g_AlignedAlloc, &g_AlignedAlloc); + if (!_zstd) + return E_OUTOFMEMORY; + } + + CZstdDecState state; + ZstdDecState_Clear(&state); + + state.inBuf = src; + state.inLim = srcLen; // + 1; for debug + // state.outStep = outSizeMax; + + state.outBuf_fromCaller = dest; + state.outBufSize_fromCaller = outSizeMax; + // state.mustBeFinished = True; + + ZstdDec_Init(_zstd); + SRes sres; + for (;;) + { + sres = ZstdDec_Decode(_zstd, &state); + if (sres != SZ_OK) + break; + if (state.inLim == state.inPos + && (state.status == ZSTD_STATUS_NEEDS_MORE_INPUT || + state.status == ZSTD_STATUS_FINISHED_FRAME)) + break; + // sres = sres; + // break; // for debug + } + + CZstdDecResInfo info; + // ZstdDecInfo_Clear(&stat); + // stat->InSize = state.inPos; + ZstdDec_GetResInfo(_zstd, &state, sres, &info); + sres = info.decode_SRes; + if (sres == SZ_OK) + { + if (state.status != ZSTD_STATUS_FINISHED_FRAME + // ||stat.UnexpededEnd + || info.extraSize != 0 + || state.inLim != state.inPos) + sres = SZ_ERROR_DATA; + } + if (sres != SZ_OK) + return SResToHRESULT(sres); + if (state.winPos > outSizeMax) + return E_FAIL; + // memcpy(dest, state.dic, state.dicPos); + destLen = state.winPos; + } else { ECoderStatus status; - SRes res = XzUnpacker_CodeFull(&_xz, + const SRes res = XzUnpacker_CodeFull(&_xz, dest, &destLen, _inputBuffer, &srcLen, CODER_FINISH_END, &status); @@ -1278,7 +1315,7 @@ *outBufWasWrittenSize = (UInt32)destLen; } else - _dynOutStreamSpec->UpdateSize(destLen); + _dynOutStream->UpdateSize(destLen); } return S_OK; } @@ -1289,7 +1326,7 @@ const unsigned offset = _h.NeedCheckData() ? 3 : 2; if (offset > packSize) return S_FALSE; - RINOK(ReadStream_FALSE(_stream, temp, offset)); + RINOK(ReadStream_FALSE(_stream, temp, offset)) // if (NeedCheckData && Major < 4) checkByte must be = 0xFF const bool be = _h.be; UInt32 size = Get16(temp); @@ -1302,17 +1339,17 @@ packSize = offset + size; if (isCompressed) { - _limitedInStreamSpec->Init(size); - RINOK(Decompress(_dynOutStream, NULL, NULL, NULL, size, kMetadataBlockSize)); + _limitedInStream->Init(size); + RINOK(Decompress(_dynOutStream, NULL, NULL, NULL, size, kMetadataBlockSize)) } else { // size != 0 here - Byte *buf = _dynOutStreamSpec->GetBufPtrForWriting(size); + Byte *buf = _dynOutStream->GetBufPtrForWriting(size); if (!buf) return E_OUTOFMEMORY; - RINOK(ReadStream_FALSE(_stream, buf, size)); - _dynOutStreamSpec->UpdateSize(size); + RINOK(ReadStream_FALSE(_stream, buf, size)) + _dynOutStream->UpdateSize(size); } return S_OK; } @@ -1320,7 +1357,7 @@ HRESULT CHandler::ReadMetadataBlock2() { - _dynOutStreamSpec->Init(); + _dynOutStream->Init(); UInt32 packSize = kMetadataBlockSize + 3; // check it return ReadMetadataBlock(packSize); } @@ -1330,26 +1367,26 @@ if (end < start || end - start >= ((UInt64)1 << 32)) return S_FALSE; const UInt32 size = (UInt32)(end - start); - RINOK(Seek2(start)); - _dynOutStreamSpec->Init(); + RINOK(Seek2(start)) + _dynOutStream->Init(); UInt32 packPos = 0; while (packPos != size) { data.PackPos.Add(packPos); - data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize()); + data.UnpackPos.Add((UInt32)_dynOutStream->GetSize()); if (packPos > size) return S_FALSE; UInt32 packSize = size - packPos; - RINOK(ReadMetadataBlock(packSize)); + RINOK(ReadMetadataBlock(packSize)) { - const size_t tSize = _dynOutStreamSpec->GetSize(); + const size_t tSize = _dynOutStream->GetSize(); if (tSize != (UInt32)tSize) return S_FALSE; } packPos += packSize; } - data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize()); - _dynOutStreamSpec->CopyToBuffer(data.Data); + data.UnpackPos.Add((UInt32)_dynOutStream->GetSize()); + _dynOutStream->CopyToBuffer(data.Data); return S_OK; } @@ -1459,14 +1496,14 @@ if (rem < nameOffset) return S_FALSE; - if ((UInt32)_items.Size() >= kNumFilesMax) + if (_items.Size() >= kNumFilesMax) return S_FALSE; if (_openCallback) { UInt64 numFiles = _items.Size(); if ((numFiles & 0xFFFF) == 0) { - RINOK(_openCallback->SetCompleted(&numFiles, NULL)); + RINOK(_openCallback->SetCompleted(&numFiles, NULL)) } } @@ -1521,13 +1558,13 @@ } } - int startItemIndex = _items.Size() - tempItems.Size(); + const unsigned startItemIndex = _items.Size() - tempItems.Size(); FOR_VECTOR (i, tempItems) { const CTempItem &tempItem = tempItems[i]; - int index = startItemIndex + i; + const unsigned index = startItemIndex + i; CItem &item = _items[index]; - RINOK(OpenDir(index, tempItem.StartBlock, tempItem.Offset, level + 1, item.Node)); + RINOK(OpenDir((int)index, tempItem.StartBlock, tempItem.Offset, level + 1, item.Node)) } return S_OK; @@ -1539,7 +1576,7 @@ ids.Alloc(size); if (num == 0) return S_OK; - RINOK(Seek2(start)); + RINOK(Seek2(start)) return ReadStream_FALSE(_stream, ids, size); } @@ -1547,7 +1584,7 @@ { { Byte buf[kHeaderSize3]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize3)); + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize3)) if (!_h.Parse(buf)) return S_FALSE; if (!_h.IsSupported()) @@ -1561,6 +1598,7 @@ case kMethod_LZMA: case kMethod_LZO: case kMethod_XZ: + case kMethod_ZSTD: break; default: return E_NOTIMPL; @@ -1580,20 +1618,20 @@ const UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog; const size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag); CByteBuffer data(numBlocksBytes); - RINOK(Seek2(_h.FragTable)); - RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)); + RINOK(Seek2(_h.FragTable)) + RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)) const bool be = _h.be; for (UInt32 i = 0; i < numBlocks; i++) { const UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4); - RINOK(Seek2(offset)); - RINOK(ReadMetadataBlock2()); - const UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize(); + RINOK(Seek2(offset)) + RINOK(ReadMetadataBlock2()) + const UInt32 unpackSize = (UInt32)_dynOutStream->GetSize(); if (unpackSize != kMetadataBlockSize) if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1))) return S_FALSE; - const Byte *buf = _dynOutStreamSpec->GetBuffer(); + const Byte *buf = _dynOutStream->GetBuffer(); for (UInt32 j = 0; j < kMetadataBlockSize && j < unpackSize;) { CFrag frag; @@ -1617,8 +1655,8 @@ return S_FALSE; } - RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable)); - RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable)); + RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable)) + RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable)) UInt64 absOffset = _h.RootInode >> 16; if (absOffset >= ((UInt64)1 << 32)) @@ -1663,12 +1701,12 @@ return S_FALSE; } int rootNodeIndex; - RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex)); + RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex)) if (_h.Major < 4) { - RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids)); - RINOK(ReadUids(_h.GidTable, _h.NumGids, _gids)); + RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids)) + RINOK(ReadUids(_h.GidTable, _h.NumGids, _gids)) } else { @@ -1677,29 +1715,29 @@ const UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize; const UInt32 numBlocksBytes = numBlocks << 3; - CByteBuffer data; - data.Alloc(numBlocksBytes); - RINOK(Seek2(_h.UidTable)); - RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)); + CByteBuffer data(numBlocksBytes); + RINOK(Seek2(_h.UidTable)) + RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)) for (UInt32 i = 0; i < numBlocks; i++) { const UInt64 offset = GetUi64(data + i * 8); - RINOK(Seek2(offset)); + RINOK(Seek2(offset)) // RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize)); - RINOK(ReadMetadataBlock2()); - const size_t unpackSize = _dynOutStreamSpec->GetSize(); - if (unpackSize != kMetadataBlockSize) - if (i != numBlocks - 1 || unpackSize != (size & (kMetadataBlockSize - 1))) - return S_FALSE; - memcpy(_uids + kMetadataBlockSize * i, _dynOutStreamSpec->GetBuffer(), unpackSize); + RINOK(ReadMetadataBlock2()) + const size_t unpackSize = _dynOutStream->GetSize(); + const UInt32 remSize = (i == numBlocks - 1) ? + (size & (kMetadataBlockSize - 1)) : kMetadataBlockSize; + if (unpackSize != remSize) + return S_FALSE; + memcpy(_uids + kMetadataBlockSize * i, _dynOutStream->GetBuffer(), remSize); } } { const UInt32 alignSize = 1 << 12; Byte buf[alignSize]; - RINOK(Seek2(_h.Size)); + RINOK(Seek2(_h.Size)) UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1); _sizeCalculated = _h.Size; if (rem != 0) @@ -1716,23 +1754,24 @@ return S_OK; } -AString CHandler::GetPath(int index) const +AString CHandler::GetPath(unsigned index) const { unsigned len = 0; - int indexMem = index; + const unsigned indexMem = index; const bool be = _h.be; - do + for (;;) { const CItem &item = _items[index]; - index = item.Parent; const Byte *p = _dirs.Data + item.Ptr; - unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; + const unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; p += _h.GetFileNameOffset(); unsigned i; for (i = 0; i < size && p[i]; i++); len += i + 1; + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; } - while (index >= 0); len--; AString path; @@ -1741,27 +1780,27 @@ for (;;) { const CItem &item = _items[index]; - index = item.Parent; const Byte *p = _dirs.Data + item.Ptr; - unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; + const unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; p += _h.GetFileNameOffset(); unsigned i; for (i = 0; i < size && p[i]; i++); dest -= i; memcpy(dest, p, i); - if (index < 0) + index = (unsigned)item.Parent; + if (item.Parent < 0) break; *(--dest) = CHAR_PATH_SEPARATOR; } return path; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { Close(); - _limitedInStreamSpec->SetStream(stream); + _limitedInStream->SetStream(stream); HRESULT res; try { @@ -1784,12 +1823,12 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _openCodePage = CP_UTF8; _sizeCalculated = 0; - _limitedInStreamSpec->ReleaseStream(); + _limitedInStream->ReleaseStream(); _stream.Release(); _items.Clear(); @@ -1800,8 +1839,8 @@ _inodesData.Clear(); _dirs.Clear(); - // _uids.Free(); - // _gids.Free();; + _uids.Free(); + _gids.Free(); _cachedBlock.Free(); ClearCache(); @@ -1809,7 +1848,7 @@ return S_OK; } -bool CHandler::GetPackSize(int index, UInt64 &totalPack, bool fillOffsets) +bool CHandler::GetPackSize(unsigned index, UInt64 &totalPack, bool fillOffsets) { totalPack = 0; const CItem &item = _items[index]; @@ -1818,7 +1857,7 @@ const Byte *p = _inodesData.Data + ptr; const bool be = _h.be; - UInt32 type = node.Type; + const UInt32 type = node.Type; UInt32 offset; if (node.IsLink() || node.FileSize == 0) { @@ -1826,7 +1865,7 @@ return true; } - UInt32 numBlocks = (UInt32)node.GetNumBlocks(_h); + const UInt32 numBlocks = (UInt32)node.GetNumBlocks(_h); if (fillOffsets) { @@ -1896,13 +1935,13 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -1919,7 +1958,7 @@ else { s = NULL; - if (_h.Method < ARRAY_SIZE(k_Methods)) + if (_h.Method < Z7_ARRAY_SIZE(k_Methods)) s = k_Methods[_h.Method]; if (!s) { @@ -1937,7 +1976,7 @@ res += "-LZMA"; res.Add_Space(); res.Add_UInt32(_h.Major); - res += '.'; + res.Add_Dot(); res.Add_UInt32(_h.Minor); prop = res; break; @@ -1979,7 +2018,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -2043,40 +2082,29 @@ } case kpidPosixAttrib: { - if (node.Type != 0 && node.Type < ARRAY_SIZE(k_TypeToMode)) + if (node.Type != 0 && node.Type < Z7_ARRAY_SIZE(k_TypeToMode)) prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; break; } case kpidUserId: - { - const UInt32 offset = (UInt32)node.Uid * 4; - if (offset < _uids.Size()) - prop = (UInt32)Get32(_uids + offset); - break; - } case kpidGroupId: { - if (_h.Major < 4) + UInt32 id = node.Uid; + const CByteBuffer *ids = &_uids; + if (propID == kpidGroupId) { - if (node.Gid == _h.GetSpecGuidIndex()) - { - const UInt32 offset = (UInt32)node.Uid * 4; - if (offset < _uids.Size()) - prop = (UInt32)Get32(_uids + offset); - } - else + id = node.Gid; + if (_h.Major < 4) { - const UInt32 offset = (UInt32)node.Gid * 4; - if (offset < _gids.Size()) - prop = (UInt32)Get32(_gids + offset); + if (id == _h.GetSpecGuidIndex()) + id = node.Uid; + else + ids = &_gids; } } - else - { - const UInt32 offset = (UInt32)node.Gid * 4; - if (offset < _uids.Size()) - prop = (UInt32)Get32(_uids + offset); - } + const UInt32 offset = (UInt32)id * 4; + if (offset < ids->Size()) + prop = (UInt32)Get32(*ids + offset); break; } /* @@ -2093,7 +2121,7 @@ class CSquashfsInStream: public CCachedInStream { - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) Z7_override; public: CHandler *Handler; }; @@ -2139,26 +2167,26 @@ packBlockSize != _cachedPackBlockSize) { ClearCache(); - RINOK(Seek2(blockOffset)); - _limitedInStreamSpec->Init(packBlockSize); + RINOK(Seek2(blockOffset)) + _limitedInStream->Init(packBlockSize); if (compressed) { - _outStreamSpec->Init((Byte *)_cachedBlock, _h.BlockSize); + _outStream->Init((Byte *)_cachedBlock, _h.BlockSize); bool outBufWasWritten; UInt32 outBufWasWrittenSize; HRESULT res = Decompress(_outStream, _cachedBlock, &outBufWasWritten, &outBufWasWrittenSize, packBlockSize, _h.BlockSize); - RINOK(res); + RINOK(res) if (outBufWasWritten) _cachedUnpackBlockSize = outBufWasWrittenSize; else - _cachedUnpackBlockSize = (UInt32)_outStreamSpec->GetPos(); + _cachedUnpackBlockSize = (UInt32)_outStream->GetPos(); } else { if (packBlockSize > _h.BlockSize) return S_FALSE; - RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize)); + RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize)) _cachedUnpackBlockSize = packBlockSize; } _cachedBlockStartPos = blockOffset; @@ -2171,11 +2199,11 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -2188,40 +2216,42 @@ const CNode &node = _nodes[item.Node]; totalSize += node.GetSize(); } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 totalPackSize; totalSize = totalPackSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + int res; + { CMyComPtr outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; const CNode &node = _nodes[item.Node]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) // const Byte *p = _data + item.Offset; if (node.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } - UInt64 unpackSize = node.GetSize(); + const UInt64 unpackSize = node.GetSize(); totalSize += unpackSize; UInt64 packSize; if (GetPackSize(index, packSize, false)) @@ -2229,9 +2259,9 @@ if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) - int res = NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; { CMyComPtr inSeqStream; HRESULT hres = GetStream(index, &inSeqStream); @@ -2243,12 +2273,12 @@ } else { - RINOK(hres); + RINOK(hres) { - hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); + hres = copyCoder.Interface()->Code(inSeqStream, outStream, NULL, NULL, lps); if (hres == S_OK) { - if (copyCoderSpec->TotalSize == unpackSize) + if (copyCoder->TotalSize == unpackSize) res = NExtract::NOperationResult::kOK; } else if (hres == E_NOTIMPL) @@ -2257,13 +2287,13 @@ } else if (hres != S_FALSE) { - RINOK(hres); + RINOK(hres) } } } } - - RINOK(extractCallback->SetOperationResult(res)); + } + RINOK(extractCallback->SetOperationResult(res)) } return S_OK; @@ -2271,7 +2301,7 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN @@ -2331,7 +2361,7 @@ 4, 'q', 's', 'h', 's' }; REGISTER_ARC_I( - "SquashFS", "squashfs", 0, 0xD2, + "SquashFS", "squashfs", NULL, 0xD2, k_Signature, 0, NArcInfoFlags::kMultiSignature, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/StdAfx.h 2013-11-13 06:36:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/SwfHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SwfHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/SwfHandler.cpp 2021-12-16 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/SwfHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -25,9 +25,9 @@ #include "Common/DummyOutStream.h" -// #define SWF_UPDATE +// #define Z7_SWF_UPDATE -#ifdef SWF_UPDATE +#ifdef Z7_SWF_UPDATE #include "../Compress/LzmaEncoder.h" #include "../Compress/ZlibEncoder.h" @@ -142,7 +142,7 @@ Buf[0] = SWF_COMPRESSED_LZMA; if (Buf[3] < SWF_MIN_COMPRESSED_LZMA_VER) Buf[3] = SWF_MIN_COMPRESSED_LZMA_VER; - SetUi32(Buf + 8, packSize); + SetUi32(Buf + 8, packSize) HeaderSize = kHeaderLzmaSize; } @@ -157,37 +157,37 @@ } }; -class CHandler: + +Z7_class_CHandler_final: public IInArchive, public IArchiveOpenSeq, - #ifdef SWF_UPDATE + #ifdef Z7_SWF_UPDATE public IOutArchive, public ISetProperties, #endif public CMyUnknownImp { + #ifdef Z7_SWF_UPDATE + Z7_IFACES_IMP_UNK_4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) + #else + Z7_IFACES_IMP_UNK_2(IInArchive, IArchiveOpenSeq) + #endif + CItem _item; UInt64 _packSize; bool _packSizeDefined; CMyComPtr _seqStream; CMyComPtr _stream; - #ifdef SWF_UPDATE +#ifdef Z7_SWF_UPDATE CSingleMethodProps _props; bool _lzmaMode; - #endif +#endif public: - #ifdef SWF_UPDATE - MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) + #ifdef Z7_SWF_UPDATE CHandler(): _lzmaMode(false) {} - INTERFACE_IOutArchive(;) - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #else - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) #endif - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); }; static const Byte kProps[] = @@ -200,7 +200,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -212,7 +212,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; @@ -222,7 +222,7 @@ { char c = 0; unsigned i; - for (i = 0; i <= 31; i++) + for (i = 0; i < 32; i++) if (((UInt32)1 << i) == val) { val = i; @@ -240,7 +240,7 @@ s[pos] = 0; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; switch (propID) @@ -265,22 +265,22 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) { - RINOK(OpenSeq(stream)); + RINOK(OpenSeq(stream)) _stream = stream; return S_OK; } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); - RINOK(_item.ReadHeader(stream)); + RINOK(_item.ReadHeader(stream)) if (!_item.IsSwf()) return S_FALSE; if (_item.IsLzma()) { - RINOK(ReadStream_FALSE(stream, _item.Buf + kHeaderBaseSize, kHeaderLzmaSize - kHeaderBaseSize)); + RINOK(ReadStream_FALSE(stream, _item.Buf + kHeaderBaseSize, kHeaderLzmaSize - kHeaderBaseSize)) _item.HeaderSize = kHeaderLzmaSize; _packSize = _item.GetLzmaPackSize(); _packSizeDefined = true; @@ -293,7 +293,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _packSize = 0; _packSizeDefined = false; @@ -302,31 +302,29 @@ return S_OK; } -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) CMyComPtr Callback; public: UInt64 Offset; - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); void Init(IArchiveOpenCallback *callback) { Callback = callback; } }; -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { - UInt64 files = 0; - UInt64 value = Offset + *inSize; + const UInt64 files = 0; + const UInt64 value = Offset + *inSize; return Callback->SetCompleted(&files, &value); } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -334,42 +332,42 @@ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - extractCallback->SetTotal(_item.GetSize()); + RINOK(extractCallback->SetTotal(_item.GetSize())) + Int32 opRes; +{ CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); lps->InSize = _item.HeaderSize; - lps->OutSize = outStreamSpec->GetSize(); - RINOK(lps->SetCur()); + lps->OutSize = outStream->GetSize(); + RINOK(lps->SetCur()) CItem item = _item; item.MakeUncompressed(); if (_stream) - RINOK(_stream->Seek(_item.HeaderSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, _item.HeaderSize)) NCompress::NZlib::CDecoder *_decoderZlibSpec = NULL; NCompress::NLzma::CDecoder *_decoderLzmaSpec = NULL; CMyComPtr _decoder; CMyComPtr inStream2; - UInt64 unpackSize = _item.GetSize() - (UInt32)8; + const UInt64 unpackSize = _item.GetSize() - (UInt32)8; if (_item.IsZlib()) { _decoderZlibSpec = new NCompress::NZlib::CDecoder; @@ -400,16 +398,16 @@ if (dicSize > (UInt32)unpackSize) { dicSize = (UInt32)unpackSize; - SetUi32(props + 1, dicSize); + SetUi32(props + 1, dicSize) } - RINOK(_decoderLzmaSpec->SetDecoderProperties2(props, 5)); + RINOK(_decoderLzmaSpec->SetDecoderProperties2(props, 5)) } - RINOK(item.WriteHeader(outStream)); - HRESULT result = _decoder->Code(inStream2, outStream, NULL, &unpackSize, progress); - Int32 opRes = NExtract::NOperationResult::kDataError; + RINOK(item.WriteHeader(outStream)) + const HRESULT result = _decoder->Code(inStream2, outStream, NULL, &unpackSize, lps); + opRes = NExtract::NOperationResult::kDataError; if (result == S_OK) { - if (item.GetSize() == outStreamSpec->GetSize()) + if (item.GetSize() == outStream->GetSize()) { if (_item.IsZlib()) { @@ -427,24 +425,25 @@ else if (result != S_FALSE) return result; - outStream.Release(); + // outStream.Release(); + } return extractCallback->SetOperationResult(opRes); COM_TRY_END } -#ifdef SWF_UPDATE +#ifdef Z7_SWF_UPDATE static HRESULT UpdateArchive(ISequentialOutStream *outStream, UInt64 size, bool lzmaMode, const CSingleMethodProps &props, IArchiveUpdateCallback *updateCallback) { UInt64 complexity = 0; - RINOK(updateCallback->SetTotal(size)); - RINOK(updateCallback->SetCompleted(&complexity)); + RINOK(updateCallback->SetTotal(size)) + RINOK(updateCallback->SetCompleted(&complexity)) CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); + RINOK(updateCallback->GetStream(0, &fileInStream)) /* CDummyOutStream *outStreamSpec = new CDummyOutStream; @@ -455,10 +454,10 @@ */ CItem item; - HRESULT res = item.ReadHeader(fileInStream); + const HRESULT res = item.ReadHeader(fileInStream); if (res == S_FALSE) return E_INVALIDARG; - RINOK(res); + RINOK(res) if (!item.IsSwf() || !item.IsUncompressed() || size != item.GetSize()) return E_INVALIDARG; @@ -473,39 +472,38 @@ return E_NOTIMPL; encoderLzmaSpec = new NCompress::NLzma::CEncoder; encoder = encoderLzmaSpec; - RINOK(props.SetCoderProps(encoderLzmaSpec, &size)); + RINOK(props.SetCoderProps(encoderLzmaSpec, &size)) item.MakeLzma((UInt32)0xFFFFFFFF); CBufPtrSeqOutStream *propStreamSpec = new CBufPtrSeqOutStream; CMyComPtr propStream = propStreamSpec; propStreamSpec->Init(item.Buf + 12, 5); - RINOK(encoderLzmaSpec->WriteCoderProperties(propStream)); + RINOK(encoderLzmaSpec->WriteCoderProperties(propStream)) } else { encoderZlibSpec = new NCompress::NZlib::CEncoder; encoder = encoderZlibSpec; encoderZlibSpec->Create(); - RINOK(props.SetCoderProps(encoderZlibSpec->DeflateEncoderSpec, NULL)); + RINOK(props.SetCoderProps(encoderZlibSpec->DeflateEncoderSpec, NULL)) item.MakeZlib(); } - RINOK(item.WriteHeader(outStream)); + RINOK(item.WriteHeader(outStream)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress)); + RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, lps)) UInt64 inputProcessed; if (lzmaMode) { UInt64 curPos = 0; - RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &curPos)); - UInt64 packSize = curPos - kHeaderLzmaSize; + RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &curPos)) + const UInt64 packSize = curPos - kHeaderLzmaSize; if (packSize > (UInt32)0xFFFFFFFF) return E_INVALIDARG; item.MakeLzma((UInt32)packSize); - RINOK(outSeekStream->Seek(0, STREAM_SEEK_SET, NULL)); - item.WriteHeader(outStream); + RINOK(outSeekStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(item.WriteHeader(outStream)) inputProcessed = encoderLzmaSpec->GetInputProcessedSize(); } else @@ -517,14 +515,14 @@ return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK); } -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { *timeType = NFileTimeType::kUnix; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { if (numItems != 1) return E_INVALIDARG; @@ -533,13 +531,13 @@ UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) if (IntToBool(newProps)) { { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) if (prop.vt == VT_BOOL) { if (prop.boolVal != VARIANT_FALSE) @@ -555,7 +553,7 @@ UInt64 size; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; @@ -571,17 +569,17 @@ if (_stream) { - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _item.WriteHeader(outStream); return NCompress::CopyStream(_seqStream, outStream, NULL); } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { _lzmaMode = false; - RINOK(_props.SetProperties(names, values, numProps)); + RINOK(_props.SetProperties(names, values, numProps)) const AString &m = _props.MethodName; if (m.IsEqualTo_Ascii_NoCase("lzma")) { @@ -621,22 +619,16 @@ CByteBuffer Buf; }; -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) CObjectVector _tags; NSwfc::CItem _item; UInt64 _phySize; HRESULT OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback); HRESULT OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - - STDMETHOD(OpenSeq)(ISequentialInStream *stream); }; static const Byte kProps[] = @@ -649,7 +641,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -662,7 +654,7 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _tags.Size(); return S_OK; @@ -764,7 +756,7 @@ , "DefineFont4" }; -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; const CTag &tag = _tags[index]; @@ -791,7 +783,7 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { return OpenSeq2(stream, callback); } @@ -867,7 +859,7 @@ RINOK(_item.ReadHeader(stream)) if (!_item.IsSwf() || !_item.IsUncompressed()) return S_FALSE; - UInt32 uncompressedSize = _item.GetSize(); + const UInt32 uncompressedSize = _item.GetSize(); if (uncompressedSize > kFileSizeMax) return S_FALSE; @@ -880,7 +872,7 @@ { CBitReader br; br.stream = &s; - unsigned numBits = br.ReadBits(5); + const unsigned numBits = br.ReadBits(5); /* UInt32 xMin = */ br.ReadBits(numBits); /* UInt32 xMax = */ br.ReadBits(numBits); /* UInt32 yMin = */ br.ReadBits(numBits); @@ -893,14 +885,14 @@ UInt64 offsetPrev = 0; for (;;) { - UInt32 pair = Read16(s); - UInt32 type = pair >> 6; + const UInt32 pair = Read16(s); + const UInt32 type = pair >> 6; UInt32 length = pair & 0x3F; if (length == 0x3F) length = Read32(s); if (type == 0) break; - UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderBaseSize + length; + const UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderBaseSize + length; if (offset > uncompressedSize || _tags.Size() >= kNumTagsMax) return S_FALSE; CTag &tag = _tags.AddNew(); @@ -910,8 +902,8 @@ return S_FALSE; if (callback && offset >= offsetPrev + (1 << 20)) { - UInt64 numItems = _tags.Size(); - RINOK(callback->SetCompleted(&numItems, &offset)); + const UInt64 numItems = _tags.Size(); + RINOK(callback->SetCompleted(&numItems, &offset)) offsetPrev = offset; } } @@ -932,22 +924,22 @@ return res; } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { return OpenSeq2(stream, NULL); } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _tags.Size(); if (numItems == 0) @@ -956,7 +948,7 @@ UInt32 i; for (i = 0; i < numItems; i++) totalSize += _tags[allFilesMode ? i : indices[i]].Buf.Size(); - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) CLocalProgress *lps = new CLocalProgress; CMyComPtr progress = lps; @@ -967,24 +959,24 @@ for (i = 0; i < numItems; i++) { lps->InSize = lps->OutSize = totalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? + RINOK(lps->SetCur()) + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CByteBuffer &buf = _tags[index].Buf; totalSize += buf.Size(); CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); + RINOK(extractCallback->GetStream(index, &outStream, askMode)) if (!testMode && !outStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) if (outStream) - RINOK(WriteStream(outStream, buf, buf.Size())); + RINOK(WriteStream(outStream, buf, buf.Size())) outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } return S_OK; COM_TRY_END @@ -993,7 +985,7 @@ static const Byte k_Signature[] = { 'F', 'W', 'S' }; REGISTER_ARC_I( - "SWF", "swf", 0, 0xD7, + "SWF", "swf", NULL, 0xD7, k_Signature, 0, NArcInfoFlags::kKeepName, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.cpp 2022-05-18 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.cpp 2024-03-04 13:00:00.000000000 +0000 @@ -39,6 +39,9 @@ kpidCTime, kpidATime, kpidPosixAttrib, +#if 0 + kpidAttrib, +#endif kpidUser, kpidGroup, kpidUserId, @@ -67,7 +70,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -79,12 +82,13 @@ UInt32 flags = 0; if (!_isArc) flags |= kpv_ErrorFlags_IsNotArc; - else switch (_arc._error) + else switch ((int)_arc._error) { case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break; case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break; // case k_ErrorType_OK: break; // case k_ErrorType_Warning: break; + // case k_ErrorType_OK: default: break; } if (flags != 0) @@ -107,6 +111,7 @@ { case CP_OEMCP: name = "OEM"; break; case CP_UTF8: name = "UTF-8"; break; + default: break; } if (!name) { @@ -132,6 +137,7 @@ if (_arc._are_mtime) s.Add_OptSpaced("mtime"); if (_arc._are_atime) s.Add_OptSpaced("atime"); if (_arc._are_ctime) s.Add_OptSpaced("ctime"); + if (_arc._are_SCHILY_fflags) s.Add_OptSpaced("SCHILY.fflags"); if (_arc._is_PaxGlobal_Error) s.Add_OptSpaced("PAX_GLOBAL_ERROR"); s.Add_OptSpaced(_encodingCharacts.GetCharactsString()); prop = s; @@ -149,6 +155,7 @@ } break; } + default: break; } prop.Detach(value); return S_OK; @@ -206,10 +213,9 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { - UInt64 endPos = 0; + UInt64 endPos; { - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_AtBegin_GetSize(stream, endPos)) } _arc._phySize_Defined = true; @@ -224,7 +230,7 @@ for (;;) { _arc.NumFiles = _items.Size(); - RINOK(_arc.ReadItem(item)); + RINOK(_arc.ReadItem(item)) if (!_arc.filled) break; @@ -245,7 +251,7 @@ _items.Add(item); - RINOK(stream->Seek((Int64)item.Get_PackSize_Aligned(), STREAM_SEEK_CUR, &_arc._phySize)); + RINOK(stream->Seek((Int64)item.Get_PackSize_Aligned(), STREAM_SEEK_CUR, &_arc._phySize)) if (_arc._phySize > endPos) { _arc._error = k_ErrorType_UnexpectedEnd; @@ -290,10 +296,11 @@ _isArc = false; return S_FALSE; } - CMyComPtr openVolumeCallback; if (!callback) return S_FALSE; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, callback) if (!openVolumeCallback) return S_FALSE; NCOM::CPropVariant prop; @@ -310,20 +317,20 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN // for (int i = 0; i < 10; i++) // for debug { Close(); - RINOK(Open2(stream, openArchiveCallback)); + RINOK(Open2(stream, openArchiveCallback)) _stream = stream; } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _seqStream = stream; @@ -331,7 +338,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; @@ -346,7 +353,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = (_stream ? _items.Size() : (UInt32)(Int32)-1); return S_OK; @@ -354,8 +361,8 @@ CHandler::CHandler() { - copyCoderSpec = new NCompress::CCopyCoder(); - copyCoder = copyCoderSpec; + // copyCoder = new NCompress::CCopyCoder(); + // copyCoder = copyCoder; _openCodePage = CP_UTF8; Init(); } @@ -367,9 +374,9 @@ if (_latestIsRead) { const UInt64 packSize = _latestItem.Get_PackSize_Aligned(); - RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL)); - _arc._phySize += copyCoderSpec->TotalSize; - if (copyCoderSpec->TotalSize != packSize) + RINOK(copyCoder.Interface()->Code(_seqStream, NULL, &packSize, &packSize, NULL)) + _arc._phySize += copyCoder->TotalSize; + if (copyCoder->TotalSize != packSize) { _arc._error = k_ErrorType_UnexpectedEnd; return S_FALSE; @@ -381,7 +388,7 @@ { _arc.SeqStream = _seqStream; _arc.InStream = NULL; - RINOK(_arc.ReadItem(_latestItem)); + RINOK(_arc.ReadItem(_latestItem)) if (!_arc.filled) { _arc._phySize_Defined = true; @@ -407,6 +414,7 @@ } +// CPaxTime is defined (NumDigits >= 0) static void PaxTimeToProp(const CPaxTime &pt, NWindows::NCOM::CPropVariant &prop) { UInt64 v; @@ -418,31 +426,21 @@ ft.dwLowDateTime = (DWORD)v; ft.dwHighDateTime = (DWORD)(v >> 32); prop.SetAsTimeFrom_FT_Prec_Ns100(ft, - k_PropVar_TimePrec_Base + pt.NumDigits, pt.Ns % 100); + k_PropVar_TimePrec_Base + (unsigned)pt.NumDigits, pt.Ns % 100); } -#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10)))) - -static void AddByteToHex2(unsigned val, AString &s) -{ - unsigned t; - t = val >> 4; - s += ValToHex(t); - t = val & 0xF; - s += ValToHex(t); -} - static void AddSpecCharToString(const char c, AString &s) { if ((Byte)c <= 0x20 || (Byte)c > 127) { - s += '['; - AddByteToHex2((Byte)(c), s); - s += ']'; + s.Add_Char('['); + s.Add_Char(GET_HEX_CHAR_LOWER((Byte)c >> 4)); + s.Add_Char(GET_HEX_CHAR_LOWER(c & 15)); + s.Add_Char(']'); } else - s += c; + s.Add_Char(c); } static void AddSpecUInt64(AString &s, const char *name, UInt64 v) @@ -452,7 +450,7 @@ s.Add_OptSpaced(name); if (v > 1) { - s += ':'; + s.Add_Colon(); s.Add_UInt64(v); } } @@ -464,12 +462,37 @@ { s.Add_OptSpaced(name); if (b2) - s += '*'; + s.Add_Char('*'); } } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +#if 0 +static bool Parse_Attrib_from_SCHILY_fflags(const AString &s, UInt32 &attribRes) +{ + UInt32 attrib = 0; + attribRes = attrib; + unsigned pos = 0; + while (pos < s.Len()) + { + int pos2 = s.Find(',', pos); + if (pos2 < 0) + pos2 = (int)s.Len(); + const AString str = s.Mid(pos, (unsigned)pos2 - pos); + if (str.IsEqualTo("hidden")) attrib |= FILE_ATTRIBUTE_HIDDEN; + else if (str.IsEqualTo("rdonly")) attrib |= FILE_ATTRIBUTE_READONLY; + else if (str.IsEqualTo("system")) attrib |= FILE_ATTRIBUTE_SYSTEM; + else + return false; + pos = (unsigned)pos2 + 1; + } + attribRes = attrib; + return true; +} +#endif + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -483,7 +506,7 @@ return E_INVALIDARG; else { - RINOK(SkipTo(index)); + RINOK(SkipTo(index)) item = &_latestItem; } } @@ -534,7 +557,30 @@ PaxTimeToProp(item->PaxTimes.CTime, prop); break; case kpidPosixAttrib: prop = item->Get_Combined_Mode(); break; - + + // kpidAttrib has priority over kpidPosixAttrib in 7-Zip. + // but if we want kpidPosixAttrib priority for TAR, we disable kpidAttrib. +#if 0 + case kpidAttrib: + { + if (!item->SCHILY_fflags.IsEmpty()) + { + UInt32 attrib = 0; + if (Parse_Attrib_from_SCHILY_fflags(item->SCHILY_fflags, attrib)) + { + if (attrib != 0) + { + if (item->IsDir()) + attrib |= FILE_ATTRIBUTE_DIRECTORY; + attrib |= ((UInt32)item->Get_Combined_Mode() << 16) | 0x8000; // FILE_ATTRIBUTE_UNIX_EXTENSION; + prop = attrib; + } + } + } + break; + } +#endif + case kpidUser: if (!item->User.IsEmpty()) TarStringToUnicode(item->User, prop); @@ -633,7 +679,11 @@ s.Add_OptSpaced("pax_linkpath"); if (item->pax_size_WasUsed) s.Add_OptSpaced("pax_size"); - + if (!item->SCHILY_fflags.IsEmpty()) + { + s.Add_OptSpaced("SCHILY.fflags="); + s += item->SCHILY_fflags; + } if (item->IsThereWarning()) s.Add_OptSpaced("WARNING"); if (item->HeaderError) @@ -658,6 +708,7 @@ } // case kpidHeadersSize: prop = item->HeaderSize; break; // for debug // case kpidOffset: prop = item->HeaderPos; break; // for debug + default: break; } prop.Detach(value); return S_OK; @@ -665,8 +716,8 @@ } -HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN ISequentialInStream *stream = _seqStream; @@ -683,52 +734,50 @@ UInt32 i; for (i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Get_UnpackSize(); - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 totalPackSize; totalSize = totalPackSize = 0; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(stream); + CMyComPtr2_Create outStreamSpec; - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(stream); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems || seqMode; i++) + for (i = 0; ; i++) { lps->InSize = totalPackSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; + RINOK(lps->SetCur()) + if (i >= numItems && !seqMode) + break; const UInt32 index = allFilesMode ? i : indices[i]; const CItemEx *item; if (seqMode) { - HRESULT res = SkipTo(index); + const HRESULT res = SkipTo(index); if (res == E_INVALIDARG) break; - RINOK(res); + RINOK(res) item = &_latestItem; } else item = &_items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) const UInt64 unpackSize = item->Get_UnpackSize(); totalSize += unpackSize; totalPackSize += item->Get_PackSize_Aligned(); if (item->IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + // realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } bool skipMode = false; @@ -737,12 +786,13 @@ if (!seqMode) { /* - // probably we must show extracting info it callback handler instead - if (item->IsHardLink() || - item->IsSymLink()) + // GetStream() creates link. + // so we can show extracting info in GetStream() instead + if (item->Is_HardLink() || + item->Is_SymLink()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } */ continue; @@ -750,7 +800,7 @@ skipMode = true; askMode = NExtract::NAskMode::kSkip; } - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) outStreamSpec->SetStream(realOutStream); realOutStream.Release(); @@ -770,16 +820,16 @@ { if (item->Is_SymLink()) { - RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len())); + RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len())) } else { if (!seqMode) { - RINOK(_stream->Seek((Int64)item->Get_DataPos(), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, item->Get_DataPos())) } - streamSpec->Init(item->Get_PackSize_Aligned()); - RINOK(copyCoder->Code(inStream2, outStream, NULL, NULL, progress)); + inStream->Init(item->Get_PackSize_Aligned()); + RINOK(copyCoder.Interface()->Code(inStream2, outStreamSpec, NULL, NULL, lps)) } if (outStreamSpec->GetRem() != 0) opRes = NExtract::NOperationResult::kDataError; @@ -790,16 +840,16 @@ _curIndex++; } outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -class CSparseStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CSparseStream +) UInt64 _phyPos; UInt64 _virtPos; bool _needStartSeek; @@ -810,10 +860,6 @@ unsigned ItemIndex; CRecordVector PhyOffsets; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - void Init() { _virtPos = 0; @@ -823,7 +869,7 @@ }; -STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -867,7 +913,7 @@ UInt64 phyPos = PhyOffsets[left] + relat; if (_needStartSeek || _phyPos != phyPos) { - RINOK(Handler->_stream->Seek((Int64)(item.Get_DataPos() + phyPos), STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(Handler->_stream, (item.Get_DataPos() + phyPos))) _needStartSeek = false; _phyPos = phyPos; } @@ -894,7 +940,7 @@ return res; } -STDMETHODIMP CSparseStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CSparseStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -911,7 +957,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN @@ -961,7 +1007,7 @@ } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { Init(); @@ -978,12 +1024,12 @@ { // some clients write 'x' property. So we support it UInt32 level = 0; - RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)); + RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)) } else if (name.IsEqualTo("cp")) { UInt32 cp = CP_OEMCP; - RINOK(ParsePropToUInt32(L"", prop, cp)); + RINOK(ParsePropToUInt32(L"", prop, cp)) _forceCodePage = true; _curCodePage = _specifiedCodePage = cp; } @@ -1036,7 +1082,7 @@ } */ bool processed = false; - RINOK(_handlerTimeOptions.Parse(name, prop, processed)); + RINOK(_handlerTimeOptions.Parse(name, prop, processed)) if (processed) continue; return E_INVALIDARG; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.h 2022-03-22 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandler.h 2023-12-19 09:00:00.000000000 +0000 @@ -1,12 +1,10 @@ // TarHandler.h -#ifndef __TAR_HANDLER_H -#define __TAR_HANDLER_H +#ifndef ZIP7_INC_TAR_HANDLER_H +#define ZIP7_INC_TAR_HANDLER_H #include "../../../Common/MyCom.h" -#include "../../../Windows/PropVariant.h" - #include "../../Compress/CopyCoder.h" #include "../Common/HandlerOut.h" @@ -16,14 +14,12 @@ namespace NArchive { namespace NTar { -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IInArchiveGetStream, - public ISetProperties, - public IOutArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_4( + IArchiveOpenSeq + , IInArchiveGetStream + , ISetProperties + , IOutArchive +) public: CObjectVector _items; CMyComPtr _stream; @@ -46,27 +42,12 @@ CArchive _arc; - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr copyCoder; + CMyComPtr2_Create copyCoder; HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); HRESULT SkipTo(UInt32 index); void TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant &prop, bool toOs = false) const; public: - MY_UNKNOWN_IMP5( - IInArchive, - IArchiveOpenSeq, - IInArchiveGetStream, - ISetProperties, - IOutArchive - ) - - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - void Init(); CHandler(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandlerOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandlerOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHandlerOut.cpp 2022-03-27 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHandlerOut.cpp 2023-11-29 11:00:00.000000000 +0000 @@ -20,7 +20,7 @@ namespace NArchive { namespace NTar { -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) { UInt32 t = NFileTimeType::kUnix; const UInt32 prec = _handlerTimeOptions.Prec; @@ -55,7 +55,7 @@ UINT codePage, unsigned utfFlags, bool convertSlash) { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propId, &prop)); + RINOK(callback->GetProperty(index, propId, &prop)) if (prop.vt == VT_BSTR) { @@ -94,7 +94,7 @@ { pt.Clear(); NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, pid, &prop)); + RINOK(callback->GetProperty(i, pid, &prop)) return Prop_To_PaxTime(prop, pt); } @@ -125,7 +125,7 @@ { defined = false; NWindows::NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, pid, &prop)); + RINOK(callback->GetProperty(i, pid, &prop)) if (prop.vt == VT_EMPTY) return S_OK; if (prop.vt == VT_UI4) @@ -147,7 +147,7 @@ bool isSet = false; { NWindows::NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, pidId, &prop)); + RINOK(callback->GetProperty(i, pidId, &prop)) if (prop.vt == VT_UI4) { isSet = true; @@ -160,7 +160,7 @@ } { NWindows::NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, pidName, &prop)); + RINOK(callback->GetProperty(i, pidName, &prop)) if (prop.vt == VT_BSTR) { const UString s = prop.bstrVal; @@ -181,8 +181,8 @@ -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) { COM_TRY_BEGIN @@ -196,8 +196,8 @@ /* // for debug only: unsigned utfFlags = 0; - utfFlags |= UTF_FLAG__TO_UTF8__EXTRACT_BMP_ESCAPE; - utfFlags |= UTF_FLAG__TO_UTF8__SURROGATE_ERROR; + utfFlags |= Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE; + utfFlags |= Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR; */ for (UInt32 i = 0; i < numItems; i++) @@ -210,7 +210,7 @@ if (!callback) return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) ui.NewProps = IntToBool(newProps); ui.NewData = IntToBool(newData); @@ -221,7 +221,7 @@ { { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) if (prop.vt == VT_EMPTY) ui.IsDir = false; else if (prop.vt != VT_BOOL) @@ -232,7 +232,7 @@ { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)); + RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)) if (prop.vt == VT_EMPTY) ui.Mode = MY_LIN_S_IRWXO @@ -255,25 +255,25 @@ if (_handlerTimeOptions.Write_CTime.Val) RINOK(GetTime(i, kpidCTime, callback, ui.PaxTimes.CTime)) - RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, utfFlags, true)); + RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, utfFlags, true)) if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') - ui.Name += '/'; - // ui.Name += '/'; // for debug + ui.Name.Add_Slash(); + // ui.Name.Add_Slash(); // for debug if (_posixMode) { - RINOK(GetDevice(callback, i, kpidDeviceMajor, ui.DeviceMajor, ui.DeviceMajor_Defined)); - RINOK(GetDevice(callback, i, kpidDeviceMinor, ui.DeviceMinor, ui.DeviceMinor_Defined)); + RINOK(GetDevice(callback, i, kpidDeviceMajor, ui.DeviceMajor, ui.DeviceMajor_Defined)) + RINOK(GetDevice(callback, i, kpidDeviceMinor, ui.DeviceMinor, ui.DeviceMinor_Defined)) } - RINOK(GetUser(callback, i, kpidUser, kpidUserId, ui.User, ui.UID, codePage, utfFlags)); - RINOK(GetUser(callback, i, kpidGroup, kpidGroupId, ui.Group, ui.GID, codePage, utfFlags)); + RINOK(GetUser(callback, i, kpidUser, kpidUserId, ui.User, ui.UID, codePage, utfFlags)) + RINOK(GetUser(callback, i, kpidGroup, kpidGroupId, ui.Group, ui.GID, codePage, utfFlags)) } if (IntToBool(newData)) { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; ui.Size = prop.uhVal.QuadPart; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.cpp 2022-03-21 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -20,7 +20,7 @@ // 7-Zip used kUsTar_00 before 21.07: const char k_Posix_ustar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ; // GNU TAR uses such header: - const char k_GNU_ustar__[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ; + const char k_GNU_ustar[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ; } /* diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.h 2022-03-21 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/TarHeader.h -#ifndef __ARCHIVE_TAR_HEADER_H -#define __ARCHIVE_TAR_HEADER_H +#ifndef ZIP7_INC_ARCHIVE_TAR_HEADER_H +#define ZIP7_INC_ARCHIVE_TAR_HEADER_H #include "../../../Common/MyTypes.h" @@ -81,7 +81,7 @@ // extern const char * const kGNUTar; // = "GNUtar "; // 7 chars and a null // extern const char * const kEmpty; // = "\0\0\0\0\0\0\0\0" extern const char k_Posix_ustar_00[8]; - extern const char k_GNU_ustar__[8]; + extern const char k_GNU_ustar[8]; } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarIn.cpp 2022-03-02 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.cpp 2024-03-04 13:00:00.000000000 +0000 @@ -14,8 +14,8 @@ #define NUM_UNROLL_BYTES (8 * 4) -MY_NO_INLINE static bool IsBufNonZero(const void *data, size_t size); -MY_NO_INLINE static bool IsBufNonZero(const void *data, size_t size) +Z7_NO_INLINE static bool IsBufNonZero(const void *data, size_t size); +Z7_NO_INLINE static bool IsBufNonZero(const void *data, size_t size) { const Byte *p = (const Byte *)data; @@ -159,7 +159,7 @@ UInt32 mode; // we allow empty Mode value for LongName prefix items - CHECK(OctalToNumber32(p, mode, true)); p += 8; + CHECK(OctalToNumber32(p, mode, true)) p += 8; // if (!OctalToNumber32(p, item.UID)) item.UID = 0; p += 8; @@ -170,9 +170,9 @@ Int64 time; UInt32 checkSum; bool isBin; - CHECK(ParseSize(p, packSize, isBin)); p += 12; - CHECK(ParseInt64_MTime(p, time, isBin)); p += 12; - CHECK(OctalToNumber32(p, checkSum)); + CHECK(ParseSize(p, packSize, isBin)) p += 12; + CHECK(ParseInt64_MTime(p, time, isBin)) p += 12; + CHECK(OctalToNumber32(p, checkSum)) return k_IsArc_Res_YES; } @@ -188,7 +188,7 @@ for (;;) { size_t processedSize = NFileHeader::kRecordSize; - RINOK(ReadStream(SeqStream, buf, &processedSize)); + RINOK(ReadStream(SeqStream, buf, &processedSize)) if (processedSize == 0) { if (!thereAreEmptyRecords) @@ -220,7 +220,7 @@ thereAreEmptyRecords = true; if (OpenCallback) { - RINOK(Progress(item, 0)); + RINOK(Progress(item, 0)) } } if (thereAreEmptyRecords) @@ -243,19 +243,19 @@ */ // we allow empty Mode value for LongName prefix items - RIF(OctalToNumber32(p, item.Mode, true)); p += 8; + RIF(OctalToNumber32(p, item.Mode, true)) p += 8; if (!OctalToNumber32(p, item.UID)) { item.UID = 0; } p += 8; if (!OctalToNumber32(p, item.GID)) { item.GID = 0; } p += 8; - RIF(ParseSize(p, item.PackSize, item.PackSize_IsBin)); + RIF(ParseSize(p, item.PackSize, item.PackSize_IsBin)) item.Size = item.PackSize; item.Size_IsBin = item.PackSize_IsBin; p += 12; - RIF(ParseInt64_MTime(p, item.MTime, item.MTime_IsBin)); p += 12; + RIF(ParseInt64_MTime(p, item.MTime, item.MTime_IsBin)) p += 12; UInt32 checkSum; - RIF(OctalToNumber32(p, checkSum)); + RIF(OctalToNumber32(p, checkSum)) memset(p, ' ', 8); p += 8; item.LinkFlag = *p++; @@ -273,8 +273,8 @@ ReadString(p, NFileHeader::kUserNameSize, item.User); p += NFileHeader::kUserNameSize; ReadString(p, NFileHeader::kGroupNameSize, item.Group); p += NFileHeader::kGroupNameSize; - item.DeviceMajor_Defined = (p[0] != 0); if (item.DeviceMajor_Defined) { RIF(OctalToNumber32(p, item.DeviceMajor)); } p += 8; - item.DeviceMinor_Defined = (p[0] != 0); if (item.DeviceMinor_Defined) { RIF(OctalToNumber32(p, item.DeviceMinor)); } p += 8; + item.DeviceMajor_Defined = (p[0] != 0); if (item.DeviceMajor_Defined) { RIF(OctalToNumber32(p, item.DeviceMajor)) } p += 8; + item.DeviceMinor_Defined = (p[0] != 0); if (item.DeviceMinor_Defined) { RIF(OctalToNumber32(p, item.DeviceMinor)) } p += 8; if (p[0] != 0 && item.IsMagic_ustar_5chars() @@ -282,7 +282,7 @@ { item.Prefix_WasUsed = true; ReadString(p, NFileHeader::kPrefixSize, item.Name); - item.Name += '/'; + item.Name.Add_Slash(); unsigned i; for (i = 0; i < NFileHeader::kNameSize; i++) if (buf[i] == 0) @@ -338,7 +338,7 @@ Byte isExtended = (Byte)buf[482]; if (isExtended != 0 && isExtended != 1) return S_OK; - RIF(ParseSize(buf + 483, item.Size, item.Size_IsBin)); + RIF(ParseSize(buf + 483, item.Size, item.Size_IsBin)) UInt64 min = 0; for (unsigned i = 0; i < 4; i++) { @@ -350,8 +350,8 @@ break; } CSparseBlock sb; - RIF(ParseSize(p, sb.Offset)); - RIF(ParseSize(p + 12, sb.Size)); + RIF(ParseSize(p, sb.Offset)) + RIF(ParseSize(p + 12, sb.Size)) item.SparseBlocks.Add(sb); if (sb.Offset < min || sb.Offset > item.Size) return S_OK; @@ -367,7 +367,7 @@ while (isExtended != 0) { size_t processedSize = NFileHeader::kRecordSize; - RINOK(ReadStream(SeqStream, buf, &processedSize)); + RINOK(ReadStream(SeqStream, buf, &processedSize)) if (processedSize != NFileHeader::kRecordSize) { error = k_ErrorType_UnexpectedEnd; @@ -378,7 +378,7 @@ if (OpenCallback) { - RINOK(Progress(item, 0)); + RINOK(Progress(item, 0)) } isExtended = (Byte)buf[21 * 24]; @@ -394,8 +394,8 @@ break; } CSparseBlock sb; - RIF(ParseSize(p, sb.Offset)); - RIF(ParseSize(p + 12, sb.Size)); + RIF(ParseSize(p, sb.Offset)) + RIF(ParseSize(p + 12, sb.Size)) item.SparseBlocks.Add(sb); if (sb.Offset < min || sb.Offset > item.Size) return S_OK; @@ -459,7 +459,7 @@ error = k_ErrorType_UnexpectedEnd; return res; } - RINOK(res); + RINOK(res) packSize -= size; @@ -492,7 +492,7 @@ if (InStream) { - RINOK(InStream->Seek((Int64)packSize, STREAM_SEEK_CUR, NULL)); + RINOK(InStream->Seek((Int64)packSize, STREAM_SEEK_CUR, NULL)) return S_OK; } const unsigned kBufSize = 1 << 15; @@ -502,7 +502,7 @@ { if (OpenCallback) { - RINOK(Progress(item, pos)); + RINOK(Progress(item, pos)) } unsigned size = kBufSize; @@ -541,6 +541,7 @@ bool Link_Defined; bool User_Defined; bool Group_Defined; + bool SCHILY_fflags_Defined; UInt64 Size; UInt32 UID; @@ -551,6 +552,7 @@ AString User; AString Group; AString UnknownLines; + AString SCHILY_fflags; bool ParseID(const AString &val, bool &defined, UInt32 &res) { @@ -590,8 +592,8 @@ if (sec >= ((UInt64)1 << 63)) return false; if (isNegative) - sec = -(Int64)sec; - pt.Sec = sec; + sec = (UInt64)-(Int64)sec; + pt.Sec = (Int64)sec; } if (*end == 0) { @@ -617,10 +619,10 @@ if (i < kNsDigits) { ns *= 10; - ns += c - '0'; + ns += (unsigned)(c - '0'); } } - pt.NumDigits = (i < kNsDigits ? i : kNsDigits); + pt.NumDigits = (int)(i < kNsDigits ? i : kNsDigits); while (i < kNsDigits) { ns *= 10; @@ -648,6 +650,7 @@ Link_Defined = false; User_Defined = false; Group_Defined = false; + SCHILY_fflags_Defined = false; // CPaxTimes::Clear(); @@ -690,7 +693,7 @@ return false; name.SetFrom(s + offset, i - offset); - val.SetFrom(s + i + 1, size - 1 - (i + 1)); + val.SetFrom(s + i + 1, (unsigned)(size - 1 - (i + 1))); bool parsed = false; if (isFile) @@ -759,6 +762,14 @@ { parsed = ParsePaxTime(val, ATime, DoubleTagError); } else if (name.IsEqualTo("ctime")) { parsed = ParsePaxTime(val, CTime, DoubleTagError); } + else if (name.IsEqualTo("SCHILY.fflags")) + { + if (SCHILY_fflags_Defined) + DoubleTagError = true; + SCHILY_fflags = val; + SCHILY_fflags_Defined = true; + parsed = true; + } else isDetectedName = false; if (isDetectedName && !parsed) @@ -812,6 +823,7 @@ item.pax_size_WasUsed = false; item.PaxExtra.Clear(); + item.SCHILY_fflags.Empty(); item.EncodingCharacts.Clear(); @@ -822,29 +834,34 @@ PaxBuf.Init(); PaxBuf_global.Init(); - for (unsigned recordIndex = 0;; recordIndex++) + UInt64 numExtraRecords = 0; + + for (;;) { if (OpenCallback) { - RINOK(Progress(item, 0)); + RINOK(Progress(item, 0)) } - RINOK(GetNextItemReal(item)); + RINOK(GetNextItemReal(item)) // NumRecords++; if (!filled) { if (error == k_ErrorType_OK) - if (item.LongName_WasUsed || - item.LongLink_WasUsed || - item.Num_Pax_Records != 0) + if (numExtraRecords != 0 + || item.LongName_WasUsed + || item.LongLink_WasUsed + || item.Num_Pax_Records != 0) error = k_ErrorType_Corrupted; + return S_OK; } - if (error != k_ErrorType_OK) return S_OK; - + + numExtraRecords++; + const char lf = item.LinkFlag; if (lf == NFileHeader::NLinkFlag::kGnu_LongName || lf == NFileHeader::NLinkFlag::kGnu_LongLink) @@ -874,7 +891,7 @@ */ const unsigned kLongNameSizeMax = (unsigned)1 << 14; - RINOK(ReadDataToBuffer(item, *tb, kLongNameSizeMax)); + RINOK(ReadDataToBuffer(item, *tb, kLongNameSizeMax)) if (error != k_ErrorType_OK) return S_OK; @@ -921,7 +938,7 @@ CTempBuffer *tb = (lf == NFileHeader::NLinkFlag::kGlobal ? &PaxBuf_global : &PaxBuf); - RINOK(ReadDataToBuffer(item, *tb, kParsingPaxSizeMax)); + RINOK(ReadDataToBuffer(item, *tb, kParsingPaxSizeMax)) if (error != k_ErrorType_OK) return S_OK; @@ -951,12 +968,19 @@ } else _is_PaxGlobal_Error = true; - if (isStartHeader) + + if (isStartHeader + && item.Num_Pax_Records == 1 + && numExtraRecords == 1) { // we skip global pax header info after parsing item.HeaderPos += item.HeaderSize; item.HeaderSize = 0; + item.Num_Pax_Records = 0; + numExtraRecords = 0; } + else + _is_PaxGlobal_Error = true; } continue; } @@ -1020,6 +1044,11 @@ item.Group = paxInfo.Group; // item.pax_gname_WasUsed = true; } + if (paxInfo.SCHILY_fflags_Defined) + { + item.SCHILY_fflags = paxInfo.SCHILY_fflags; + // item.SCHILY_fflags_WasUsed = true; + } if (paxInfo.UID_Defined) { item.UID = (UInt32)paxInfo.UID; @@ -1071,7 +1100,7 @@ if (error != k_ErrorType_OK) _error = error; - RINOK(res); + RINOK(res) if (filled) { @@ -1086,6 +1115,7 @@ if (item.PaxTimes.MTime.IsDefined()) _are_mtime = true; if (item.PaxTimes.ATime.IsDefined()) _are_atime = true; if (item.PaxTimes.CTime.IsDefined()) _are_ctime = true; + if (!item.SCHILY_fflags.IsEmpty()) _are_SCHILY_fflags = true; if (item.pax_path_WasUsed) _are_pax_path = true; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarIn.h 2022-02-28 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarIn.h 2024-03-04 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // TarIn.h -#ifndef __ARCHIVE_TAR_IN_H -#define __ARCHIVE_TAR_IN_H +#ifndef ZIP7_INC_ARCHIVE_TAR_IN_H +#define ZIP7_INC_ARCHIVE_TAR_IN_H #include "../IArchive.h" @@ -61,6 +61,7 @@ bool _are_LongName; bool _are_LongLink; bool _pathPrefix_WasUsed; + bool _are_SCHILY_fflags; // bool _isSparse; // temp internal vars for ReadItem(): @@ -110,6 +111,7 @@ _are_LongName = false; _are_LongLink = false; _pathPrefix_WasUsed = false; + _are_SCHILY_fflags = false; // _isSparse = false; _is_Warning = false; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarItem.h 2022-03-24 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarItem.h 2024-03-04 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // TarItem.h -#ifndef __ARCHIVE_TAR_ITEM_H -#define __ARCHIVE_TAR_ITEM_H +#ifndef ZIP7_INC_ARCHIVE_TAR_ITEM_H +#define ZIP7_INC_ARCHIVE_TAR_ITEM_H #include "../../../Common/MyLinux.h" #include "../../../Common/UTFConvert.h" @@ -143,7 +143,7 @@ { memcpy(Magic, posixMode ? NFileHeader::NMagic::k_Posix_ustar_00 : - NFileHeader::NMagic::k_GNU_ustar__, + NFileHeader::NMagic::k_GNU_ustar, 8); } @@ -161,6 +161,7 @@ case NFileHeader::NLinkFlag::kPax_2: case NFileHeader::NLinkFlag::kGlobal: return true; + default: break; } return false; } @@ -172,7 +173,7 @@ void Set_LinkFlag_for_File(UInt32 mode) { - Byte lf = NFileHeader::NLinkFlag::kNormal; + char lf = NFileHeader::NLinkFlag::kNormal; if (MY_LIN_S_ISCHR(mode)) lf = NFileHeader::NLinkFlag::kCharacter; else if (MY_LIN_S_ISBLK(mode)) lf = NFileHeader::NLinkFlag::kBlock; else if (MY_LIN_S_ISFIFO(mode)) lf = NFileHeader::NLinkFlag::kFIFO; @@ -195,6 +196,7 @@ case NFileHeader::NLinkFlag::kCharacter: return MY_LIN_S_IFCHR; case NFileHeader::NLinkFlag::kFIFO: return MY_LIN_S_IFIFO; // case return MY_LIN_S_IFSOCK; + default: break; } if (IsDir()) @@ -218,6 +220,7 @@ // we also do it return Name.Back() == '/'; // return NItemName::HasTailSlash(Name, CP_OEMCP); + default: break; } return false; } @@ -225,7 +228,7 @@ bool IsMagic_ustar_5chars() const { for (unsigned i = 0; i < 5; i++) - if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar__[i]) + if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar[i]) return false; return true; } @@ -241,7 +244,7 @@ bool IsMagic_GNU() const { for (unsigned i = 0; i < 8; i++) - if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar__[i]) + if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar[i]) return false; return true; } @@ -347,6 +350,7 @@ UInt64 Num_Pax_Records; CPaxExtra PaxExtra; + AString SCHILY_fflags; CEncodingCharacts EncodingCharacts; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarOut.cpp 2022-03-30 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.cpp 2023-12-11 13:00:00.000000000 +0000 @@ -60,7 +60,7 @@ } } -static void WriteOctal_12_Signed(char *s, Int64 val) +static void WriteOctal_12_Signed(char *s, const Int64 val) { if (val >= 0) { @@ -68,10 +68,10 @@ return; } s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF; - WriteBin_64bit(s + 4, val); + WriteBin_64bit(s + 4, (UInt64)val); } -static void CopyString(char *dest, const AString &src, unsigned maxSize) +static void CopyString(char *dest, const AString &src, const unsigned maxSize) { unsigned len = src.Len(); if (len == 0) @@ -119,11 +119,11 @@ COPY_STRING_CHECK (cur, (!isPax && !Glob_Name.IsEmpty()) ? Glob_Name : item.Name, - kNameSize); + kNameSize) - WRITE_OCTAL_8_CHECK (cur, item.Mode); cur += 8; // & k_7_oct_digits_Val_Max - WRITE_OCTAL_8_CHECK (cur, item.UID); cur += 8; - WRITE_OCTAL_8_CHECK (cur, item.GID); cur += 8; + WRITE_OCTAL_8_CHECK (cur, item.Mode) cur += 8; // & k_7_oct_digits_Val_Max + WRITE_OCTAL_8_CHECK (cur, item.UID) cur += 8; + WRITE_OCTAL_8_CHECK (cur, item.GID) cur += 8; WriteOctal_12 (cur, /* zero_PackSize ? 0 : */ item.PackSize); cur += 12; WriteOctal_12_Signed (cur, /* zero_MTime ? 0 : */ item.MTime); cur += 12; @@ -135,13 +135,13 @@ *cur++ = item.LinkFlag; - COPY_STRING_CHECK (cur, item.LinkName, kNameSize); + COPY_STRING_CHECK (cur, item.LinkName, kNameSize) memcpy(cur, item.Magic, 8); cur += 8; - COPY_STRING_CHECK (cur, item.User, kUserNameSize); - COPY_STRING_CHECK (cur, item.Group, kGroupNameSize); + COPY_STRING_CHECK (cur, item.User, kUserNameSize) + COPY_STRING_CHECK (cur, item.Group, kGroupNameSize) const bool needDevice = (IsPosixMode && !isPax); @@ -159,7 +159,7 @@ if (!isPax && !Prefix.IsEmpty()) { - COPY_STRING_CHECK (cur, Prefix, kPrefixSize); + COPY_STRING_CHECK (cur, Prefix, kPrefixSize) } if (item.Is_Sparse()) @@ -194,7 +194,7 @@ record[148 + 7] = ' '; // we need it, if we use binary init } - RINOK(Write_Data(record, kRecordSize)); + RINOK(Write_Data(record, kRecordSize)) if (item.Is_Sparse()) { @@ -209,7 +209,7 @@ WriteOctal_12(p + 12, sb.Size); } record[21 * 24] = (char)(i < item.SparseBlocks.Size() ? 1 : 0); - RINOK(Write_Data(record, kRecordSize)); + RINOK(Write_Data(record, kRecordSize)) } } @@ -232,16 +232,16 @@ s += n; s.Add_Space(); s += name; - s += '='; + s.Add_Char('='); s += val; s.Add_LF(); } - +// pt is defined : (pt.NumDigits >= 0) static void AddPaxTime(AString &s, const char *name, const CPaxTime &pt, const CTimeOptions &options) { - unsigned numDigits = pt.NumDigits; + unsigned numDigits = (unsigned)pt.NumDigits; if (numDigits > options.NumDigitsMax) numDigits = options.NumDigitsMax; @@ -265,14 +265,14 @@ if (pt.Sec < 0) { sec = -sec; - v += '-'; + v.Add_Minus(); if (ns != 0) { ns = 1000*1000*1000 - ns; sec--; } } - v.Add_UInt64(sec); + v.Add_UInt64((UInt64)sec); } if (needNs) @@ -291,7 +291,7 @@ if (!d.IsEmpty()) { - v += '.'; + v.Add_Dot(); v += d; // v += "1234567009999"; // for debug // for (int y = 0; y < 1000; y++) v += '8'; // for debug @@ -467,8 +467,8 @@ // mi.LinkFlag = 'Z'; // for debug mi.PackSize = paxSize; // for (unsigned y = 0; y < 1; y++) { // for debug - RINOK(WriteHeaderReal(mi, true)); // isPax - RINOK(Write_Data_And_Residual(s, paxSize)); + RINOK(WriteHeaderReal(mi, true)) // isPax + RINOK(Write_Data_And_Residual(s, paxSize)) // } // for debug /* we can send (zero_MTime) for compatibility with gnu tar output. @@ -538,8 +538,8 @@ const unsigned nameStreamSize = name->Len() + 1; mi.PackSize = nameStreamSize; // for (unsigned y = 0; y < 3; y++) { // for debug - RINOK(WriteHeaderReal(mi)); - RINOK(Write_Data_And_Residual(name->Ptr(), nameStreamSize)); + RINOK(WriteHeaderReal(mi)) + RINOK(Write_Data_And_Residual(name->Ptr(), nameStreamSize)) // } // for debug @@ -615,7 +615,7 @@ HRESULT COutArchive::Write_Data_And_Residual(const void *data, unsigned size) { - RINOK(Write_Data(data, size)); + RINOK(Write_Data(data, size)) return Write_AfterDataResidual(size); } @@ -636,7 +636,7 @@ for (unsigned i = 0; i < kNumFinishRecords; i++) { - RINOK(Write_Data(record, kRecordSize)); + RINOK(Write_Data(record, kRecordSize)) } return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarOut.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarOut.h 2022-02-22 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarOut.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/TarOut.h -#ifndef __ARCHIVE_TAR_OUT_H -#define __ARCHIVE_TAR_OUT_H +#ifndef ZIP7_INC_ARCHIVE_TAR_OUT_H +#define ZIP7_INC_ARCHIVE_TAR_OUT_H #include "../../../Common/MyCom.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarRegister.cpp 2022-05-04 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -12,7 +12,7 @@ static const Byte k_Signature[] = { 'u', 's', 't', 'a', 'r' }; REGISTER_ARC_IO( - "tar", "tar ova", 0, 0xEE, + "tar", "tar ova", NULL, 0xEE, k_Signature, NFileHeader::kUstarMagic_Offset, NArcInfoFlags::kStartOpen diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.cpp 2022-03-28 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.cpp 2024-02-19 13:00:00.000000000 +0000 @@ -8,6 +8,7 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" @@ -44,7 +45,7 @@ const unsigned prec = prop.wReserved1; if (prec >= k_PropVar_TimePrec_Base) { - pt.NumDigits = prec - k_PropVar_TimePrec_Base; + pt.NumDigits = (int)(prec - k_PropVar_TimePrec_Base); if (prop.wReserved2 < 100) ns += prop.wReserved2; } @@ -58,7 +59,7 @@ { pt.Clear(); NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(pid, &prop)); + RINOK(getProp->GetProperty(pid, &prop)) return Prop_To_PaxTime(prop, pt); } @@ -73,7 +74,7 @@ bool isSet = false; { NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(pidId, &prop)); + RINOK(getProp->GetProperty(pidId, &prop)) if (prop.vt == VT_UI4) { isSet = true; @@ -85,7 +86,7 @@ } { NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(pidName, &prop)); + RINOK(getProp->GetProperty(pidName, &prop)) if (prop.vt == VT_BSTR) { const UString s = prop.bstrVal; @@ -133,7 +134,7 @@ { defined = false; NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(pid, &prop)); + RINOK(getProp->GetProperty(pid, &prop)) if (prop.vt == VT_EMPTY) return S_OK; if (prop.vt == VT_UI4) @@ -158,8 +159,10 @@ outArchive.IsPosixMode = options.PosixMode; outArchive.TimeOptions = options.TimeOptions; - CMyComPtr outSeekStream; - outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream); + Z7_DECL_CMyComPtr_QI_FROM(IOutStream, outSeekStream, outStream) + Z7_DECL_CMyComPtr_QI_FROM(IStreamSetRestriction, setRestriction, outStream) + Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackFile, opCallback, outStream) + if (outSeekStream) { /* @@ -169,12 +172,10 @@ RINOK(outStream->Write(buf, sizeof(buf), NULL)); */ // we need real outArchive.Pos, if outSeekStream->SetSize() will be used. - RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &outArchive.Pos)); + RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &outArchive.Pos)) } - - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) UInt64 complexity = 0; @@ -183,23 +184,23 @@ { const CUpdateItem &ui = updateItems[i]; if (ui.NewData) + { + if (ui.Size == (UInt64)(Int64)-1) + break; complexity += ui.Size; + } else complexity += inputItems[(unsigned)ui.IndexInArc].Get_FullSize_Aligned(); } - RINOK(updateCallback->SetTotal(complexity)); + if (i == updateItems.Size()) + RINOK(updateCallback->SetTotal(complexity)) - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLimited(streamSpec); - streamSpec->SetStream(inStream); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStreamLimited; + inStreamLimited->SetStream(inStream); complexity = 0; @@ -208,10 +209,14 @@ for (i = 0;; i++) { lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) if (i == updateItems.Size()) + { + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) return outArchive.WriteFinishHeader(); + } const CUpdateItem &ui = updateItems[i]; CItem item; @@ -253,7 +258,7 @@ if (ui.NewData || ui.NewProps) { RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, - options.CodePage, options.UtfFlags, true)); + options.CodePage, options.UtfFlags, true)) if (!symLink.IsEmpty()) { item.LinkFlag = NFileHeader::NLinkFlag::kSymLink; @@ -266,9 +271,10 @@ item.SparseBlocks.Clear(); item.PackSize = ui.Size; item.Size = ui.Size; +#if 0 if (ui.Size == (UInt64)(Int64)-1) return E_INVALIDARG; - +#endif CMyComPtr fileInStream; bool needWrite = true; @@ -286,7 +292,7 @@ needWrite = false; else { - RINOK(res); + RINOK(res) if (!fileInStream) { @@ -295,9 +301,7 @@ } else { - CMyComPtr getProps; - CMyComPtr getProp; - fileInStream->QueryInterface(IID_IStreamGetProp, (void **)&getProp); + Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProp, getProp, fileInStream) if (getProp) { if (options.Write_MTime.Val) RINOK(GetTime(getProp, kpidMTime, item.PaxTimes.MTime)) @@ -312,23 +316,23 @@ */ bool defined = false; UInt32 val = 0; - RINOK(GetDevice(getProp, kpidDeviceMajor, val, defined)); + RINOK(GetDevice(getProp, kpidDeviceMajor, val, defined)) if (defined) { item.DeviceMajor = val; item.DeviceMajor_Defined = true; item.DeviceMinor = 0; item.DeviceMinor_Defined = false; - RINOK(GetDevice(getProp, kpidDeviceMinor, item.DeviceMinor, item.DeviceMinor_Defined)); + RINOK(GetDevice(getProp, kpidDeviceMinor, item.DeviceMinor, item.DeviceMinor_Defined)) } } - RINOK(GetUser(getProp, kpidUser, kpidUserId, item.User, item.UID, options.CodePage, options.UtfFlags)); - RINOK(GetUser(getProp, kpidGroup, kpidGroupId, item.Group, item.GID, options.CodePage, options.UtfFlags)); + RINOK(GetUser(getProp, kpidUser, kpidUserId, item.User, item.UID, options.CodePage, options.UtfFlags)) + RINOK(GetUser(getProp, kpidGroup, kpidGroupId, item.Group, item.GID, options.CodePage, options.UtfFlags)) { NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(kpidPosixAttrib, &prop)); + RINOK(getProp->GetProperty(kpidPosixAttrib, &prop)) if (prop.vt == VT_EMPTY) item.Mode = MY_LIN_S_IRWXO @@ -346,10 +350,11 @@ { NWindows::NCOM::CPropVariant prop; - RINOK(getProp->GetProperty(kpidSize, &prop)); + RINOK(getProp->GetProperty(kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; const UInt64 size = prop.uhVal.QuadPart; + // printf("\nTAR after GetProperty(kpidSize size = %8d\n", (unsigned)size); item.PackSize = size; item.Size = size; } @@ -361,7 +366,7 @@ } else { - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); + Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProps, getProps, fileInStream) if (getProps) { FILETIME mTime, aTime, cTime; @@ -386,7 +391,7 @@ // we must request kpidHardLink after updateCallback->GetStream() AString hardLink; RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, - options.CodePage, options.UtfFlags, true)); + options.CodePage, options.UtfFlags, true)) if (!hardLink.IsEmpty()) { item.LinkFlag = NFileHeader::NLinkFlag::kHardLink; @@ -406,13 +411,23 @@ if (needWrite) { + if (fileInStream) + // if (item.PackSize == (UInt64)(Int64)-1) + if (item.Size == (UInt64)(Int64)-1) + return E_INVALIDARG; + const UInt64 headerPos = outArchive.Pos; // item.PackSize = ((UInt64)1 << 33); // for debug - RINOK(outArchive.WriteHeader(item)); + + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(outArchive.Pos, (UInt64)(Int64)-1)) + + RINOK(outArchive.WriteHeader(item)) if (fileInStream) { for (unsigned numPasses = 0;; numPasses++) { + // printf("\nTAR numPasses = %d" " old size = %8d\n", numPasses, (unsigned)item.PackSize); /* we support 2 attempts to write header: pass-0: main pass: pass-1: additional pass, if size_of_file and size_of_header are changed */ @@ -424,12 +439,12 @@ } const UInt64 dataPos = outArchive.Pos; - RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress)); - outArchive.Pos += copyCoderSpec->TotalSize; - RINOK(outArchive.Write_AfterDataResidual(copyCoderSpec->TotalSize)); - + RINOK(copyCoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + outArchive.Pos += copyCoder->TotalSize; + RINOK(outArchive.Write_AfterDataResidual(copyCoder->TotalSize)) + // printf("\nTAR after Code old size = %8d copyCoder->TotalSize = %8d \n", (unsigned)item.PackSize, (unsigned)copyCoder->TotalSize); // if (numPasses >= 10) // for debug - if (copyCoderSpec->TotalSize == item.PackSize) + if (copyCoder->TotalSize == item.PackSize) break; if (opCallback) @@ -442,11 +457,11 @@ if (!outSeekStream) return E_FAIL; const UInt64 nextPos = outArchive.Pos; - RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL)); + RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL)) outArchive.Pos = headerPos; - item.PackSize = copyCoderSpec->TotalSize; + item.PackSize = copyCoder->TotalSize; - RINOK(outArchive.WriteHeader(item)); + RINOK(outArchive.WriteHeader(item)) // if (numPasses >= 10) // for debug if (outArchive.Pos == dataPos) @@ -454,7 +469,7 @@ const UInt64 alignedSize = nextPos - dataPos; if (alignedSize != 0) { - RINOK(outSeekStream->Seek(alignedSize, STREAM_SEEK_CUR, NULL)); + RINOK(outSeekStream->Seek((Int64)alignedSize, STREAM_SEEK_CUR, NULL)) outArchive.Pos += alignedSize; } break; @@ -462,12 +477,11 @@ // size of header was changed. // we remove data after header and try new attempt, if required - CMyComPtr fileSeekStream; - fileInStream->QueryInterface(IID_IInStream, (void **)&fileSeekStream); + Z7_DECL_CMyComPtr_QI_FROM(IInStream, fileSeekStream, fileInStream) if (!fileSeekStream) return E_FAIL; - RINOK(fileSeekStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(outSeekStream->SetSize(outArchive.Pos)); + RINOK(InStream_SeekToBegin(fileSeekStream)) + RINOK(outSeekStream->SetSize(outArchive.Pos)) if (item.PackSize == 0) break; } @@ -476,7 +490,7 @@ complexity += item.PackSize; fileInStream.Release(); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) } else { @@ -518,7 +532,7 @@ item.UID = existItem.UID; item.GID = existItem.GID; - RINOK(outArchive.WriteHeader(item)); + RINOK(outArchive.WriteHeader(item)) size = existItem.Get_PackSize_Aligned(); pos = existItem.Get_DataPos(); } @@ -530,11 +544,13 @@ if (size != 0) { - RINOK(inStream->Seek((Int64)pos, STREAM_SEEK_SET, NULL)); - streamSpec->Init(size); + RINOK(InStream_SeekSet(inStream, pos)) + inStreamLimited->Init(size); + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) // 22.00 : we copy Residual data from old archive to new archive instead of zeroing - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != size) + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != size) return E_FAIL; outArchive.Pos += size; // RINOK(outArchive.Write_AfterDataResidual(existItem.PackSize)); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.h 2022-03-24 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Tar/TarUpdate.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // TarUpdate.h -#ifndef __TAR_UPDATE_H -#define __TAR_UPDATE_H +#ifndef ZIP7_INC_TAR_UPDATE_H +#define ZIP7_INC_TAR_UPDATE_H #include "../IArchive.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.cpp 2022-06-29 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.cpp 2023-12-19 10:00:00.000000000 +0000 @@ -26,7 +26,7 @@ if (!NWindows::NTime::GetSecondsSince1601(t.GetYear(), d[4], d[5], d[6], d[7], d[8], numSecs)) return; if (t.IsLocal()) - numSecs -= (Int64)((Int32)t.GetMinutesOffset() * 60); + numSecs = (UInt64)((Int64)numSecs - (Int64)((Int32)t.GetMinutesOffset() * 60)); const UInt32 m0 = d[9]; const UInt32 m1 = d[10]; const UInt32 m2 = d[11]; @@ -69,7 +69,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -144,15 +144,15 @@ COM_TRY_END } -class CProgressImp: public CProgressVirt +class CProgressImp Z7_final: public CProgressVirt { CMyComPtr _callback; UInt64 _numFiles; UInt64 _numBytes; public: - HRESULT SetTotal(UInt64 numBytes); - HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes); - HRESULT SetCompleted(); + HRESULT SetTotal(UInt64 numBytes) Z7_override; + HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) Z7_override; + HRESULT SetCompleted() Z7_override; CProgressImp(IArchiveOpenCallback *callback): _callback(callback), _numFiles(0), _numBytes(0) {} }; @@ -177,13 +177,13 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { Close(); CProgressImp progressImp(callback); - RINOK(_archive.Open(stream, &progressImp)); + RINOK(_archive.Open(stream, &progressImp)) bool showVolName = (_archive.LogVols.Size() > 1); FOR_VECTOR (volIndex, _archive.LogVols) { @@ -209,7 +209,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _inStream.Release(); _archive.Clear(); @@ -217,13 +217,13 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _refs2.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -258,9 +258,9 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { - *stream = 0; + *stream = NULL; const CRef2 &ref2 = _refs2[index]; const CLogVol &vol = _archive.LogVols[ref2.Vol]; @@ -318,11 +318,11 @@ return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _refs2.Size(); if (numItems == 0) @@ -332,7 +332,7 @@ for (i = 0; i < numItems; i++) { - UInt32 index = (allFilesMode ? i : indices[i]); + const UInt32 index = (allFilesMode ? i : indices[i]); const CRef2 &ref2 = _refs2[index]; const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; const CFile &file = _archive.Files[ref.FileIndex]; @@ -340,31 +340,28 @@ if (!item.IsDir()) totalSize += item.Size; } - extractCallback->SetTotal(totalSize); + RINOK(extractCallback->SetTotal(totalSize)) UInt64 currentTotalSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create outStream; - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) const CRef2 &ref2 = _refs2[index]; const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; @@ -373,8 +370,8 @@ if (item.IsDir()) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } currentTotalSize += item.Size; @@ -382,26 +379,28 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - outStreamSpec->SetStream(realOutStream); + RINOK(extractCallback->PrepareOperation(askMode)) + outStream->SetStream(realOutStream); realOutStream.Release(); - outStreamSpec->Init(item.Size); + outStream->Init(item.Size); Int32 opRes; - CMyComPtr udfInStream; - HRESULT res = GetStream(index, &udfInStream); - if (res == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (res != S_OK) - opRes = NExtract::NOperationResult::kDataError; - else { - RINOK(copyCoder->Code(udfInStream, outStream, NULL, NULL, progress)); - opRes = outStreamSpec->IsFinishedOK() ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError; + CMyComPtr udfInStream; + const HRESULT res = GetStream(index, &udfInStream); + if (res == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else if (res != S_OK) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(copyCoder.Interface()->Code(udfInStream, outStream, NULL, NULL, lps)) + opRes = outStream->IsFinishedOK() ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError; + } } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); + outStream->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END @@ -410,12 +409,18 @@ static const UInt32 kIsoStartPos = 0x8000; // 5, { 0, 'N', 'S', 'R', '0' }, -static const Byte k_Signature[] = { 1, 'C', 'D', '0', '0', '1' }; + +static const Byte k_Signature[] = +{ + 8, 0, 'B', 'E', 'A', '0', '1', 1, 0, + 6, 1, 'C', 'D', '0', '0', '1' +}; REGISTER_ARC_I( - "Udf", "udf iso img", 0, 0xE0, + "Udf", "udf iso img", NULL, 0xE0, k_Signature, kIsoStartPos, + NArcInfoFlags::kMultiSignature | NArcInfoFlags::kStartOpen, IsArc_Udf) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.h 2022-06-28 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UdfHandler.h -#ifndef __UDF_HANDLER_H -#define __UDF_HANDLER_H +#ifndef ZIP7_INC_UDF_HANDLER_H +#define ZIP7_INC_UDF_HANDLER_H #include "../../../Common/MyCom.h" @@ -19,18 +19,12 @@ unsigned Ref; }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CRecordVector _refs2; CMyComPtr _inStream; CInArchive _archive; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.cpp 2022-06-29 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -27,9 +27,9 @@ #define Get32(p) GetUi32(p) #define Get64(p) GetUi64(p) -#define G16(_offs_, dest) dest = Get16(p + (_offs_)); -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); -#define G64(_offs_, dest) dest = Get64(p + (_offs_)); +#define G16(_offs_, dest) dest = Get16(p + (_offs_)) +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) namespace NArchive { namespace NUdf { @@ -50,7 +50,7 @@ #define kCrc16Poly 0x1021 static UInt16 g_Crc16Table[256]; -static void MY_FAST_CALL Crc16GenerateTable(void) +static void Z7_FASTCALL Crc16GenerateTable(void) { UInt32 i; for (i = 0; i < 256; i++) @@ -62,7 +62,7 @@ } } -static UInt32 MY_FAST_CALL Crc16Calc(const void *data, size_t size) +static UInt32 Z7_FASTCALL Crc16Calc(const void *data, size_t size) { UInt32 v = CRC16_INIT_VAL; const Byte *p = (const Byte *)data; @@ -176,7 +176,7 @@ char temp[16]; ConvertUInt32ToHex(major, temp); s += temp; - s += '.'; + s.Add_Dot(); ConvertUInt32ToHex8Digits(minor, temp); s += &temp[8 - 2]; } @@ -346,7 +346,7 @@ const CLogVol &vol = LogVols[volIndex]; const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize; - RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, offset)) offset += len; UpdatePhySize(offset); const HRESULT res = ReadStream_FALSE(_stream, buf, len); @@ -375,7 +375,7 @@ { const CMyExtent &e = item.Extents[i]; const UInt32 len = e.GetLen(); - RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos)); + RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos)) pos += len; } return S_OK; @@ -447,6 +447,19 @@ // ECMA 4/14.4 +// UDF 2.3.4 + +/* +File Characteristics: +Deleted bit: + ECMA: If set to ONE, shall mean this File Identifier Descriptor + identifies a file that has been deleted; + UDF: If the space for the file or directory is deallocated, + the implementation shall set the ICB field to zero. + ECMA 167 4/8.6 requires that the File Identifiers of all FIDs in a directory shall be unique. + The implementations shall follow these rules when a Deleted bit is set: + rewrire the compression ID of the File Identifier: 8 -> 254, 16 -> 255. +*/ struct CFileId { @@ -456,7 +469,10 @@ CDString Id; CLongAllocDesc Icb; - bool IsItLinkParent() const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; } + bool IsItLink_Dir () const { return (FileCharacteristics & FILEID_CHARACS_Dir) != 0; } + bool IsItLink_Deleted() const { return (FileCharacteristics & FILEID_CHARACS_Deleted) != 0; } + bool IsItLink_Parent () const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; } + size_t Parse(const Byte *p, size_t size); }; @@ -466,10 +482,13 @@ if (size < 38) return 0; CTag tag; - RINOK(tag.Parse(p, size)); + if (tag.Parse(p, size) != S_OK) + return 0; if (tag.Id != DESC_TYPE_FileId) return 0; // FileVersion = Get16(p + 16); + // UDF: There shall be only one version of a file as specified below with the value being set to 1. + FileCharacteristics = p[18]; const unsigned idLen = p[19]; Icb.Parse(p + 20); @@ -490,10 +509,10 @@ -HRESULT CInArchive::ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) +HRESULT CInArchive::ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed) { if (Files.Size() % 100 == 0) - RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes)); + RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes)) if (numRecurseAllowed-- == 0) return S_FALSE; CFile &file = Files.Back(); @@ -510,15 +529,15 @@ { if (value == kRecursedErrorValue) return S_FALSE; - file.ItemIndex = value; + file.ItemIndex = (int)(Int32)value; } else { value = Items.Size(); - file.ItemIndex = (int)value; + file.ItemIndex = (int)(Int32)value; if (partition.Map.Set(key, kRecursedErrorValue)) return S_FALSE; - RINOK(ReadItem(volIndex, fsIndex, lad, numRecurseAllowed)); + RINOK(ReadItem(volIndex, (int)fsIndex, lad, isDir, numRecurseAllowed)) if (!partition.Map.Set(key, value)) return S_FALSE; } @@ -528,7 +547,7 @@ // (fsIndex = -1) means that it's metadata file -HRESULT CInArchive::ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) +HRESULT CInArchive::ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed) { if (Items.Size() >= kNumItemsMax) return S_FALSE; @@ -541,11 +560,11 @@ return S_FALSE; CByteBuffer buf(size); - RINOK(ReadLad(volIndex, lad, buf)); + RINOK(ReadLad(volIndex, lad, buf)) CTag tag; const Byte *p = buf; - RINOK(tag.Parse(p, size)); + RINOK(tag.Parse(p, size)) item.IsExtended = (tag.Id == DESC_TYPE_ExtendedFile); const size_t kExtendOffset = item.IsExtended ? 40 : 0; @@ -638,6 +657,9 @@ } } + if (isDir != item.IcbTag.IsDir()) + return S_FALSE; + if (item.IcbTag.IsDir()) { if (fsIndex < 0) @@ -646,7 +668,7 @@ if (!item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) return S_FALSE; CByteBuffer buf2; - RINOK(ReadFromFile(volIndex, item, buf2)); + RINOK(ReadFromFile(volIndex, item, buf2)) item.Size = 0; item.Extents.ClearAndFree(); item.InlineData.Free(); @@ -663,7 +685,10 @@ p2 += cur; size2 -= cur; } - if (!fileId.IsItLinkParent()) + if (fileId.IsItLink_Parent()) + continue; + if (fileId.IsItLink_Deleted()) + continue; { CFile file; // file.FileVersion = fileId.FileVersion; @@ -679,7 +704,8 @@ if (Files.Size() >= kNumFilesMax) return S_FALSE; Files.Add(file); - RINOK(ReadFileItem(volIndex, fsIndex, fileId.Icb, numRecurseAllowed)); + RINOK(ReadFileItem(volIndex, (unsigned)fsIndex, fileId.Icb, + fileId.IsItLink_Dir(), numRecurseAllowed)) } } } @@ -702,7 +728,7 @@ { if ((_numRefs & 0xFFF) == 0) { - RINOK(_progress->SetCompleted()); + RINOK(_progress->SetCompleted()) } if (numRecurseAllowed-- == 0) return S_FALSE; @@ -712,12 +738,12 @@ CRef ref; ref.FileIndex = fileIndex; ref.Parent = parent; - parent = fs.Refs.Size(); + parent = (int)fs.Refs.Size(); fs.Refs.Add(ref); const CItem &item = Items[Files[fileIndex].ItemIndex]; FOR_VECTOR (i, item.SubFiles) { - RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed)); + RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed)) } return S_OK; } @@ -727,9 +753,9 @@ { UInt32 res = k_IsArc_Res_NO; unsigned SecLogSize; - for (SecLogSize = 11;; SecLogSize -= 3) + for (SecLogSize = 11;; SecLogSize -= 2) { - if (SecLogSize < 8) + if (SecLogSize < 9) return res; const UInt32 offset = (UInt32)256 << SecLogSize; const UInt32 bufSize = (UInt32)1 << SecLogSize; @@ -754,7 +780,7 @@ { Clear(); UInt64 fileSize; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize)) FileSize = fileSize; // Some UDFs contain additional pad zeros (2 KB). @@ -765,7 +791,7 @@ const size_t kBufSize = 1 << 14; Byte buf[kBufSize]; size_t readSize = (fileSize < kBufSize) ? (size_t)fileSize : kBufSize; - RINOK(_stream->Seek(fileSize - readSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, fileSize - readSize)) RINOK(ReadStream(_stream, buf, &readSize)); size_t i = readSize; for (;;) @@ -785,20 +811,29 @@ extentVDS.Parse(buf + i + 16); */ + /* + An Anchor Volume Descriptor Pointer structure shall be recorded in at + least 2 of the following 3 locations on the media: + Logical Sector 256. + Logical Sector (N - 256). + N + */ + const size_t kBufSize = 1 << 11; Byte buf[kBufSize]; - for (SecLogSize = 11;; SecLogSize -= 3) + for (SecLogSize = 11;; SecLogSize -= 2) { - if (SecLogSize < 8) + // Windows 10 uses unusual (SecLogSize = 9) + if (SecLogSize < 9) return S_FALSE; const UInt32 offset = (UInt32)256 << SecLogSize; if (offset >= fileSize) continue; - RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, offset)) const size_t bufSize = (size_t)1 << SecLogSize; size_t readSize = bufSize; - RINOK(ReadStream(_stream, buf, &readSize)); + RINOK(ReadStream(_stream, buf, &readSize)) if (readSize == bufSize) { CTag tag; @@ -834,15 +869,15 @@ const size_t bufSize = (size_t)1 << SecLogSize; { const UInt64 offs = ((UInt64)extentVDS.Pos + location) << SecLogSize; - RINOK(_stream->Seek(offs, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, offs)) const HRESULT res = ReadStream_FALSE(_stream, buf, bufSize); if (res == S_FALSE && offs + bufSize > FileSize) UnexpectedEnd = true; - RINOK(res); + RINOK(res) } CTag tag; - RINOK(tag.Parse(buf, bufSize)); + RINOK(tag.Parse(buf, bufSize)) if (tag.Id == DESC_TYPE_Terminating) break; @@ -1086,14 +1121,26 @@ RINOK(ReadItem(volIndex, -1, // (fsIndex = -1) means that it's metadata lad, - 1)); // numRecurseAllowed + false, // isDir + 1)) // numRecurseAllowed } { const CItem &item = Items.Back(); if (!CheckItemExtents(volIndex, item)) return S_FALSE; if (item.Extents.Size() != 1) - return S_FALSE; + { + if (item.Extents.Size() < 1) + return S_FALSE; + /* Windows 10 writes empty record item.Extents[1]. + we ignore such extent here */ + for (unsigned k = 1; k < item.Extents.Size(); k++) + { + const CMyExtent &e = item.Extents[k]; + if (e.GetLen() != 0) + return S_FALSE; + } + } const CMyExtent &e = item.Extents[0]; const CPartition &part = Partitions[pm.PartitionIndex]; @@ -1126,7 +1173,7 @@ } } - RINOK(_progress->SetTotal(totalSize)); + RINOK(_progress->SetTotal(totalSize)) PRF(printf("\n Read files")); @@ -1143,12 +1190,12 @@ if (nextExtent.GetLen() < 512) return S_FALSE; CByteBuffer buf2(nextExtent.GetLen()); - RINOK(ReadLad(volIndex, nextExtent, buf2)); + RINOK(ReadLad(volIndex, nextExtent, buf2)) const Byte *p = buf2; const size_t size = nextExtent.GetLen(); CTag tag; - RINOK(tag.Parse(p, size)); + RINOK(tag.Parse(p, size)) /* // commented in 22.01 @@ -1191,8 +1238,10 @@ CFileSet &fs = vol.FileSets[fsIndex]; const unsigned fileIndex = Files.Size(); Files.AddNew(); - RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB, kNumRecursionLevelsMax)); - RINOK(FillRefs(fs, fileIndex, -1, kNumRecursionLevelsMax)); + RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB, + true, // isDir + kNumRecursionLevelsMax)) + RINOK(FillRefs(fs, fileIndex, -1, kNumRecursionLevelsMax)) } } @@ -1248,7 +1297,7 @@ UInt64 rem = fileSize - PhySize; const size_t secSize = (size_t)1 << SecLogSize; - RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, PhySize)) // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end @@ -1261,7 +1310,7 @@ if (readSize > rem) readSize = (size_t)rem; - RINOK(ReadStream(_stream, buf, &readSize)); + RINOK(ReadStream(_stream, buf, &readSize)) if (readSize == 0) break; @@ -1270,8 +1319,9 @@ if (readSize == secSize /* && NoEndAnchor */) { CTag tag; - if (tag.Parse(buf, readSize) == S_OK && - tag.Id == DESC_TYPE_AnchorVolPtr) + if (tag.Parse(buf, readSize) == S_OK + && tag.Id == DESC_TYPE_AnchorVolPtr + && Get32(buf + 12) == (UInt32)((fileSize - rem) >> SecLogSize)) { NoEndAnchor = false; rem -= readSize; @@ -1443,7 +1493,7 @@ , "NetBSD" }; -static void AddOs_Class_Id(UString &s, const char *p) +static void AddOs_Class_Id(UString &s, const Byte *p) { // UDF 2.1.5.3 Implementation Identifier Suffix // Appendix 6.3 Operating System Identifiers. @@ -1451,7 +1501,7 @@ if (osClass != 0) { s += "::"; - s += TypeToString(g_OsClasses, ARRAY_SIZE(g_OsClasses), osClass); + s += TypeToString(g_OsClasses, Z7_ARRAY_SIZE(g_OsClasses), osClass); } const Byte osId = p[1]; if (osId != 0) @@ -1459,7 +1509,7 @@ s += "::"; if (osClass == 4) // unix { - s += TypeToString(g_OsIds_Unix, ARRAY_SIZE(g_OsIds_Unix), osId); + s += TypeToString(g_OsIds_Unix, Z7_ARRAY_SIZE(g_OsIds_Unix), osId); } else s.Add_UInt32(osId); @@ -1552,7 +1602,7 @@ AddComment_RegId(s, "ContentsId", part.ContentsId); AddComment_RegId_Impl(s, "ImplementationId", part.ImplId); AddComment_PropName(s, "AccessType"); - s += TypeToString(g_PartitionTypes, ARRAY_SIZE(g_PartitionTypes), part.AccessType); + s += TypeToString(g_PartitionTypes, Z7_ARRAY_SIZE(g_PartitionTypes), part.AccessType); s.Add_LF(); } AddComment_UInt64(s, "Size", (UInt64)part.Len << SecLogSize); @@ -1663,7 +1713,7 @@ // we break on root file (that probably has empty name) if (ref.Parent < 0) break; - refIndex = ref.Parent; + refIndex = (unsigned)ref.Parent; UpdateWithName(name, GetSpecName(Files[ref.FileIndex].GetName())); } @@ -1681,7 +1731,7 @@ UString newName2 = vol.GetName(); if (newName2.IsEmpty()) newName2 = "Volume"; - newName += '-'; + newName.Add_Minus(); newName += newName2; UpdateWithName(name, newName); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.h 2022-06-29 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Udf/UdfIn.h 2023-03-23 08:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/UdfIn.h -- UDF / ECMA-167 -#ifndef __ARCHIVE_UDF_IN_H -#define __ARCHIVE_UDF_IN_H +#ifndef ZIP7_INC_ARCHIVE_UDF_IN_H +#define ZIP7_INC_ARCHIVE_UDF_IN_H #include "../../../Common/IntToString.h" #include "../../../Common/MyBuffer.h" @@ -72,7 +72,7 @@ { Byte Flags; char Id[23]; - char Suffix[8]; + Byte Suffix[8]; void Parse(const Byte *buf); void AddCommentTo(UString &s) const; @@ -281,9 +281,15 @@ void Parse(const Byte *p); }; + // ECMA 4/14.4.3 +// UDF 2.3.4.2 FileCharacteristics + // const Byte FILEID_CHARACS_Existance = (1 << 0); -const Byte FILEID_CHARACS_Parent = (1 << 3); +const Byte FILEID_CHARACS_Dir = (1 << 1); +const Byte FILEID_CHARACS_Deleted = (1 << 2); +const Byte FILEID_CHARACS_Parent = (1 << 3); +// const Byte FILEID_CHARACS_Metadata = (1 << 4); struct CFile { @@ -423,13 +429,14 @@ }; - -struct CProgressVirt +Z7_PURE_INTERFACES_BEGIN +struct Z7_DECLSPEC_NOVTABLE CProgressVirt { - virtual HRESULT SetTotal(UInt64 numBytes) PURE; - virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) PURE; - virtual HRESULT SetCompleted() PURE; + virtual HRESULT SetTotal(UInt64 numBytes) =0; \ + virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) =0; \ + virtual HRESULT SetCompleted() =0; \ }; +Z7_PURE_INTERFACES_END class CInArchive { @@ -467,8 +474,8 @@ HRESULT ReadLad(unsigned volIndex, const CLongAllocDesc &lad, Byte *buf); HRESULT ReadFromFile(unsigned volIndex, const CItem &item, CByteBuffer &buf); - HRESULT ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); - HRESULT ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); + HRESULT ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed); + HRESULT ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed); HRESULT Open2(); HRESULT FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/UefiHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/UefiHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/UefiHandler.cpp 2021-01-26 09:48:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/UefiHandler.cpp 2024-06-17 08:00:00.000000000 +0000 @@ -10,9 +10,10 @@ #include "../../../C/7zCrc.h" #include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" #include "../../../C/LzmaDec.h" +#include "../../../C/CpuArch.h" +#include "../../Common/AutoPtr.h" #include "../../Common/ComTry.h" #include "../../Common/IntToString.h" #include "../../Common/MyBuffer.h" @@ -42,8 +43,8 @@ namespace NArchive { namespace NUefi { -static const size_t kBufTotalSizeMax = (1 << 29); -static const unsigned kNumFilesMax = (1 << 18); +static const size_t kBufTotalSizeMax = 1 << 29; +static const unsigned kNumFilesMax = 1 << 18; static const unsigned kLevelMax = 64; static const Byte k_IntelMeSignature[] = @@ -171,14 +172,14 @@ static const char *FindExt(const Byte *p, size_t size) { unsigned i; - for (i = 0; i < ARRAY_SIZE(g_Sigs); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_Sigs); i++) { const CSigExtPair &pair = g_Sigs[i]; if (size >= pair.sigSize) if (memcmp(p, pair.sig, pair.sigSize) == 0) break; } - if (i == ARRAY_SIZE(g_Sigs)) + if (i == Z7_ARRAY_SIZE(g_Sigs)) return NULL; switch (i) { @@ -212,9 +213,9 @@ static int FindGuid(const Byte *p) { - for (unsigned i = 0; i < ARRAY_SIZE(kGuids); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kGuids); i++) if (AreGuidsEq(p, kGuids[i])) - return i; + return (int)i; return -1; } @@ -222,7 +223,7 @@ { if (Get32(p + 0x28) != kFvSignature) return false; - for (unsigned i = 0; i < ARRAY_SIZE(k_Guids_FS); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Guids_FS); i++) if (AreGuidsEq(p + kFfsGuidOffset, k_Guids_FS[i])) return true; return false; @@ -396,7 +397,7 @@ for (UInt32 i = 0; i < size;) { unsigned command = p[i++]; - if (command > ARRAY_SIZE(kExpressionCommands)) + if (command > Z7_ARRAY_SIZE(kExpressionCommands)) return false; res += kExpressionCommands[command]; if (command < 3) @@ -437,9 +438,9 @@ return true; } -#define FLAGS_TO_STRING(pairs, value) FlagsToString(pairs, ARRAY_SIZE(pairs), value) -#define TYPE_TO_STRING(table, value) TypeToString(table, ARRAY_SIZE(table), value) -#define TYPE_PAIR_TO_STRING(table, value) TypePairToString(table, ARRAY_SIZE(table), value) +#define FLAGS_TO_STRING(pairs, value) FlagsToString(pairs, Z7_ARRAY_SIZE(pairs), value) +#define TYPE_TO_STRING(table, value) TypeToString(table, Z7_ARRAY_SIZE(table), value) +#define TYPE_PAIR_TO_STRING(table, value) TypePairToString(table, Z7_ARRAY_SIZE(table), value) static const UInt32 kFileHeaderSize = 24; @@ -559,8 +560,8 @@ } }; -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); -#define G16(_offs_, dest) dest = Get16(p + (_offs_)); +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G16(_offs_, dest) dest = Get16(p + (_offs_)) struct CCapsuleHeader { @@ -632,14 +633,14 @@ int Parent; int Method; int NameIndex; - int NumChilds; + unsigned NumChilds; bool IsDir; bool Skip; bool ThereAreSubDirs; bool ThereIsUniqueName; bool KeepName; - int BufIndex; + unsigned BufIndex; UInt32 Offset; UInt32 Size; @@ -668,14 +669,14 @@ return Name; char sz[32]; char sz2[32]; - ConvertUInt32ToString(NameIndex, sz); - ConvertUInt32ToString(numChildsInParent - 1, sz2); - int numZeros = (int)strlen(sz2) - (int)strlen(sz); + ConvertUInt32ToString((unsigned)NameIndex, sz); + ConvertUInt32ToString((unsigned)numChildsInParent - 1, sz2); + const int numZeros = (int)strlen(sz2) - (int)strlen(sz); AString res; for (int i = 0; i < numZeros; i++) res += '0'; res += sz; - res += '.'; + res.Add_Dot(); res += Name; return res; } @@ -684,17 +685,16 @@ { AString Name; AString Characts; - int MainIndex; + unsigned MainIndex; int Parent; CItem2(): Parent(-1) {} }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CObjectVector _items; CObjectVector _items2; CObjectVector _bufs; @@ -708,20 +708,23 @@ UInt64 _phySize; void AddCommentString(const char *name, UInt32 pos); - int AddItem(const CItem &item); - int AddFileItemWithIndex(CItem &item); - int AddDirItem(CItem &item); + unsigned AddItem(const CItem &item); + unsigned AddFileItemWithIndex(CItem &item); + unsigned AddDirItem(CItem &item); unsigned AddBuf(size_t size); HRESULT DecodeLzma(const Byte *data, size_t inputSize); - HRESULT ParseSections(int bufIndex, UInt32 pos, UInt32 size, int parent, int method, unsigned level, bool &error); + HRESULT ParseSections(unsigned bufIndex, UInt32 pos, + UInt32 size, + int parent, int method, unsigned level, + bool &error); - HRESULT ParseIntelMe(int bufIndex, UInt32 posBase, + HRESULT ParseIntelMe(unsigned bufIndex, UInt32 posBase, UInt32 exactSize, UInt32 limitSize, int parent, int method, unsigned level); - HRESULT ParseVolume(int bufIndex, UInt32 posBase, + HRESULT ParseVolume(unsigned bufIndex, UInt32 posBase, UInt32 exactSize, UInt32 limitSize, int parent, int method, unsigned level); @@ -730,11 +733,9 @@ HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback); public: CHandler(bool capsuleMode): _capsuleMode(capsuleMode) {} - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; + static const Byte kProps[] = { kpidPath, @@ -755,7 +756,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -823,7 +824,7 @@ _comment += s; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -845,7 +846,7 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_headersError) v |= kpv_ErrorFlags_HeadersError; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; if (v != 0) prop = v; break; @@ -875,23 +876,23 @@ -int CHandler::AddItem(const CItem &item) +unsigned CHandler::AddItem(const CItem &item) { if (_items.Size() >= kNumFilesMax) throw 2; return _items.Add(item); } -int CHandler::AddFileItemWithIndex(CItem &item) +unsigned CHandler::AddFileItemWithIndex(CItem &item) { - int nameIndex = _items.Size(); + unsigned nameIndex = _items.Size(); if (item.Parent >= 0) nameIndex = _items[item.Parent].NumChilds++; - item.NameIndex = nameIndex; + item.NameIndex = (int)nameIndex; return AddItem(item); } -int CHandler::AddDirItem(CItem &item) +unsigned CHandler::AddDirItem(CItem &item) { if (item.Parent >= 0) _items[item.Parent].ThereAreSubDirs = true; @@ -936,7 +937,7 @@ } -HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level, bool &error) +HRESULT CHandler::ParseSections(unsigned bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level, bool &error) { error = false; @@ -990,8 +991,8 @@ { if (sectSize < 4 + 5) return S_FALSE; - UInt32 uncompressedSize = Get32(p + 4); - Byte compressionType = p[8]; + const UInt32 uncompressedSize = Get32(p + 4); + const Byte compressionType = p[8]; UInt32 newSectSize = sectSize - 9; UInt32 newOffset = posBase + pos + 9; @@ -1010,25 +1011,20 @@ if (compressionType == COMPRESSION_TYPE_NONE) { bool error2; - RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level, error2)); + RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level, error2)) } else if (compressionType == COMPRESSION_TYPE_LZH) { - unsigned newBufIndex = AddBuf(uncompressedSize); + const unsigned newBufIndex = AddBuf(uncompressedSize); CByteBuffer &buf = _bufs[newBufIndex]; - - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; - CMyComPtr lzhDecoder; - - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - + CMyUniquePtr lzhDecoder; + lzhDecoder.Create_if_Empty(); { const Byte *src = pStart; if (newSectSize < 8) return S_FALSE; UInt32 packSize = Get32(src); - UInt32 unpackSize = Get32(src + 4); + const UInt32 unpackSize = Get32(src + 4); PRF(printf(" LZH packSize = %6x, unpackSize = %6x", packSize, unpackSize)); @@ -1041,14 +1037,10 @@ if (src[packSize] != 0) return S_FALSE; - CBufInStream *inStreamSpec = new CBufInStream; - CMyComPtr inStream = inStreamSpec; - - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream = outStreamSpec; - - UInt64 uncompressedSize64 = uncompressedSize; - lzhDecoderSpec->FinishMode = true; + CMyComPtr2_Create inStream; + CMyComPtr2_Create outStream; + // const UInt64 uncompressedSize64 = uncompressedSize; + // lzhDecoder->FinishMode = true; /* EFI 1.1 probably used LZH with small dictionary and (pbit = 4). It was named "Efi compression". New version of compression code (named Tiano) uses LZH with (1 << 19) dictionary. @@ -1056,21 +1048,19 @@ We check both LZH versions: Tiano and then Efi. */ HRESULT res = S_FALSE; - for (unsigned m = 0 ; m < 2; m++) { - inStreamSpec->Init(src, packSize); - outStreamSpec->Init(buf, uncompressedSize); - lzhDecoderSpec->SetDictSize((m == 0) ? ((UInt32)1 << 19) : ((UInt32)1 << 14)); - res = lzhDecoder->Code(inStream, outStream, NULL, &uncompressedSize64, NULL); + inStream->Init(src, packSize); + outStream->Init(buf, uncompressedSize); + lzhDecoder->SetDictSize(m == 0 ? ((UInt32)1 << 19) : ((UInt32)1 << 14)); + res = lzhDecoder->Code(inStream, outStream, uncompressedSize, NULL); if (res == S_OK) break; } - RINOK(res); + RINOK(res) } - bool error2; - RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level, error2)); + RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level, error2)) } else { @@ -1091,13 +1081,13 @@ } pStart += addSize; - RINOK(DecodeLzma(pStart, newSectSize - addSize)); + RINOK(DecodeLzma(pStart, newSectSize - addSize)) const size_t lzmaUncompressedSize = _bufs.Back().Size(); // if (lzmaUncompressedSize != uncompressedSize) if (lzmaUncompressedSize < uncompressedSize) return S_FALSE; bool error2; - RINOK(ParseSections(_bufs.Size() - 1, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level, error2)); + RINOK(ParseSections(_bufs.Size() - 1, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level, error2)) } _methodsMask |= (1 << compressionType); } @@ -1108,15 +1098,15 @@ if (sectSize < kHeaderSize) return S_FALSE; item.SetGuid(p + 4); - UInt32 dataOffset = Get16(p + 4 + kGuidSize); - UInt32 attrib = Get16(p + 4 + kGuidSize + 2); + const UInt32 dataOffset = Get16(p + 4 + kGuidSize); + const UInt32 attrib = Get16(p + 4 + kGuidSize + 2); if (dataOffset > sectSize || dataOffset < kHeaderSize) return S_FALSE; UInt32 newSectSize = sectSize - dataOffset; item.Size = newSectSize; UInt32 newOffset = posBase + pos + dataOffset; item.Offset = newOffset; - UInt32 propsSize = dataOffset - kHeaderSize; + const UInt32 propsSize = dataOffset - kHeaderSize; AddSpaceAndString(item.Characts, FLAGS_TO_STRING(g_GUIDED_SECTION_ATTRIBUTES, attrib)); bool needDir = true; @@ -1129,7 +1119,7 @@ // AddItem(item); const Byte *pStart = bufData + newOffset; // do we need correct pStart here for lzma steram offset? - RINOK(DecodeLzma(pStart, newSectSize)); + RINOK(DecodeLzma(pStart, newSectSize)) _methodsMask |= (1 << COMPRESSION_TYPE_LZMA); newBufIndex = _bufs.Size() - 1; newOffset = 0; @@ -1157,18 +1147,18 @@ int newParent = parent; if (needDir) - newParent = AddDirItem(item); + newParent = (int)AddDirItem(item); bool error2; - RINOK(ParseSections(newBufIndex, newOffset, newSectSize, newParent, newMethod, level, error2)); + RINOK(ParseSections(newBufIndex, newOffset, newSectSize, newParent, newMethod, level, error2)) } else if (type == SECTION_FIRMWARE_VOLUME_IMAGE) { item.KeepName = false; - int newParent = AddDirItem(item); + const int newParent = (int)AddDirItem(item); RINOK(ParseVolume(bufIndex, posBase + pos + 4, sectSize - 4, sectSize - 4, - newParent, method, level)); + newParent, method, level)) } else { @@ -1185,11 +1175,11 @@ { needAdd = false; item.Name = "vol"; - int newParent = AddDirItem(item); + const unsigned newParent = AddDirItem(item); RINOK(ParseVolume(bufIndex, posBase + pos + 4 + kInsydeOffset, sectDataSize - kInsydeOffset, sectDataSize - kInsydeOffset, - newParent, method, level)); + (int)newParent, method, level)) } if (needAdd) @@ -1306,11 +1296,11 @@ if (HeaderLen < kFvHeaderSize || (HeaderLen & 0x7) != 0 || VolSize < HeaderLen) return false; return true; -}; +} HRESULT CHandler::ParseVolume( - int bufIndex, UInt32 posBase, + unsigned bufIndex, UInt32 posBase, UInt32 exactSize, UInt32 limitSize, int parent, int method, unsigned level) { @@ -1382,7 +1372,7 @@ UInt32 rem = (UInt32)ffsHeader.VolSize - pos; if (rem < kFileHeaderSize) break; - pos = (pos + 7) & ~7; + pos = (pos + 7) & ~7u; rem = (UInt32)ffsHeader.VolSize - pos; if (rem < kFileHeaderSize) break; @@ -1457,11 +1447,11 @@ } if (isVolume) { - int newParent = AddDirItem(item); - UInt32 limSize = fh.GetDataSize2(rem); + const unsigned newParent = AddDirItem(item); + const UInt32 limSize = fh.GetDataSize2(rem); // volume.VolSize > fh.Size for some UEFI archives (is it correct UEFI?) // so we will check VolSize for limitSize instead. - RINOK(ParseVolume(bufIndex, offset, sectSize, limSize, newParent, method, level)); + RINOK(ParseVolume(bufIndex, offset, sectSize, limSize, (int)newParent, method, level)) } else AddItem(item); @@ -1477,9 +1467,9 @@ else */ { - int newParent = AddDirItem(item); + const unsigned newParent = AddDirItem(item); bool error2; - RINOK(ParseSections(bufIndex, offset, sectSize, newParent, method, level + 1, error2)); + RINOK(ParseSections(bufIndex, offset, sectSize, (int)newParent, method, level + 1, error2)) if (error2) { // in intel bio example: one FV_FILETYPE_FREEFORM file is wav file (not sections) @@ -1510,12 +1500,13 @@ HRESULT CHandler::ParseIntelMe( - int bufIndex, UInt32 posBase, + unsigned bufIndex, UInt32 posBase, UInt32 exactSize, UInt32 limitSize, - int parent, int method, unsigned level) + int parent, int method, unsigned /* level */) { UNUSED_VAR(limitSize) - level++; + // level++; + const Byte *p = _bufs[bufIndex] + posBase; if (exactSize < 16 + 16) return S_FALSE; @@ -1581,13 +1572,15 @@ { const unsigned kHeaderSize = 80; Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)) if (!_h.Parse(buf)) return S_FALSE; if (_h.CapsuleImageSize < kHeaderSize || _h.CapsuleImageSize < _h.HeaderSize || _h.OffsetToCapsuleBody < _h.HeaderSize || _h.OffsetToCapsuleBody > _h.CapsuleImageSize + || _h.CapsuleImageSize > (1u << 30) // to reduce false detection + || _h.HeaderSize > (1u << 28) // to reduce false detection ) return S_FALSE; _phySize = _h.CapsuleImageSize; @@ -1596,7 +1589,7 @@ _h.OffsetToSplitInformation != 0 ) return E_NOTIMPL; - unsigned bufIndex = AddBuf(_h.CapsuleImageSize); + const unsigned bufIndex = AddBuf(_h.CapsuleImageSize); CByteBuffer &buf0 = _bufs[bufIndex]; memcpy(buf0, buf, kHeaderSize); ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize); @@ -1619,7 +1612,7 @@ HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* callback */) { Byte buf[kFvHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kFvHeaderSize)); + RINOK(ReadStream_FALSE(stream, buf, kFvHeaderSize)) if (!IsFfs(buf)) return S_FALSE; CVolFfsHeader ffsHeader; @@ -1628,10 +1621,10 @@ if (ffsHeader.VolSize > ((UInt32)1 << 30)) return S_FALSE; _phySize = ffsHeader.VolSize; - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(stream)) UInt32 fvSize32 = (UInt32)ffsHeader.VolSize; unsigned bufIndex = AddBuf(fvSize32); - RINOK(ReadStream_FALSE(stream, _bufs[bufIndex], fvSize32)); + RINOK(ReadStream_FALSE(stream, _bufs[bufIndex], fvSize32)) return ParseVolume(bufIndex, 0, fvSize32, fvSize32, -1, -1, 0); } @@ -1640,14 +1633,14 @@ { if (_capsuleMode) { - RINOK(OpenCapsule(stream)); + RINOK(OpenCapsule(stream)) } else { - RINOK(OpenFv(stream, maxCheckStartPosition, callback)); + RINOK(OpenFv(stream, maxCheckStartPosition, callback)) } - unsigned num = _items.Size(); + const unsigned num = _items.Size(); CIntArr numChilds(num); unsigned i; @@ -1657,7 +1650,7 @@ for (i = 0; i < num; i++) { - int parent = _items[i].Parent; + const int parent = _items[i].Parent; if (parent >= 0) numChilds[(unsigned)parent]++; } @@ -1665,7 +1658,7 @@ for (i = 0; i < num; i++) { const CItem &item = _items[i]; - int parent = item.Parent; + const int parent = item.Parent; if (parent >= 0) { CItem &parentItem = _items[(unsigned)parent]; @@ -1718,7 +1711,7 @@ item2.Name = name; item2.Characts = characts2; if (parent >= 0) - item2.Parent = mainToReduced[(unsigned)parent]; + item2.Parent = (int)mainToReduced[(unsigned)parent]; _items2.Add(item2); /* CItem2 item2; @@ -1732,9 +1725,9 @@ return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback) + IArchiveOpenCallback *callback)) { COM_TRY_BEGIN Close(); @@ -1747,7 +1740,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; _totalBufsSize = 0; @@ -1761,17 +1754,17 @@ return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items2.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items2.Size(); if (numItems == 0) @@ -1780,55 +1773,54 @@ UInt32 i; for (i = 0; i < numItems; i++) totalSize += _items[_items2[allFilesMode ? i : indices[i]].MainIndex].Size; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; + RINOK(extractCallback->SetTotal(totalSize)) + totalSize = 0; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; - for (i = 0; i < numItems; i++) + for (i = 0;; i++) { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[_items2[index].MainIndex]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentTotalSize += item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode || item.IsDir) + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + Int32 opRes; { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - int res = NExtract::NOperationResult::kDataError; - CMyComPtr inStream; - GetStream(index, &inStream); - if (inStream) - { - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) - res = NExtract::NOperationResult::kOK; + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[_items2[index].MainIndex]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + totalSize += item.Size; + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (testMode || item.IsDir) + opRes = NExtract::NOperationResult::kOK; + else + { + opRes = NExtract::NOperationResult::kDataError; + CMyComPtr inStream; + GetStream(index, &inStream); + if (inStream) + { + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) + opRes = NExtract::NOperationResult::kOK; + } + } } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN const CItem &item = _items[_items2[index].MainIndex]; @@ -1860,7 +1852,7 @@ REGISTER_ARC_I_CLS( CHandler(true), - "UEFIc", "scap", 0, 0xD0, + "UEFIc", "scap", NULL, 0xD0, k_Capsule_Signatures, 0, NArcInfoFlags::kMultiSignature | @@ -1880,7 +1872,7 @@ REGISTER_ARC_I_CLS( CHandler(false), - "UEFIf", "uefif", 0, 0xD1, + "UEFIf", "uefif", NULL, 0xD1, k_FFS_Signatures, kFfsGuidOffset, NArcInfoFlags::kMultiSignature | diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/VdiHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VdiHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/VdiHandler.cpp 2021-12-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VdiHandler.cpp 2023-03-06 17:00:00.000000000 +0000 @@ -26,9 +26,7 @@ namespace NArchive { namespace NVdi { -#define SIGNATURE { 0x7F, 0x10, 0xDA, 0xBE } - -static const Byte k_Signature[] = SIGNATURE; +static const Byte k_Signature[] = { 0x7F, 0x10, 0xDA, 0xBE }; static const unsigned k_ClusterBits = 20; static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits; @@ -85,7 +83,7 @@ -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { UInt32 _dataOffset; CByteBuffer _table; @@ -99,7 +97,7 @@ HRESULT Seek2(UInt64 offset) { _posInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, offset); } HRESULT InitAndSeek() @@ -108,17 +106,17 @@ return Seek2(0); } - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; public: - INTERFACE_IInArchive_Img(;) + Z7_IFACE_COM7_IMP(IInArchive_Img) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) }; -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -152,7 +150,7 @@ offset += lowBits; if (offset != _posInArc) { - RINOK(Seek2(offset)); + RINOK(Seek2(offset)) } HRESULT res = Stream->Read(data, size, &size); _posInArc += size; @@ -189,7 +187,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -209,7 +207,7 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; // if (_headerError) v |= kpv_ErrorFlags_HeadersError; if (!Stream && v == 0 && _isArc) @@ -249,7 +247,7 @@ char temp[64]; RawLeGuidToString_Braced(guid, temp); MyStringLower_Ascii(temp); - strcat(temp, ".vdi"); + MyStringCat(temp, ".vdi"); prop = temp; } break; @@ -262,7 +260,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -284,7 +282,7 @@ { const unsigned kHeaderSize = 512; Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)) if (memcmp(buf + 0x40, k_Signature, sizeof(k_Signature)) != 0) return S_FALSE; @@ -378,8 +376,8 @@ } _table.Alloc(numBytes); - RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _table, numBytes)); + RINOK(InStream_SeekSet(stream, tableOffset)) + RINOK(ReadStream_FALSE(stream, _table, numBytes)) const Byte *data = _table; for (UInt32 i = 0; i < totalBlocks; i++) @@ -399,7 +397,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _table.Free(); _phySize = 0; @@ -416,14 +414,14 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; if (_unsupported) return S_FALSE; CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); + RINOK(InitAndSeek()) *stream = streamTemp.Detach(); return S_OK; COM_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/VhdHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/VhdHandler.cpp 2022-02-02 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -5,6 +5,7 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" #include "../../Windows/PropVariant.h" @@ -18,18 +19,17 @@ #define Get32(p) GetBe32(p) #define Get64(p) GetBe64(p) -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); -#define G64(_offs_, dest) dest = Get64(p + (_offs_)); +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) using namespace NWindows; namespace NArchive { namespace NVhd { -#define SIGNATURE { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x', 0, 0 } - static const unsigned kSignatureSize = 10; -static const Byte kSignature[kSignatureSize] = SIGNATURE; +static const Byte kSignature[kSignatureSize] = + { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x', 0, 0 }; static const UInt32 kUnusedBlock = 0xFFFFFFFF; @@ -74,7 +74,7 @@ void CFooter::AddTypeString(AString &s) const { - if (Type < ARRAY_SIZE(kDiskTypes)) + if (Type < Z7_ARRAY_SIZE(kDiskTypes)) s += kDiskTypes[Type]; else s.Add_UInt32(Type); @@ -214,7 +214,7 @@ return CheckBlock(p, 1024, 0x24, 0x240 + 8 * 24); } -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { UInt64 _posInArcLimit; UInt64 _startOffset; @@ -247,7 +247,6 @@ _phySize = value; } - void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; } HRESULT Seek2(UInt64 offset); HRESULT InitAndSeek(); HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size); @@ -280,9 +279,9 @@ if (mainName != anotherName && !anotherName.IsEmpty()) { res.Add_Space(); - res += '('; + res.Add_Char('('); res += anotherName; - res += ')'; + res.Add_Char(')'); } p = p->Parent; } @@ -303,26 +302,26 @@ HRESULT Open3(); HRESULT Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level); - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) Z7_override { return Open2(stream, NULL, openArchiveCallback, 0); } - void CloseAtError(); + void CloseAtError() Z7_override; public: - INTERFACE_IInArchive_Img(;) + Z7_IFACE_COM7_IMP(IInArchive_Img) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) }; -HRESULT CHandler::Seek2(UInt64 offset) { return Stream->Seek(_startOffset + offset, STREAM_SEEK_SET, NULL); } +HRESULT CHandler::Seek2(UInt64 offset) { return InStream_SeekSet(Stream, _startOffset + offset); } HRESULT CHandler::InitAndSeek() { if (ParentStream) { - RINOK(Parent->InitAndSeek()); + RINOK(Parent->InitAndSeek()) } _virtPos = _posInArc = 0; BitMapTag = kUnusedBlock; @@ -337,7 +336,7 @@ if (offset != _posInArc) { _posInArc = offset; - RINOK(Seek2(offset)); + RINOK(Seek2(offset)) } HRESULT res = ReadStream_FALSE(Stream, data, size); if (res == S_OK) @@ -352,10 +351,10 @@ // Fixed archive uses only footer UInt64 startPos; - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &startPos)); + RINOK(InStream_GetPos(Stream, startPos)) _startOffset = startPos; Byte header[kHeaderSize]; - RINOK(ReadStream_FALSE(Stream, header, kHeaderSize)); + RINOK(ReadStream_FALSE(Stream, header, kHeaderSize)) bool headerIsOK = Footer.Parse(header); _size = Footer.CurrentSize; @@ -372,15 +371,15 @@ } UInt64 fileSize; - RINOK(Stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(Stream, fileSize)) if (fileSize < kHeaderSize) return S_FALSE; const UInt32 kDynSize = 1024; Byte buf[kDynSize]; - RINOK(Stream->Seek(fileSize - kHeaderSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(Stream, buf, kHeaderSize)); + RINOK(InStream_SeekSet(Stream, fileSize - kHeaderSize)) + RINOK(ReadStream_FALSE(Stream, buf, kHeaderSize)) if (!headerIsOK) { @@ -389,6 +388,7 @@ _size = Footer.CurrentSize; if (Footer.ThereIsDynamic()) return S_FALSE; // we can't open Dynamic Archive backward. + // fixed archive _posInArcLimit = Footer.CurrentSize; _phySize = Footer.CurrentSize + kHeaderSize; _startOffset = fileSize - kHeaderSize - Footer.CurrentSize; @@ -407,7 +407,7 @@ _phySize = fileSize - _startOffset; } - RINOK(ReadPhy(Footer.DataOffset, buf, kDynSize)); + RINOK(ReadPhy(Footer.DataOffset, buf, kDynSize)) if (!Dyn.Parse(buf)) return S_FALSE; @@ -430,7 +430,7 @@ unsigned len = (locator.DataLen >> 1); { wchar_t *s = tempString.GetBuf(len); - RINOK(ReadPhy(locator.DataOffset, nameBuf, locator.DataLen)); + RINOK(ReadPhy(locator.DataOffset, nameBuf, locator.DataLen)) unsigned j; for (j = 0; j < len; j++) { @@ -467,7 +467,7 @@ while ((UInt32)Bat.Size() < Dyn.NumBlocks) { - RINOK(ReadPhy(Dyn.TableOffset + (UInt64)Bat.Size() * 4, buf, kSectorSize)); + RINOK(ReadPhy(Dyn.TableOffset + (UInt64)Bat.Size() * 4, buf, kSectorSize)) UpdatePhySize(Dyn.TableOffset + kSectorSize); for (UInt32 j = 0; j < kSectorSize; j += 4) { @@ -495,7 +495,7 @@ return S_OK; } - RINOK(ReadPhy(_phySize, buf, kHeaderSize)); + RINOK(ReadPhy(_phySize, buf, kHeaderSize)) if (memcmp(header, buf, kHeaderSize) == 0) { _posInArcLimit = _phySize; @@ -511,7 +511,7 @@ for (i = 0; i < kSectorSize && buf[i] == 0; i++); if (i == kSectorSize) { - RINOK(ReadPhy(_phySize + kSectorSize, buf, kHeaderSize)); + RINOK(ReadPhy(_phySize + kSectorSize, buf, kHeaderSize)) if (memcmp(header, buf, kHeaderSize) == 0) { _phySize += kSectorSize; @@ -527,7 +527,7 @@ return S_OK; } -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -540,9 +540,40 @@ } if (size == 0) return S_OK; - UInt32 blockIndex = (UInt32)(_virtPos >> Dyn.BlockSizeLog); - UInt32 blockSectIndex = Bat[blockIndex]; - UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; + + if (Footer.IsFixed()) + { + if (_virtPos > _posInArcLimit) + return S_FALSE; + { + const UInt64 rem = _posInArcLimit - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + HRESULT res = S_OK; + if (_virtPos != _posInArc) + { + _posInArc = _virtPos; + res = Seek2(_virtPos); + } + if (res == S_OK) + { + UInt32 processedSize2 = 0; + res = Stream->Read(data, size, &processedSize2); + if (processedSize) + *processedSize = processedSize2; + _posInArc += processedSize2; + } + if (res != S_OK) + Reset_PosInArc(); + return res; + } + + const UInt32 blockIndex = (UInt32)(_virtPos >> Dyn.BlockSizeLog); + if (blockIndex >= Bat.Size()) + return E_FAIL; // it's some unexpected case + const UInt32 blockSectIndex = Bat[blockIndex]; + const UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); size = MyMin(blockSize - offsetInBlock, size); @@ -551,7 +582,7 @@ { if (ParentStream) { - RINOK(ParentStream->Seek(_virtPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(ParentStream, _virtPos)) res = ParentStream->Read(data, size, &size); } else @@ -559,23 +590,23 @@ } else { - UInt64 newPos = (UInt64)blockSectIndex << kSectorSize_Log; + const UInt64 newPos = (UInt64)blockSectIndex << kSectorSize_Log; if (BitMapTag != blockIndex) { - RINOK(ReadPhy(newPos, BitMap, (UInt32)BitMap.Size())); + RINOK(ReadPhy(newPos, BitMap, (UInt32)BitMap.Size())) BitMapTag = blockIndex; } - RINOK(ReadPhy(newPos + BitMap.Size() + offsetInBlock, data, size)); + RINOK(ReadPhy(newPos + BitMap.Size() + offsetInBlock, data, size)) for (UInt32 cur = 0; cur < size;) { const UInt32 rem = MyMin(0x200 - (offsetInBlock & 0x1FF), size - cur); - UInt32 bmi = offsetInBlock >> kSectorSize_Log; + const UInt32 bmi = offsetInBlock >> kSectorSize_Log; if (((BitMap[bmi >> 3] >> (7 - (bmi & 7))) & 1) == 0) { if (ParentStream) { - RINOK(ParentStream->Seek(_virtPos + cur, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(ParentStream, (Byte *)data + cur, rem)); + RINOK(InStream_SeekSet(ParentStream, _virtPos + cur)) + RINOK(ReadStream_FALSE(ParentStream, (Byte *)data + cur, rem)) } else { @@ -651,25 +682,15 @@ { for (int i = 24; i >= 0; i -= 8) { - Byte b = (Byte)((val >> i) & 0xFF); + const Byte b = (Byte)((val >> i) & 0xFF); if (b < 0x20 || b > 0x7F) break; - *dest++ = b; + *dest++ = (char)b; } *dest = 0; } -static void ConvertByteToHex(unsigned value, char *s) -{ - for (int i = 0; i < 2; i++) - { - unsigned t = value & 0xF; - value >>= 4; - s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -705,7 +726,7 @@ res.Trim(); res.Add_Space(); res.Add_UInt32(Footer.CreatorVersion >> 16); - res += '.'; + res.Add_Dot(); res.Add_UInt32(Footer.CreatorVersion & 0xFFFF); prop = res; break; @@ -724,10 +745,8 @@ } case kpidId: { - char s[32 + 4]; - for (int i = 0; i < 16; i++) - ConvertByteToHex(Footer.Id[i], s + i * 2); - s[32] = 0; + char s[sizeof(Footer.Id) * 2 + 2]; + ConvertDataToHex_Upper(s, Footer.Id, sizeof(Footer.Id)); prop = s; break; } @@ -776,7 +795,7 @@ if (level > (1 << 12)) // Maybe we need to increase that limit return S_FALSE; - RINOK(Open3()); + RINOK(Open3()) NumLevels = 1; if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0) @@ -800,9 +819,10 @@ Dyn.RelativeNameWasUsed = useRelative; - CMyComPtr openVolumeCallback; - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openArchiveCallback) + if (openVolumeCallback) { CMyComPtr nextStream; @@ -881,13 +901,13 @@ // _unexpectedEnd = false; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { CloseAtError(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -912,25 +932,25 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; if (Footer.IsFixed()) { - CLimitedInStream *streamSpec = new CLimitedInStream; - CMyComPtr streamTemp = streamSpec; + CMyComPtr2 streamSpec; + streamSpec.Create_if_Empty(); streamSpec->SetStream(Stream); // fixme : check (startOffset = 0) streamSpec->InitAndSeek(_startOffset, Footer.CurrentSize); - RINOK(streamSpec->SeekToStart()); - *stream = streamTemp.Detach(); + RINOK(streamSpec->SeekToStart()) + *stream = streamSpec.Detach(); return S_OK; } if (!Footer.ThereIsDynamic() || !AreParentsOK()) return S_FALSE; CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); + RINOK(InitAndSeek()) *stream = streamTemp.Detach(); return S_OK; COM_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/VhdxHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdxHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/VhdxHandler.cpp 2021-12-29 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VhdxHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -7,6 +7,8 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringToInt.h" #include "../../Common/MyBuffer.h" #include "../../Windows/PropVariant.h" @@ -20,8 +22,8 @@ #define Get32(p) GetUi32(p) #define Get64(p) GetUi64(p) -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); -#define G64(_offs_, dest) dest = Get64(p + (_offs_)); +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) using namespace NWindows; @@ -31,9 +33,10 @@ // CRC-32C (Castagnoli) : reversed for poly 0x1EDC6F41 #define k_Crc32c_Poly 0x82f63b78 +MY_ALIGN(64) static UInt32 g_Crc32c_Table[256]; -static void MY_FAST_CALL Crc32c_GenerateTable() +static void Z7_FASTCALL Crc32c_GenerateTable() { UInt32 i; for (i = 0; i < 256; i++) @@ -46,13 +49,24 @@ } } -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); #define CRC32C_INIT_VAL 0xFFFFFFFF -static UInt32 MY_FAST_CALL Crc32c_Calc(const void *data, size_t size) +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +// UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); +static UInt32 Z7_FASTCALL CrcUpdateT1_vhdx(UInt32 v, const void *data, size_t size, const UInt32 *table) { - return CrcUpdateT1(CRC32C_INIT_VAL, data, size, g_Crc32c_Table) ^ CRC32C_INIT_VAL; + const Byte *p = (const Byte *)data; + const Byte *pEnd = p + size; + for (; p != pEnd; p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +static UInt32 Z7_FASTCALL Crc32c_Calc(const void *data, size_t size) +{ + return CrcUpdateT1_vhdx(CRC32C_INIT_VAL, data, size, g_Crc32c_Table) ^ CRC32C_INIT_VAL; } EXTERN_C_END @@ -61,12 +75,11 @@ namespace NArchive { namespace NVhdx { -static struct C_CRC32c_TableInit { C_CRC32c_TableInit() { Crc32c_GenerateTable(); } } g__CRC32c_TableInit; +static struct C_CRC32c_TableInit { C_CRC32c_TableInit() { Crc32c_GenerateTable(); } } g_CRC32c_TableInit; -#define SIGNATURE { 'v', 'h', 'd', 'x', 'f', 'i', 'l', 'e' } - static const unsigned kSignatureSize = 8; -static const Byte kSignature[kSignatureSize] = SIGNATURE; +static const Byte kSignature[kSignatureSize] = + { 'v', 'h', 'd', 'x', 'f', 'i', 'l', 'e' }; static const unsigned kBitmapSize_Log = 20; static const size_t kBitmapSize = (size_t)1 << kBitmapSize_Log; @@ -81,31 +94,13 @@ } -#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10)))) - -static void AddByteToHex2(unsigned val, UString &s) -{ - unsigned t; - t = val >> 4; - s += ValToHex(t); - t = val & 0xF; - s += ValToHex(t); -} - - -static int HexToVal(const wchar_t c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'z') return c - 'a' + 10; - if (c >= 'A' && c <= 'Z') return c - 'A' + 10; - return -1; -} +Z7_FORCE_INLINE static int DecodeFrom2HexChars(const wchar_t *s) { - const int v0 = HexToVal(s[0]); if (v0 < 0) return -1; - const int v1 = HexToVal(s[1]); if (v1 < 0) return -1; - return ((unsigned)v0 << 4) | (unsigned)v1; + unsigned v0 = (unsigned)s[0]; Z7_PARSE_HEX_DIGIT(v0, return -1;) + unsigned v1 = (unsigned)s[1]; Z7_PARSE_HEX_DIGIT(v1, return -1;) + return (int)((v0 << 4) | v1); } @@ -151,8 +146,9 @@ void CGuid::AddHexToString(UString &s) const { - for (unsigned i = 0; i < 16; i++) - AddByteToHex2(Data[i], s); + char temp[sizeof(Data) * 2 + 2]; + ConvertDataToHex_Lower(temp, Data, sizeof(Data)); + s += temp; } @@ -183,7 +179,7 @@ if (!Guids[i].IsEqualTo(h.Guids[i])) return false; return true; - }; + } bool Parse(Byte *p); }; @@ -195,7 +191,7 @@ if (Get32(p) != 0x64616568) // "head" return false; const UInt32 crc = Get32(p + 4); - SetUi32(p + 4, 0); + SetUi32(p + 4, 0) if (Crc32c_Calc(p, kHeader2Size) != crc) return false; G64(8, SequenceNumber); @@ -264,7 +260,7 @@ }; -static const unsigned kRegionSize = 1 << 16; +static const size_t kRegionSize = 1 << 16; static const unsigned kNumRegionEntriesMax = (1 << 11) - 1; bool CRegion::Parse(Byte *p) @@ -277,7 +273,7 @@ if (Get32(p) != 0x69676572) // "regi" return false; const UInt32 crc = Get32(p + 4); - SetUi32(p + 4, 0); + SetUi32(p + 4, 0) const UInt32 crc_calced = Crc32c_Calc(p, kRegionSize); if (crc_calced != crc) return false; @@ -372,7 +368,7 @@ if ((Flags1 & 3) != 0) // Reserved2 return false; return true; -}; +} struct CParentPair @@ -406,7 +402,7 @@ { const CParentPair &pair = ParentPairs[i]; if (pair.Key.IsEqualTo(name)) - return i; + return (int)i; } return -1; } @@ -628,7 +624,7 @@ -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { UInt64 _phySize; @@ -657,11 +653,11 @@ CMyComPtr ParentStream; CHandler *Parent; UString _errorMessage; - UString _Creator; + UString _creator; bool _nonEmptyLog; bool _isDataContiguous; - // bool _BatOverlap; + // bool _batOverlap; CGuid _parentGuid; bool _parentGuid_IsDefined; @@ -756,15 +752,15 @@ bool CheckBat(); HRESULT Open3(); - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) Z7_override; HRESULT OpenParent(IArchiveOpenCallback *openArchiveCallback, bool &_parentFileWasOpen); - virtual void CloseAtError(); + virtual void CloseAtError() Z7_override; public: - INTERFACE_IInArchive_Img(;) + Z7_IFACE_COM7_IMP(IInArchive_Img) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) CHandler(): _child(NULL), @@ -777,7 +773,7 @@ HRESULT CHandler::Seek2(UInt64 offset) { - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, offset); } @@ -833,8 +829,8 @@ #define SB_BLOCK_NOT_PRESENT 0 #define SB_BLOCK_PRESENT 6 -#define BAT_GET_OFFSET(v) ((v) & ~(UInt64)0xFFFFF); -#define BAT_GET_STATE(v) ((UInt32)(v) & 7); +#define BAT_GET_OFFSET(v) ((v) & ~(UInt64)0xFFFFF) +#define BAT_GET_STATE(v) ((UInt32)(v) & 7) /* The log contains only updates to metadata, bat and region tables The log doesn't contain updates to start header, and 2 headers (first 192 KB of file). @@ -1154,10 +1150,10 @@ HRESULT CHandler::Open3() { { - static const unsigned kHeaderSize = 512; // + 8 + const unsigned kHeaderSize = 512; // + 8 Byte header[kHeaderSize]; - RINOK(Read_FALSE(header, kHeaderSize)); + RINOK(Read_FALSE(header, kHeaderSize)) if (memcmp(header, kSignature, kSignatureSize) != 0) return S_FALSE; @@ -1168,7 +1164,7 @@ const wchar_t c = Get16(p + i); if (c < 0x20 || c > 0x7F) break; - _Creator += c; + _creator += c; } } @@ -1178,8 +1174,8 @@ Byte header[kHeader2Size]; for (unsigned i = 0; i < 2; i++) { - RINOK(Seek2((1 << 16) * (1 + i))); - RINOK(Read_FALSE(header, kHeader2Size)); + RINOK(Seek2((1 << 16) * (1 + i))) + RINOK(Read_FALSE(header, kHeader2Size)) bool headerIsOK = headers[i].Parse(header); if (!headerIsOK) return S_FALSE; @@ -1233,8 +1229,8 @@ { CByteBuffer temp; temp.Alloc(kRegionSize * 2); - RINOK(Seek2((1 << 16) * 3)); - RINOK(Read_FALSE(temp, kRegionSize * 2)); + RINOK(Seek2((1 << 16) * 3)) + RINOK(Read_FALSE(temp, kRegionSize * 2)) unsigned numTables = 1; if (memcmp(temp, temp + kRegionSize, kRegionSize) != 0) { @@ -1249,7 +1245,7 @@ if (regions[i].Parse(temp)) { if (correctRegionIndex < 0) - correctRegionIndex = i; + correctRegionIndex = (int)i; } else { @@ -1281,8 +1277,8 @@ // static const kMetaTableSize = 1 << 16; CByteBuffer temp; { - RINOK(Seek2(e.Offset)); - RINOK(ReadToBuf_FALSE(temp, e.Len)); + RINOK(Seek2(e.Offset)) + RINOK(ReadToBuf_FALSE(temp, e.Len)) } if (!Meta.Parse(temp, temp.Size())) return S_FALSE; @@ -1297,15 +1293,15 @@ return S_FALSE; // UpdatePhySize(e.GetEndPos()); { - RINOK(Seek2(e.Offset)); - RINOK(ReadToBuf_FALSE(Bat.Data, e.Len)); + RINOK(Seek2(e.Offset)) + RINOK(ReadToBuf_FALSE(Bat.Data, e.Len)) } if (!ParseBat()) return S_FALSE; if (!CheckBat()) { AddErrorMessage("BAT overlap"); - // _BatOverlap = true; + // _batOverlap = true; // return S_FALSE; } } @@ -1327,13 +1323,13 @@ { // absolute paths for parent stream can be rejected later in client callback // the order of check by specification: - static const char * const g_ParentKeys[] = + const char * const g_ParentKeys[] = { "relative_path" // "..\..\path2\sub3\parent.vhdx" , "volume_path" // "\\?\Volume{26A21BDA-A627-11D7-9931-806E6F6E6963}\path2\sub3\parent.vhdx") , "absolute_win32_path" // "d:\path2\sub3\parent.vhdx" }; - for (unsigned i = 0; i < ARRAY_SIZE(g_ParentKeys); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ParentKeys); i++) { const int index = Meta.FindParentKey(g_ParentKeys[i]); if (index < 0) @@ -1368,7 +1364,7 @@ // _posInArc = 0; // Reset_PosInArc(); - // RINOK(Stream->Seek(0, STREAM_SEEK_SET, NULL)); + // RINOK(InStream_SeekToBegin(Stream)) return S_OK; } @@ -1384,7 +1380,7 @@ } } g_Counter; */ -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { // g_NumCalls++; if (processedSize) @@ -1489,7 +1485,7 @@ return S_FALSE; // if (ParentStream) { - RINOK(ParentStream->Seek(_virtPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(ParentStream, _virtPos)) size_t processed = size; res = ReadStream(ParentStream, (Byte *)data, &processed); size = (UInt32)processed; @@ -1566,7 +1562,7 @@ static void AddComment_Bool(UString &s, const char *name, bool val) { AddComment_Name(s, name); - s += val ? "+" : "-"; + s.Add_Char(val ? '+' : '-'); s.Add_LF(); } @@ -1668,7 +1664,7 @@ -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -1735,8 +1731,8 @@ } case kpidCreatorApp: { - if (!_Creator.IsEmpty()) - prop = _Creator; + if (!_creator.IsEmpty()) + prop = _creator; break; } case kpidId: @@ -1808,7 +1804,7 @@ if (_level >= (1 << 20)) return S_FALSE; - RINOK(Open3()); + RINOK(Open3()) NumLevels = 1; PackSize_Total = GetPackSize(); @@ -1882,12 +1878,11 @@ HRESULT CHandler::OpenParent(IArchiveOpenCallback *openArchiveCallback, bool &_parentFileWasOpen) { _parentFileWasOpen = false; - CMyComPtr openVolumeCallback; - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openArchiveCallback) if (!openVolumeCallback) return S_FALSE; - { CMyComPtr nextStream; HRESULT res = S_FALSE; @@ -1961,7 +1956,7 @@ UInt64 numBytes = (UInt64)NumUsedBitMaps << kBitmapSize_Log; if (openArchiveCallback && numBytes != 0) { - RINOK(openArchiveCallback->SetTotal(NULL, &numBytes)); + RINOK(openArchiveCallback->SetTotal(NULL, &numBytes)) } numBytes = 0; for (size_t i = ChunkRatio; i < TotalBatEntries; i += ChunkRatio + 1) @@ -1975,12 +1970,12 @@ { if (openArchiveCallback) { - RINOK(openArchiveCallback->SetCompleted(NULL, &numBytes)); + RINOK(openArchiveCallback->SetCompleted(NULL, &numBytes)) } numBytes += kBitmapSize; buf.Alloc(kBitmapSize); - RINOK(Seek2(offset)); - RINOK(Read_FALSE(buf, kBitmapSize)); + RINOK(Seek2(offset)) + RINOK(Read_FALSE(buf, kBitmapSize)) /* for (unsigned i = 0; i < (1 << 20); i+=4) { @@ -2018,11 +2013,11 @@ Parent = NULL; ParentStream.Release(); _errorMessage.Empty(); - _Creator.Empty(); + _creator.Empty(); _nonEmptyLog = false; _parentGuid_IsDefined = false; _isDataContiguous = false; - // _BatOverlap = false; + // _batOverlap = false; ParentNames.Clear(); ParentName_Used.Empty(); @@ -2039,14 +2034,14 @@ _isCyclic_or_CyclicParent = false; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { CloseAtError(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -2064,7 +2059,7 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN *stream = NULL; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/VmdkHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VmdkHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/VmdkHandler.cpp 2022-02-15 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/VmdkHandler.cpp 2025-06-16 09:00:00.000000000 +0000 @@ -31,14 +31,12 @@ #define Get32(p) GetUi32(p) #define Get64(p) GetUi64(p) -#define LE_16(offs, dest) dest = Get16(p + (offs)); -#define LE_32(offs, dest) dest = Get32(p + (offs)); -#define LE_64(offs, dest) dest = Get64(p + (offs)); +#define LE_16(offs, dest) dest = Get16(p + (offs)) +#define LE_32(offs, dest) dest = Get32(p + (offs)) +#define LE_64(offs, dest) dest = Get64(p + (offs)) -#define SIGNATURE { 'K', 'D', 'M', 'V' } - -static const Byte k_Signature[] = SIGNATURE; +static const Byte k_Signature[] = { 'K', 'D', 'M', 'V' }; static const UInt32 k_Flags_NL = (UInt32)1 << 0; // static const UInt32 k_Flags_RGD = (UInt32)1 << 1; @@ -65,10 +63,10 @@ UInt64 gdOffset; UInt64 overHead; - bool Is_NL() const { return (flags & k_Flags_NL) != 0; }; - bool Is_ZeroGrain() const { return (flags & k_Flags_ZeroGrain) != 0; }; - bool Is_Compressed() const { return (flags & k_Flags_Compressed) != 0; }; - bool Is_Marker() const { return (flags & k_Flags_Marker) != 0; }; + bool Is_NL() const { return (flags & k_Flags_NL) != 0; } + bool Is_ZeroGrain() const { return (flags & k_Flags_ZeroGrain) != 0; } + bool Is_Compressed() const { return (flags & k_Flags_Compressed) != 0; } + bool Is_Marker() const { return (flags & k_Flags_Marker) != 0; } bool Parse(const Byte *p); @@ -165,7 +163,7 @@ static const char *GetNextWord(const char *s, AString &dest) { dest.Empty(); - SKIP_SPACES(s); + SKIP_SPACES(s) const char *start = s; for (;; s++) { @@ -180,7 +178,7 @@ static const char *GetNextNumber(const char *s, UInt64 &val) { - SKIP_SPACES(s); + SKIP_SPACES(s) if (*s == 0) return s; const char *end; @@ -204,9 +202,12 @@ // PartitionUUID // DeviceIdentifier - bool IsType_ZERO() const { return Type == "ZERO"; } - // bool IsType_FLAT() const { return Type == "FLAT"; } - bool IsType_Flat() const { return Type == "FLAT" || Type == "VMFS" || Type == "VMFSRAW"; } + bool IsType_ZERO() const { return Type.IsEqualTo("ZERO"); } + // bool IsType_FLAT() const { return Type.IsEqualTo("FLAT"); } + bool IsType_Flat() const + { return Type.IsEqualTo("FLAT") + || Type.IsEqualTo("VMFS") + || Type.IsEqualTo("VMFSRAW"); } bool Parse(const char *s); }; @@ -228,7 +229,7 @@ if (Type.IsEmpty()) return false; - SKIP_SPACES(s); + SKIP_SPACES(s) if (IsType_ZERO()) return (*s == 0); @@ -243,7 +244,7 @@ FileName.SetFrom(s, (unsigned)(s2 - s)); s = s2 + 1; } - SKIP_SPACES(s); + SKIP_SPACES(s) if (*s == 0) return true; @@ -298,7 +299,7 @@ for (;;) { - char c = 0; + Byte c = 0; if (size != 0) { size--; @@ -369,7 +370,7 @@ UInt64 GetEndOffset() const { return StartOffset + NumBytes; } - bool IsVmdk() const { return !IsZero && !IsFlat; }; + bool IsVmdk() const { return !IsZero && !IsFlat; } // if (IsOK && IsVmdk()), then VMDK header of this extent was read CExtent(): @@ -403,7 +404,7 @@ HRESULT Seek(UInt64 offset) { PosInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, offset); } HRESULT InitAndSeek() @@ -422,7 +423,7 @@ }; -class CHandler: public CHandlerImg +Z7_class_CHandler_final: public CHandlerImg { bool _isArc; bool _unsupported; @@ -461,17 +462,17 @@ _virtPos = 0; } - virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); - virtual void CloseAtError(); + virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; + virtual void CloseAtError() Z7_override; public: - INTERFACE_IInArchive_Img(;) + Z7_IFACE_COM7_IMP(IInArchive_Img) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) }; -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -569,7 +570,7 @@ UInt64 offset = extent.FlatOffset + vir; if (offset != extent.PosInArc) { - RINOK(extent.Seek(offset)); + RINOK(extent.Seek(offset)) } UInt32 size2 = 0; HRESULT res = extent.Stream->Read(data, size, &size2); @@ -636,13 +637,13 @@ if (offset != extent.PosInArc) { // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); - RINOK(extent.Seek(offset)); + RINOK(extent.Seek(offset)) } const size_t kStartSize = 1 << 9; { size_t curSize = kStartSize; - RINOK(extent.Read(_cacheCompressed, &curSize)); + RINOK(extent.Read(_cacheCompressed, &curSize)) // _stream_PackSize += curSize; if (curSize != kStartSize) return S_FALSE; @@ -664,7 +665,7 @@ return S_FALSE; size_t curSize = dataSize2 - kStartSize; const size_t curSize2 = curSize; - RINOK(extent.Read(_cacheCompressed + kStartSize, &curSize)); + RINOK(extent.Read(_cacheCompressed + kStartSize, &curSize)) // _stream_PackSize += curSize; if (curSize != curSize2) return S_FALSE; @@ -680,8 +681,8 @@ _bufOutStreamSpec->Init(_cache, clusterSize); // Do we need to use smaller block than clusterSize for last cluster? - UInt64 blockSize64 = clusterSize; - HRESULT res = _zlibDecoderSpec->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); + const UInt64 blockSize64 = clusterSize; + HRESULT res = _zlibDecoder->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); /* if (_bufOutStreamSpec->GetPos() != clusterSize) @@ -699,7 +700,7 @@ res = S_FALSE; } - RINOK(res); + RINOK(res) _cacheCluster = cluster; _cacheExtent = extentIndex; @@ -718,7 +719,7 @@ if (offset != extent.PosInArc) { // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); - RINOK(extent.Seek(offset)); + RINOK(extent.Seek(offset)) } UInt32 size2 = 0; HRESULT res = extent.Stream->Read(data, size, &size2); @@ -762,6 +763,7 @@ static const Byte kArcProps[] = { kpidNumVolumes, + kpidTotalPhySize, kpidMethod, kpidClusterSize, kpidHeadersSize, @@ -774,7 +776,7 @@ IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -794,6 +796,17 @@ { case kpidMainSubfile: prop = (UInt32)0; break; case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidTotalPhySize: + { + UInt64 sum = _phySize; + if (_isMultiVol) + { + FOR_VECTOR (i, _extents) + sum += _extents[i].PhySize; + } + prop = sum; + break; + } case kpidClusterSize: prop = (UInt32)((UInt32)1 << _clusterBitsMax); break; case kpidHeadersSize: if (e) prop = (e->h.overHead << 9); break; case kpidMethod: @@ -805,7 +818,7 @@ bool zlib = false; bool marker = false; - int algo = -1; + Int32 algo = -1; FOR_VECTOR (i, _extents) { @@ -819,7 +832,7 @@ { if (h.algo == 1) zlib = true; - else if (algo != (int)h.algo) + else if (algo != h.algo) { s.Add_Space_if_NotEmpty(); s.Add_UInt32(h.algo); @@ -896,7 +909,7 @@ case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod; if (_headerError) v |= kpv_ErrorFlags_HeadersError; @@ -913,7 +926,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -962,9 +975,9 @@ HRESULT CExtent::ReadForHeader(IInStream *stream, UInt64 sector, void *data, size_t numSectors) { sector <<= 9; - RINOK(stream->Seek(sector, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, sector)) size_t size = numSectors << 9; - RINOK(ReadStream_FALSE(stream, data, size)); + RINOK(ReadStream_FALSE(stream, data, size)) UInt64 end = sector + size; if (PhySize < end) PhySize = end; @@ -987,7 +1000,7 @@ const unsigned kSectoreSize = 512; Byte buf[kSectoreSize]; size_t headerSize = kSectoreSize; - RINOK(ReadStream(stream, buf, &headerSize)); + RINOK(ReadStream(stream, buf, &headerSize)) if (headerSize < sizeof(k_Signature)) return S_FALSE; @@ -1003,13 +1016,13 @@ return S_FALSE; UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) if (endPos > (1 << 20)) return S_FALSE; const size_t numBytes = (size_t)endPos; _descriptorBuf.Alloc(numBytes); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _descriptorBuf, numBytes)); + RINOK(InStream_SeekToBegin(stream)) + RINOK(ReadStream_FALSE(stream, _descriptorBuf, numBytes)) if (!_descriptor.Parse(_descriptorBuf, _descriptorBuf.Size())) return S_FALSE; @@ -1046,7 +1059,7 @@ if (_descriptor.Extents.Size() > 1) { const UInt64 numFiles = _descriptor.Extents.Size(); - RINOK(openCallback->SetTotal(&numFiles, NULL)); + RINOK(openCallback->SetTotal(&numFiles, NULL)) } } @@ -1117,7 +1130,7 @@ stream = nextStream; headerSize = kSectoreSize; - RINOK(ReadStream(stream, buf, &headerSize)); + RINOK(ReadStream(stream, buf, &headerSize)) if (headerSize != kSectoreSize) continue; @@ -1176,7 +1189,7 @@ _needDeflate = false; _clusterBitsMax = 0; - unsigned numOKs = 0; + // unsigned numOKs = 0; unsigned numUnsupported = 0; FOR_VECTOR (i, _extents) @@ -1186,7 +1199,7 @@ numUnsupported++; if (!e.IsOK) continue; - numOKs++; + // numOKs++; if (e.IsVmdk()) { if (e.NeedDeflate) @@ -1212,7 +1225,7 @@ h.descriptorSize > (1 << 10)) return S_FALSE; DescriptorBuf.Alloc((size_t)h.descriptorSize << 9); - RINOK(ReadForHeader(stream, h.descriptorOffset, DescriptorBuf, (size_t)h.descriptorSize)); + RINOK(ReadForHeader(stream, h.descriptorOffset, DescriptorBuf, (size_t)h.descriptorSize)) if (h.descriptorOffset == 1 && h.Is_Marker() && Get64(DescriptorBuf) == 0) { // We check data as end marker. @@ -1231,7 +1244,7 @@ { // Grain Dir is at end of file UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) if ((endPos & 511) != 0) return S_FALSE; @@ -1239,8 +1252,8 @@ Byte buf2[kEndSize]; if (endPos < kEndSize) return S_FALSE; - RINOK(stream->Seek(endPos - kEndSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf2, kEndSize)); + RINOK(InStream_SeekSet(stream, endPos - kEndSize)) + RINOK(ReadStream_FALSE(stream, buf2, kEndSize)) CHeader h2; if (!h2.Parse(buf2 + 512)) @@ -1260,7 +1273,7 @@ PhySize = endPos; } - int grainSize_Log = GetLog(h.grainSize); + const int grainSize_Log = GetLog(h.grainSize); if (grainSize_Log < 3 || grainSize_Log > 30 - 9) // grain size must be >= 4 KB return S_FALSE; if (h.capacity >= ((UInt64)1 << (63 - 9))) @@ -1269,7 +1282,7 @@ return S_FALSE; IsArc = true; - ClusterBits = (9 + grainSize_Log); + ClusterBits = (9 + (unsigned)grainSize_Log); VirtSize = h.capacity << 9; NeedDeflate = (h.algo >= 1); @@ -1281,7 +1294,7 @@ } { - UInt64 overHeadBytes = h.overHead << 9; + const UInt64 overHeadBytes = h.overHead << 9; if (PhySize < overHeadBytes) PhySize = overHeadBytes; } @@ -1290,8 +1303,8 @@ if (h.Is_ZeroGrain()) ZeroSector = 1; - const UInt64 numSectorsPerGde = (UInt64)1 << (grainSize_Log + k_NumMidBits); - const UInt64 numGdeEntries = (h.capacity + numSectorsPerGde - 1) >> (grainSize_Log + k_NumMidBits); + const UInt64 numSectorsPerGde = (UInt64)1 << ((unsigned)grainSize_Log + k_NumMidBits); + const UInt64 numGdeEntries = (h.capacity + numSectorsPerGde - 1) >> ((unsigned)grainSize_Log + k_NumMidBits); CByteBuffer table; if (numGdeEntries != 0) @@ -1320,7 +1333,7 @@ } } - RINOK(ReadForHeader(stream, h.gdOffset, table, numSectors)); + RINOK(ReadForHeader(stream, h.gdOffset, table, numSectors)) } const size_t clusterSize = (size_t)1 << ClusterBits; @@ -1332,12 +1345,12 @@ complexity += (UInt64)numGdeEntries << (k_NumMidBits + 2); { const UInt64 numVols2 = numVols; - RINOK(openCallback->SetTotal((numVols == 1) ? NULL : &numVols2, &complexity)); + RINOK(openCallback->SetTotal((numVols == 1) ? NULL : &numVols2, &complexity)) } if (numVols != 1) { const UInt64 volIndex2 = volIndex; - RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &complexityStart)); + RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &complexityStart)) } } @@ -1360,7 +1373,7 @@ { const UInt64 comp = complexityStart + ((UInt64)i << (k_NumMidBits + 2)); const UInt64 volIndex2 = volIndex; - RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &comp)); + RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &comp)) numProcessed_Prev = i; } @@ -1380,7 +1393,7 @@ } buf.Alloc(k_NumMidItems * 4); - RINOK(ReadForHeader(stream, v, buf, k_NumSectors)); + RINOK(ReadForHeader(stream, v, buf, k_NumSectors)) } for (size_t k = 0; k < k_NumMidItems; k++) @@ -1427,7 +1440,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; @@ -1458,10 +1471,10 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) { COM_TRY_BEGIN - *stream = 0; + *stream = NULL; if (_unsupported) return S_FALSE; @@ -1496,7 +1509,7 @@ FOR_VECTOR (i, _extents) { - RINOK(_extents[i].InitAndSeek()); + RINOK(_extents[i].InitAndSeek()) } CMyComPtr streamTemp = this; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.cpp 2022-03-30 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.cpp 2024-01-01 09:00:00.000000000 +0000 @@ -95,7 +95,7 @@ } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -124,7 +124,7 @@ const CImageInfo &image2 = xml.Images[i]; if (image2.CTimeDefined) if (index < 0 || ::CompareFileTime(&image2.CTime, &xml.Images[index].CTime) < 0) - index = i; + index = (int)i; } if (index >= 0) prop = xml.Images[index].CTime; @@ -141,7 +141,7 @@ const CImageInfo &image2 = xml.Images[i]; if (image2.MTimeDefined) if (index < 0 || ::CompareFileTime(&image2.MTime, &xml.Images[index].MTime) > 0) - index = i; + index = (int)i; } if (index >= 0) prop = xml.Images[index].MTime; @@ -170,11 +170,11 @@ AString res; res.Add_UInt32(ver1); - res += '.'; + res.Add_Dot(); res.Add_UInt32(ver2); if (ver3 != 0) { - res += '.'; + res.Add_Dot(); res.Add_UInt32(ver3); } prop = res; @@ -245,7 +245,7 @@ if (h.PartNumber != 1) { s.Add_UInt32(h.PartNumber); - s += '.'; + s.Add_Dot(); } s += "swm"; prop = s; @@ -267,7 +267,7 @@ { const CHeader &header = _volumes[_xmls[i].VolIndex].Header; unsigned method = header.GetMethod(); - if (method < ARRAY_SIZE(k_Methods)) + if (method < Z7_ARRAY_SIZE(k_Methods)) methodMask |= ((UInt32)1 << method); else methodUnknown = method; @@ -280,7 +280,7 @@ unsigned numMethods = 0; - for (unsigned i = 0; i < ARRAY_SIZE(k_Methods); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Methods); i++) { if (methodMask & ((UInt32)1 << i)) { @@ -299,7 +299,7 @@ if (numMethods == 1 && chunkSizeBits != 0) { - res += ':'; + res.Add_Colon(); res.Add_UInt32((UInt32)chunkSizeBits); } @@ -365,8 +365,8 @@ { char temp[32]; - if ((unsigned)method < ARRAY_SIZE(k_Methods)) - strcpy(temp, k_Methods[(unsigned)method]); + if ((unsigned)method < Z7_ARRAY_SIZE(k_Methods)) + MyStringCopy(temp, k_Methods[(unsigned)method]); else ConvertUInt32ToString((UInt32)(unsigned)method, temp); @@ -382,7 +382,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -423,7 +423,7 @@ else */ AString s (FILES_DIR_NAME STRING_PATH_SEPARATOR); - s.Add_UInt32(item.StreamIndex); + s.Add_UInt32((UInt32)(Int32)item.StreamIndex); prop = s; } break; @@ -434,7 +434,7 @@ else { char sz[16]; - ConvertUInt32ToString(item.StreamIndex, sz); + ConvertUInt32ToString((UInt32)(Int32)item.StreamIndex, sz); /* AString s = sz; while (s.Len() < _nameLenForStreams) @@ -558,7 +558,7 @@ if (r.SolidIndex >= 0) { CSolid &ss = _db.Solids[r.SolidIndex]; - MethodToProp(ss.Method, ss.ChunkSizeBits, prop); + MethodToProp(ss.Method, (int)ss.ChunkSizeBits, prop); } } else @@ -567,8 +567,8 @@ int chunkSizeBits = -1; if (r.IsCompressed()) { - method = vol->Header.GetMethod(); - chunkSizeBits = vol->Header.ChunkSizeBits; + method = (int)vol->Header.GetMethod(); + chunkSizeBits = (int)vol->Header.ChunkSizeBits; } MethodToProp(method, chunkSizeBits, prop); } @@ -620,7 +620,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::GetRootProp(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetRootProp(PROPID propID, PROPVARIANT *value)) { // COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -670,9 +670,9 @@ return S_OK; } -STDMETHODIMP CHandler::GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { - *data = 0; + *data = NULL; *dataSize = 0; *propType = 0; if (propID == kpidNtSecure && _db.Images.Size() != 0 && _db.NumExcludededItems != 0) @@ -694,20 +694,20 @@ }; -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { - *numProps = ARRAY_SIZE(kRawProps); + *numProps = Z7_ARRAY_SIZE(kRawProps); return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) { *propID = kRawProps[index]; - *name = 0; + *name = NULL; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; @@ -722,13 +722,13 @@ if (item.Parent >= 0) { if (_db.ExludedItem != item.Parent) - *parent = _db.Items[item.Parent].IndexInSorted; + *parent = (unsigned)_db.Items[item.Parent].IndexInSorted; } else { CImage &image = _db.Images[item.ImageIndex]; if (image.VirtualRootIndex >= 0) - *parent = _db.SortedItems.Size() + _numXmlItems + image.VirtualRootIndex; + *parent = _db.SortedItems.Size() + _numXmlItems + (unsigned)image.VirtualRootIndex; } } else @@ -736,7 +736,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -842,8 +842,8 @@ { int dotPos = name.ReverseFind_Dot(); if (dotPos < 0) - dotPos = name.Len(); - _before.SetFrom(name.Ptr(), dotPos); + dotPos = (int)name.Len(); + _before.SetFrom(name.Ptr(), (unsigned)dotPos); _after = name.Ptr(dotPos); } @@ -856,7 +856,7 @@ } }; -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN @@ -963,7 +963,7 @@ numVolumes = header.NumParts; { NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) break; seqName.InitName(prop.bstrVal); @@ -971,7 +971,7 @@ } } - RINOK(_db.FillAndCheck(_volumes)); + RINOK(_db.FillAndCheck(_volumes)) int defaultImageIndex = (int)_defaultImageNumber - 1; bool showImageNumber = (_db.Images.Size() != 1 && defaultImageIndex < 0); @@ -983,8 +983,8 @@ _showImageNumber = showImageNumber; - RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber)); - RINOK(_db.ExtractReparseStreams(_volumes, callback)); + RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber)) + RINOK(_db.ExtractReparseStreams(_volumes, callback)) /* wchar_t sz[16]; @@ -1001,7 +1001,7 @@ } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _firstVolumeIndex = -1; _phySize = 0; @@ -1019,11 +1019,11 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size() + _numIgnoreItems; @@ -1048,77 +1048,73 @@ else { index -= _db.SortedItems.Size(); - if (index < (UInt32)_numXmlItems) + if (index < _numXmlItems) totalSize += _xmls[index].Data.Size(); } } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) - UInt64 currentTotalUnPacked = 0; + totalSize = 0; UInt64 currentItemUnPacked; int prevSuccessStreamIndex = -1; CUnpacker unpacker; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); for (i = 0;; i++, - currentTotalUnPacked += currentItemUnPacked) + totalSize += currentItemUnPacked) { currentItemUnPacked = 0; - lps->InSize = unpacker.TotalPacked; - lps->OutSize = currentTotalUnPacked; - - RINOK(lps->SetCur()); - + lps->OutSize = totalSize; + RINOK(lps->SetCur()) if (i >= numItems) break; UInt32 index = allFilesMode ? i : indices[i]; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (index >= _db.SortedItems.Size()) { if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) index -= _db.SortedItems.Size(); - if (index < (UInt32)_numXmlItems) + if (index < _numXmlItems) { const CByteBuffer &data = _xmls[index].Data; currentItemUnPacked = data.Size(); if (realOutStream) { - RINOK(WriteStream(realOutStream, (const Byte *)data, data.Size())); + RINOK(WriteStream(realOutStream, (const Byte *)data, data.Size())) realOutStream.Release(); } } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } const CItem &item = _db.Items[_db.SortedItems[index]]; - int streamIndex = item.StreamIndex; + const int streamIndex = item.StreamIndex; if (streamIndex < 0) { if (!item.IsDir) if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); RINOK(extractCallback->SetOperationResult(!item.IsDir && _db.ItemHasStream(item) ? NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kOK)); + NExtract::NOperationResult::kOK)) continue; } @@ -1128,17 +1124,16 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) Int32 opRes = NExtract::NOperationResult::kOK; if (streamIndex != prevSuccessStreamIndex || realOutStream) { Byte digest[kHashSize]; const CVolume &vol = _volumes[si.PartNumber]; - bool needDigest = !si.IsEmptyHash(); - - HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db, - realOutStream, progress, needDigest ? digest : NULL); + const bool needDigest = !si.IsEmptyHash() && !_disable_Sha1Check; + const HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db, + realOutStream, lps, needDigest ? digest : NULL); if (res == S_OK) { @@ -1156,7 +1151,7 @@ } realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -1164,7 +1159,7 @@ } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _db.SortedItems.Size() + _numXmlItems + @@ -1180,7 +1175,7 @@ _xmlError = false; } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { InitDefaults(); @@ -1197,18 +1192,18 @@ { // some clients write 'x' property. So we support it UInt32 level = 0; - RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)); + RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)) } else if (name.IsEqualTo("is")) { - RINOK(PROPVARIANT_to_bool(prop, _set_showImageNumber)); + RINOK(PROPVARIANT_to_bool(prop, _set_showImageNumber)) _set_use_ShowImageNumber = true; } else if (name.IsEqualTo("im")) { UInt32 image = 9; - RINOK(ParsePropToUInt32(L"", prop, image)); - _defaultImageNumber = image; + RINOK(ParsePropToUInt32(L"", prop, image)) + _defaultImageNumber = (int)image; } else if (name.IsPrefixedBy_Ascii_NoCase("mt")) { @@ -1216,13 +1211,25 @@ else if (name.IsPrefixedBy_Ascii_NoCase("memuse")) { } + else if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 1; + RINOK(ParsePropToUInt32(name, prop, crcSize)) + _disable_Sha1Check = (crcSize == 0); + } else - return E_INVALIDARG; + { + bool processed = false; + RINOK(_timeOptions.Parse(name, prop, processed)) + if (!processed) + return E_INVALIDARG; + } } return S_OK; } -STDMETHODIMP CHandler::KeepModeForNextOpen() +Z7_COM7F_IMF(CHandler::KeepModeForNextOpen()) { _keepMode_ShowImageNumber = _showImageNumber; return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.h 2015-09-15 11:58:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandler.h 2023-12-25 20:00:00.000000000 +0000 @@ -1,39 +1,40 @@ // WimHandler.h -#ifndef __ARCHIVE_WIM_HANDLER_H -#define __ARCHIVE_WIM_HANDLER_H +#ifndef ZIP7_INC_ARCHIVE_WIM_HANDLER_H +#define ZIP7_INC_ARCHIVE_WIM_HANDLER_H #include "../../../Common/MyCom.h" +#include "../Common/HandlerOut.h" + #include "WimIn.h" namespace NArchive { namespace NWim { -static const Int32 kNumImagesMaxUpdate = (1 << 10); +const Int32 kNumImagesMaxUpdate = 1 << 10; -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IArchiveGetRootProps, - public IArchiveKeepModeForNextOpen, - public ISetProperties, - public IOutArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_5( + IArchiveGetRawProps + , IArchiveGetRootProps + , IArchiveKeepModeForNextOpen + , ISetProperties + , IOutArchive +) CDatabase _db; UInt32 _version; - bool _isOldVersion; UInt32 _bootIndex; CObjectVector _volumes; CObjectVector _xmls; // unsigned _nameLenForStreams; - bool _xmlInComments; - + unsigned _numXmlItems; unsigned _numIgnoreItems; + bool _isOldVersion; + bool _xmlInComments; + bool _xmlError; bool _isArc; bool _unsupported; @@ -43,17 +44,21 @@ int _defaultImageNumber; bool _showImageNumber; - bool _keepMode_ShowImageNumber; + bool _disable_Sha1Check; UInt64 _phySize; - int _firstVolumeIndex; + Int32 _firstVolumeIndex; + + CHandlerTimeOptions _timeOptions; void InitDefaults() { + _disable_Sha1Check = false; _set_use_ShowImageNumber = false; _set_showImageNumber = false; _defaultImageNumber = -1; + _timeOptions.Init(); } bool IsUpdateSupported() const @@ -83,19 +88,6 @@ HRESULT GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, FILETIME &ft); public: CHandler(); - MY_UNKNOWN_IMP6( - IInArchive, - IArchiveGetRawProps, - IArchiveGetRootProps, - IArchiveKeepModeForNextOpen, - ISetProperties, - IOutArchive) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IArchiveGetRootProps(;) - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - STDMETHOD(KeepModeForNextOpen)(); - INTERFACE_IOutArchive(;) }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandlerOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandlerOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimHandlerOut.cpp 2022-01-08 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimHandlerOut.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -20,6 +20,8 @@ #include "../../Crypto/RandGen.h" #include "../../Crypto/Sha1Cls.h" +#include "../Common/OutStreamWithSha1.h" + #include "WimHandler.h" using namespace NWindows; @@ -27,8 +29,25 @@ namespace NArchive { namespace NWim { -static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const Byte *h, int streamIndexForInsert) +static const unsigned k_NumSubVectors_Bits = 12; // must be <= 16 + +struct CSortedIndex +{ + CObjectVector Vectors; + + CSortedIndex() + { + const unsigned k_NumSubVectors = 1 << k_NumSubVectors_Bits; + Vectors.ClearAndReserve(k_NumSubVectors); + for (unsigned i = 0; i < k_NumSubVectors; i++) + Vectors.AddNew(); + } +}; + +static int AddUniqHash(const CStreamInfo *streams, CSortedIndex &sorted2, const Byte *h, int streamIndexForInsert) { + const unsigned hash = (((unsigned)h[0] << 8) | (unsigned)h[1]) >> (16 - k_NumSubVectors_Bits); + CUIntVector &sorted = sorted2.Vectors[hash]; unsigned left = 0, right = sorted.Size(); while (left != right) { @@ -42,7 +61,7 @@ break; if (i == kHashSize) - return index; + return (int)index; if (h[i] < hash2[i]) right = mid; @@ -50,8 +69,8 @@ left = mid + 1; } - if (streamIndexForInsert >= 0) - sorted.Insert(left, streamIndexForInsert); + if (streamIndexForInsert != -1) + sorted.Insert(left, (unsigned)streamIndexForInsert); return -1; } @@ -78,13 +97,13 @@ FILETIME CTime; FILETIME ATime; FILETIME MTime; - UInt32 Attrib; UInt64 FileID; UInt64 VolID; UString Name; UString ShortName; + UInt32 Attrib; int SecurityId; // -1: means no secutity ID bool IsDir; bool Skip; @@ -97,12 +116,19 @@ CMetaItem(): UpdateIndex(-1) , HashIndex(-1) + , Size(0) , FileID(0) , VolID(0) + , Attrib(0) , SecurityId(-1) + , IsDir(false) , Skip(false) , NumSkipAltStreams(0) - {} + { + FILETIME_Clear(CTime); + FILETIME_Clear(ATime); + FILETIME_Clear(MTime); + } }; @@ -128,7 +154,7 @@ const unsigned index = indexes[mid]; const int comp = Compare_HardLink_MetaItems(mi, metaItems[index]); if (comp == 0) - return index; + return (int)index; if (comp < 0) right = mid; else @@ -220,7 +246,7 @@ } -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) { *type = NFileTimeType::kWindows; return S_OK; @@ -229,8 +255,8 @@ HRESULT CHandler::GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value) { - if (arcIndex >= 0) - return GetProperty(arcIndex, propID, value); + if (arcIndex != -1) + return GetProperty((UInt32)arcIndex, propID, value); return callback->GetProperty(callbackIndex, propID, value); } @@ -239,7 +265,7 @@ { ft.dwLowDateTime = ft.dwHighDateTime = 0; NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)); + RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)) if (prop.vt == VT_FILETIME) ft = prop.filetime; else if (prop.vt != VT_EMPTY) @@ -256,7 +282,7 @@ NCOM::CPropVariant prop; if (callback) { - RINOK(callback->GetRootProp(propID, &prop)); + RINOK(callback->GetRootProp(propID, &prop)) if (prop.vt == VT_FILETIME) { ft = prop.filetime; @@ -267,7 +293,7 @@ } if (arcRoot) { - RINOK(arcRoot->GetRootProp(propID, &prop)); + RINOK(arcRoot->GetRootProp(propID, &prop)) if (prop.vt == VT_FILETIME) { ft = prop.filetime; @@ -285,29 +311,29 @@ void CResource::WriteTo(Byte *p) const { - Set64(p, PackSize); + Set64(p, PackSize) p[7] = Flags; - Set64(p + 8, Offset); - Set64(p + 16, UnpackSize); + Set64(p + 8, Offset) + Set64(p + 16, UnpackSize) } void CHeader::WriteTo(Byte *p) const { memcpy(p, kSignature, kSignatureSize); - Set32(p + 8, kHeaderSizeMax); - Set32(p + 0xC, Version); - Set32(p + 0x10, Flags); - Set32(p + 0x14, ChunkSize); + Set32(p + 8, kHeaderSizeMax) + Set32(p + 0xC, Version) + Set32(p + 0x10, Flags) + Set32(p + 0x14, ChunkSize) memcpy(p + 0x18, Guid, 16); - Set16(p + 0x28, PartNumber); - Set16(p + 0x2A, NumParts); - Set32(p + 0x2C, NumImages); + Set16(p + 0x28, PartNumber) + Set16(p + 0x2A, NumParts) + Set32(p + 0x2C, NumImages) OffsetResource.WriteTo(p + 0x30); XmlResource.WriteTo(p + 0x48); MetadataResource.WriteTo(p + 0x60); IntegrityResource.WriteTo(p + 0x7C); - Set32(p + 0x78, BootIndex); + Set32(p + 0x78, BootIndex) memset(p + 0x94, 0, 60); } @@ -315,53 +341,16 @@ void CStreamInfo::WriteTo(Byte *p) const { Resource.WriteTo(p); - Set16(p + 0x18, PartNumber); - Set32(p + 0x1A, RefCount); + Set16(p + 0x18, PartNumber) + Set32(p + 0x1A, RefCount) memcpy(p + 0x1E, Hash, kHashSize); } -class CInStreamWithSha1: - public ISequentialInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - // NCrypto::NSha1::CContext _sha; - CAlignedBuffer _sha; - CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } -public: - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - CInStreamWithSha1(): _sha(sizeof(CSha1)) {} - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - Sha1_Init(Sha()); - } - void ReleaseStream() { _stream.Release(); } - UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { Sha1_Final(Sha(), digest); } -}; - -STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); - _size += realProcessedSize; - Sha1_Update(Sha(), (const Byte *)data, realProcessedSize); - if (processedSize) - *processedSize = realProcessedSize; - return result; -} - - static void SetFileTimeToMem(Byte *p, const FILETIME &ft) { - Set32(p, ft.dwLowDateTime); - Set32(p + 4, ft.dwHighDateTime); + Set32(p, ft.dwLowDateTime) + Set32(p + 4, ft.dwHighDateTime) } static size_t WriteItem_Dummy(const CMetaItem &item) @@ -372,15 +361,15 @@ // we write fileNameLen + 2 + 2 to be same as original WIM. unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); - unsigned shortNameLen = item.ShortName.Len() * 2; - unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); + const unsigned shortNameLen = item.ShortName.Len() * 2; + const unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); - size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); + size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); if (item.GetNumAltStreams() != 0) { if (!item.IsDir) { - UInt32 curLen = (((0x26 + 0) + 6) & ~7); + const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); totalLen += curLen; } FOR_VECTOR (i, item.AltStreams) @@ -390,7 +379,7 @@ continue; fileNameLen = ss.Name.Len() * 2; fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); - UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); + const UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); totalLen += curLen; } } @@ -407,12 +396,12 @@ unsigned shortNameLen = item.ShortName.Len() * 2; unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); - size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); + size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); memset(p, 0, totalLen); - Set64(p, totalLen); - Set64(p + 8, item.Attrib); - Set32(p + 0xC, (Int32)item.SecurityId); + Set64(p, totalLen) + Set64(p + 8, item.Attrib) + Set32(p + 0xC, (UInt32)(Int32)item.SecurityId) SetFileTimeToMem(p + 0x28, item.CTime); SetFileTimeToMem(p + 0x30, item.ATime); SetFileTimeToMem(p + 0x38, item.MTime); @@ -425,21 +414,21 @@ if (item.Reparse.Size() != 0) { UInt32 tag = GetUi32(item.Reparse); - Set32(p + 0x58, tag); + Set32(p + 0x58, tag) // Set32(p + 0x5C, 0); // probably it's always ZERO } else if (item.FileID != 0) { - Set64(p + 0x58, item.FileID); + Set64(p + 0x58, item.FileID) } - Set16(p + 0x62, (UInt16)shortNameLen); - Set16(p + 0x64, (UInt16)fileNameLen); + Set16(p + 0x62, (UInt16)shortNameLen) + Set16(p + 0x64, (UInt16)fileNameLen) unsigned i; for (i = 0; i * 2 < fileNameLen; i++) - Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]); + Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]) for (i = 0; i * 2 < shortNameLen; i++) - Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]); + Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]) if (item.GetNumAltStreams() == 0) { @@ -448,14 +437,14 @@ } else { - Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))); + Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))) p += totalLen; if (!item.IsDir) { - UInt32 curLen = (((0x26 + 0) + 6) & ~7); + const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); memset(p, 0, curLen); - Set64(p, curLen); + Set64(p, curLen) if (item.HashIndex >= 0) memcpy(p + 0x10, streams[item.HashIndex].Hash, kHashSize); totalLen += curLen; @@ -470,15 +459,15 @@ fileNameLen = ss.Name.Len() * 2; fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); - UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); + UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); memset(p, 0, curLen); - Set64(p, curLen); + Set64(p, curLen) if (ss.HashIndex >= 0) memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize); - Set16(p + 0x24, (UInt16)fileNameLen); + Set16(p + 0x24, (UInt16)fileNameLen) for (i = 0; i * 2 < fileNameLen; i++) - Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]); + Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]) totalLen += curLen; p += curLen; } @@ -529,7 +518,7 @@ for (i = 0; i < tree.Dirs.Size(); i++) pos += WriteItem_Dummy(MetaItems[tree.Dirs[i].MetaIndex]); - Set64(dest + pos, 0); + Set64(dest + pos, 0) pos += 8; @@ -544,7 +533,7 @@ posStart += len; if (needCreateTree) { - Set64(dest + posStart - len + 0x10, pos); // subdirOffset + Set64(dest + posStart - len + 0x10, pos) // subdirOffset WriteTree(subDir, dest, pos); } } @@ -557,18 +546,18 @@ { const CMetaItem &mi = MetaItems[tree.MetaIndex]; if (mi.UpdateIndex >= 0) - UpdateIndexes.Add(mi.UpdateIndex); + UpdateIndexes.Add((unsigned)mi.UpdateIndex); FOR_VECTOR (si, mi.AltStreams) - UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); + UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); } unsigned i; for (i = 0; i < tree.Files.Size(); i++) { const CMetaItem &mi = MetaItems[tree.Files[i]]; - UpdateIndexes.Add(mi.UpdateIndex); + UpdateIndexes.Add((unsigned)mi.UpdateIndex); FOR_VECTOR (si, mi.AltStreams) - UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); + UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); } for (i = 0; i < tree.Dirs.Size(); i++) @@ -578,14 +567,14 @@ static void AddTag_ToString(AString &s, const char *name, const char *value) { - s += '<'; + s.Add_Char('<'); s += name; - s += '>'; + s.Add_Char('>'); s += value; - s += '<'; - s += '/'; + s.Add_Char('<'); + s.Add_Slash(); s += name; - s += '>'; + s.Add_Char('>'); } @@ -599,7 +588,7 @@ static CXmlItem &AddUniqueTag(CXmlItem &parentItem, const char *name) { - int index = parentItem.FindSubTag(name); + const int index = parentItem.FindSubTag(name); if (index < 0) { CXmlItem &subItem = parentItem.SubItems.AddNew(); @@ -658,8 +647,7 @@ static void AddTag_String_IfEmpty(CXmlItem &parentItem, const char *name, const char *value) { - int index = parentItem.FindSubTag(name); - if (index >= 0) + if (parentItem.FindSubTag(name) >= 0) return; CXmlItem &tag = parentItem.SubItems.AddNew(); tag.IsTag = true; @@ -696,7 +684,7 @@ static void AddTrees(CObjectVector &trees, CObjectVector &metaItems, const CMetaItem &ri, int curTreeIndex) { while (curTreeIndex >= (int)trees.Size()) - trees.AddNew().Dirs.AddNew().MetaIndex = metaItems.Add(ri); + trees.AddNew().Dirs.AddNew().MetaIndex = (int)metaItems.Add(ri); } @@ -704,7 +692,7 @@ -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback)) { COM_TRY_BEGIN @@ -732,7 +720,7 @@ return E_NOTIMPL; CMyComPtr outStream; - RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)); + RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)) if (!outStream) return E_NOTIMPL; if (!callback) @@ -744,7 +732,7 @@ CMetaItem ri; // default DIR item FILETIME ftCur; NTime::GetCurUtcFileTime(ftCur); - ri.MTime = ri.ATime = ri.CTime = ftCur; + // ri.MTime = ri.ATime = ri.CTime = ftCur; ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; ri.IsDir = true; @@ -765,7 +753,7 @@ { UInt32 indexInArchive; Int32 newData, newProps; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) if (newProps == 0) { if (indexInArchive >= _db.SortedItems.Size()) @@ -791,7 +779,7 @@ else { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPath, &prop)); + RINOK(callback->GetProperty(i, kpidPath, &prop)) if (prop.vt != VT_BSTR) return E_INVALIDARG; @@ -851,11 +839,11 @@ UInt32 propType = 0; if (getRootProps) { - RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); + RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) } if (dataSize == 0 && isUpdate) { - RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); + RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) } if (dataSize != 0) { @@ -864,21 +852,21 @@ while (defaultImageIndex >= (int)secureBlocks.Size()) secureBlocks.AddNew(); CUniqBlocks &secUniqBlocks = secureBlocks[defaultImageIndex]; - rootItem.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); + rootItem.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); } } IArchiveGetRootProps *thisGetRoot = isUpdate ? this : NULL; - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)); - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)); - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)); + if (_timeOptions.Write_CTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)) + if (_timeOptions.Write_ATime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)) + if (_timeOptions.Write_MTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)) { NCOM::CPropVariant prop; if (getRootProps) { - RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)); + RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)) if (prop.vt == VT_UI4) rootItem.Attrib = prop.ulVal; else if (prop.vt != VT_EMPTY) @@ -886,7 +874,7 @@ } if (prop.vt == VT_EMPTY && thisGetRoot) { - RINOK(GetRootProp(kpidAttrib, &prop)); + RINOK(GetRootProp(kpidAttrib, &prop)) if (prop.vt == VT_UI4) rootItem.Attrib = prop.ulVal; else if (prop.vt != VT_EMPTY) @@ -908,7 +896,7 @@ CUpdateItem ui; UInt32 indexInArchive; Int32 newData, newProps; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) if (newData == 0 || newProps == 0) { @@ -940,16 +928,16 @@ } if (newData == 0) - ui.InArcIndex = indexInArchive; + ui.InArcIndex = (Int32)indexInArchive; } // we set arcIndex only if we must use old props - Int32 arcIndex = (newProps ? -1 : indexInArchive); + const Int32 arcIndex = (newProps ? -1 : (Int32)indexInArchive); bool isDir = false; { NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)); + RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)) if (prop.vt == VT_BOOL) isDir = (prop.boolVal != VARIANT_FALSE); else if (prop.vt != VT_EMPTY) @@ -959,7 +947,7 @@ bool isAltStream = false; { NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)); + RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)) if (prop.vt == VT_BOOL) isAltStream = (prop.boolVal != VARIANT_FALSE); else if (prop.vt != VT_EMPTY) @@ -986,11 +974,11 @@ if (newData) { - RINOK(callback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)) } else { - RINOK(GetProperty(indexInArchive, kpidSize, &prop)); + RINOK(GetProperty(indexInArchive, kpidSize, &prop)) } if (prop.vt == VT_UI8) @@ -1002,7 +990,7 @@ { NCOM::CPropVariant propPath; const wchar_t *path = NULL; - RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)); + RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)) if (propPath.vt == VT_BSTR) path = propPath.bstrVal; else if (propPath.vt != VT_EMPTY) @@ -1056,8 +1044,8 @@ CAltStream ss; ss.Size = size; ss.Name = end + 1; - ss.UpdateIndex = db.UpdateItems.Size(); - ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); + ss.UpdateIndex = (int)db.UpdateItems.Size(); + ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); } else if (c == WCHAR_PATH_SEPARATOR || c == L'/') { @@ -1073,7 +1061,7 @@ { for (;;) { - wchar_t c = *path++; + const wchar_t c = *path++; if (c == 0) break; if (c == WCHAR_PATH_SEPARATOR || c == L'/') @@ -1082,7 +1070,7 @@ if (!curItem->FindDir(db.MetaItems, fileName, indexOfDir)) { CDir &dir = curItem->Dirs.InsertNew(indexOfDir); - dir.MetaIndex = db.MetaItems.Add(ri); + dir.MetaIndex = (int)db.MetaItems.Add(ri); db.MetaItems.Back().Name = fileName; } curItem = &curItem->Dirs[indexOfDir]; @@ -1121,7 +1109,7 @@ // we want to support cases of c::substream, where c: is drive name if (colonPos == 1 && fileName[2] == L':' && IS_LETTER_CHAR(fileName[0])) colonPos = 2; - const UString mainName = fileName.Left(colonPos); + const UString mainName = fileName.Left((unsigned)colonPos); unsigned indexOfDir; if (mainName.IsEmpty()) @@ -1132,11 +1120,11 @@ { for (int j = (int)curItem->Files.Size() - 1; j >= 0; j--) { - int metaIndex = curItem->Files[j]; + const unsigned metaIndex = curItem->Files[j]; const CMetaItem &mi = db.MetaItems[metaIndex]; if (CompareFileNames(mainName, mi.Name) == 0) { - ui.MetaIndex = metaIndex; + ui.MetaIndex = (int)metaIndex; break; } } @@ -1147,8 +1135,8 @@ CAltStream ss; ss.Size = size; ss.Name = fileName.Ptr(colonPos + 1); - ss.UpdateIndex = db.UpdateItems.Size(); - ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); + ss.UpdateIndex = (int)db.UpdateItems.Size(); + ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); } } } @@ -1158,7 +1146,7 @@ { if (!isRootImageDir) { - ui.MetaIndex = db.MetaItems.Size(); + ui.MetaIndex = (int)db.MetaItems.Size(); db.MetaItems.AddNew(); } @@ -1166,10 +1154,10 @@ mi.Size = size; mi.IsDir = isDir; mi.Name = fileName; - mi.UpdateIndex = db.UpdateItems.Size(); + mi.UpdateIndex = (int)db.UpdateItems.Size(); { NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)); + RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) mi.Attrib = 0; else if (prop.vt == VT_UI4) @@ -1179,13 +1167,17 @@ if (isDir) mi.Attrib |= FILE_ATTRIBUTE_DIRECTORY; } - RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)); - RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)); - RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)); + + if (arcIndex != -1 || _timeOptions.Write_CTime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)) + if (arcIndex != -1 || _timeOptions.Write_ATime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)) + if (arcIndex != -1 || _timeOptions.Write_MTime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)) { NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)); + RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)) if (prop.vt == VT_BSTR) mi.ShortName.SetFromBstr(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -1208,7 +1200,7 @@ if (arcIndex >= 0) { - GetRawProp(arcIndex, kpidNtSecure, &data, &dataSize, &propType); + GetRawProp((UInt32)arcIndex, kpidNtSecure, &data, &dataSize, &propType); } else { @@ -1219,7 +1211,7 @@ { if (propType != NPropDataType::kRaw) return E_FAIL; - mi.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); + mi.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); } data = NULL; @@ -1228,7 +1220,7 @@ if (arcIndex >= 0) { - GetRawProp(arcIndex, kpidNtReparse, &data, &dataSize, &propType); + GetRawProp((UInt32)arcIndex, kpidNtReparse, &data, &dataSize, &propType); } else { @@ -1254,7 +1246,7 @@ curItem->Dirs.InsertNew(indexOfDir).MetaIndex = ui.MetaIndex; } else - curItem->Files.Add(ui.MetaIndex); + curItem->Files.Add((unsigned)ui.MetaIndex); } } @@ -1272,7 +1264,7 @@ if (!isChangedImage[i]) numNewImages = i + 1; - AddTrees(trees, db.MetaItems, ri, numNewImages - 1); + AddTrees(trees, db.MetaItems, ri, (int)numNewImages - 1); for (i = 0; i < trees.Size(); i++) if (i >= isChangedImage.Size() || isChangedImage[i]) @@ -1354,15 +1346,12 @@ complexity += rs.PackSize; } - RINOK(callback->SetTotal(complexity)); + RINOK(callback->SetTotal(complexity)) UInt64 totalComplexity = complexity; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(callback, true); + CMyComPtr2_Create copyCoder; complexity = 0; @@ -1381,19 +1370,23 @@ header.ChunkSizeBits = srcHeader.ChunkSizeBits; } + CMyComPtr setRestriction; + outSeqStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, kHeaderSizeMax)) + { Byte buf[kHeaderSizeMax]; header.WriteTo(buf); - RINOK(WriteStream(outStream, buf, kHeaderSizeMax)); + RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) } UInt64 curPos = kHeaderSizeMax; - CInStreamWithSha1 *inShaStreamSpec = new CInStreamWithSha1; - CMyComPtr inShaStream = inShaStreamSpec; + CMyComPtr2_Create inShaStream; CLimitedSequentialInStream *inStreamLimitedSpec = NULL; - CMyComPtr inStreamLimited; + CMyComPtr inStreamLimited; if (_volumes.Size() == 2) { inStreamLimitedSpec = new CLimitedSequentialInStream; @@ -1403,7 +1396,7 @@ CRecordVector streams; - CUIntVector sortedHashes; // indexes to streams, sorted by SHA1 + CSortedIndex sortedHashes; // indexes to streams, sorted by SHA1 // ---------- Copy unchanged data streams ---------- @@ -1415,7 +1408,7 @@ const CStreamInfo &siOld = _db.DataStreams[i]; const CResource &rs = siOld.Resource; - unsigned numRefs = streamsRefs[i]; + const unsigned numRefs = streamsRefs[i]; if (numRefs == 0) { @@ -1426,9 +1419,9 @@ } lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) - int streamIndex = streams.Size(); + const unsigned streamIndex = streams.Size(); CStreamInfo s; s.Resource = rs; s.PartNumber = 1; @@ -1462,17 +1455,17 @@ if (!rs.IsSolid() || rs.IsSolidSmall()) { - int find = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, streamIndex); - if (find >= 0) + const int find = AddUniqHash(streams.ConstData(), sortedHashes, siOld.Hash, (int)streamIndex); + if (find != -1) return E_FAIL; // two streams with same SHA-1 } if (!rs.IsSolid() || rs.IsSolidBig()) { - RINOK(_volumes[siOld.PartNumber].Stream->Seek(rs.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_volumes[siOld.PartNumber].Stream, rs.Offset)) inStreamLimitedSpec->Init(rs.PackSize); - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != rs.PackSize) + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != rs.PackSize) return E_FAIL; s.Resource.Offset = curPos; curPos += rs.PackSize; @@ -1490,7 +1483,7 @@ for (i = 0; i < db.UpdateIndexes.Size(); i++) { lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; CMetaItem &mi = db.MetaItems[ui.MetaIndex]; UInt64 size = 0; @@ -1534,9 +1527,9 @@ const CStreamInfo &siOld = _db.DataStreams[item.StreamIndex]; - int index = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, -1); + const int index = AddUniqHash(streams.ConstData(), sortedHashes, siOld.Hash, -1); // we must have written that stream already - if (index < 0) + if (index == -1) return E_FAIL; if (ui.AltStreamIndex < 0) @@ -1562,7 +1555,7 @@ } else { - RINOK(res); + RINOK(res) int miIndex = -1; @@ -1581,23 +1574,23 @@ if (getProps2->GetProps2(&props) == S_OK) { mi.Attrib = props.Attrib; - mi.CTime = props.CTime; - mi.ATime = props.ATime; - mi.MTime = props.MTime; + if (_timeOptions.Write_CTime.Val) mi.CTime = props.CTime; + if (_timeOptions.Write_ATime.Val) mi.ATime = props.ATime; + if (_timeOptions.Write_MTime.Val) mi.MTime = props.MTime; mi.FileID = props.FileID_Low; if (props.NumLinks <= 1) mi.FileID = 0; mi.VolID = props.VolID; if (mi.FileID != 0) - miIndex = AddToHardLinkList(db.MetaItems, ui.MetaIndex, hlIndexes); + miIndex = AddToHardLinkList(db.MetaItems, (unsigned)ui.MetaIndex, hlIndexes); if (props.Size != size && props.Size != (UInt64)(Int64)-1) { - Int64 delta = (Int64)props.Size - (Int64)size; - Int64 newComplexity = totalComplexity + delta; + const Int64 delta = (Int64)props.Size - (Int64)size; + const Int64 newComplexity = (Int64)totalComplexity + delta; if (newComplexity > 0) { - totalComplexity = newComplexity; + totalComplexity = (UInt64)newComplexity; callback->SetTotal(totalComplexity); } mi.Size = props.Size; @@ -1620,19 +1613,19 @@ return E_FAIL; NCrypto::NSha1::CContext sha1; sha1.Init(); - size_t packSize = mi.Reparse.Size() - 8; + const size_t packSize = mi.Reparse.Size() - 8; sha1.Update((const Byte *)mi.Reparse + 8, packSize); Byte hash[kHashSize]; sha1.Final(hash); - int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); + int index = AddUniqHash(streams.ConstData(), sortedHashes, hash, (int)streams.Size()); - if (index >= 0) + if (index != -1) streams[index].RefCount++; else { - index = streams.Size(); - RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)); + index = (int)streams.Size(); + RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)) CStreamInfo s; s.Resource.PackSize = packSize; s.Resource.Offset = curPos; @@ -1654,9 +1647,13 @@ } else { - inShaStreamSpec->SetStream(fileInStream); + inShaStream->SetStream(fileInStream); + + CMyComPtr inSeekStream; + fileInStream.QueryInterface(IID_IInStream, (void **)&inSeekStream); + fileInStream.Release(); - inShaStreamSpec->Init(); + inShaStream->Init(); UInt64 offsetBlockSize = 0; /* if (useResourceCompression) @@ -1670,54 +1667,88 @@ } } */ + + // 22.02: we use additional read-only pass to calculate SHA-1 + bool needWritePass = true; + int index = -1; - RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress)); - size = copyCoderSpec->TotalSize; - - if (size != 0) + if (inSeekStream /* && !sortedHashes.IsEmpty() */) { - Byte hash[kHashSize]; - UInt64 packSize = offsetBlockSize + size; - inShaStreamSpec->Final(hash); - - int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); - - if (index >= 0) - { - streams[index].RefCount++; - outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); - outStream->SetSize(curPos); - } + RINOK(copyCoder.Interface()->Code(inShaStream, NULL, NULL, NULL, lps)) + size = copyCoder->TotalSize; + if (size == 0) + needWritePass = false; else { - index = streams.Size(); - CStreamInfo s; - s.Resource.PackSize = packSize; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = size; - s.Resource.Flags = 0; - /* - if (useResourceCompression) - s.Resource.Flags = NResourceFlags::Compressed; - */ - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, hash, kHashSize); - curPos += packSize; + Byte hash[kHashSize]; + inShaStream->Final(hash); - streams.Add(s); + index = AddUniqHash(streams.ConstData(), sortedHashes, hash, -1); + if (index != -1) + { + streams[index].RefCount++; + needWritePass = false; + } + else + { + RINOK(InStream_SeekToBegin(inSeekStream)) + inShaStream->Init(); + } } - + } + + if (needWritePass) + { + RINOK(copyCoder.Interface()->Code(inShaStream, outStream, NULL, NULL, lps)) + size = copyCoder->TotalSize; + } + + if (size != 0) + { + if (needWritePass) + { + Byte hash[kHashSize]; + const UInt64 packSize = offsetBlockSize + size; + inShaStream->Final(hash); + + index = AddUniqHash(streams.ConstData(), sortedHashes, hash, (int)streams.Size()); + + if (index != -1) + { + streams[index].RefCount++; + outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); + outStream->SetSize(curPos); + } + else + { + index = (int)streams.Size(); + CStreamInfo s; + s.Resource.PackSize = packSize; + s.Resource.Offset = curPos; + s.Resource.UnpackSize = size; + s.Resource.Flags = 0; + /* + if (useResourceCompression) + s.Resource.Flags = NResourceFlags::Compressed; + */ + s.PartNumber = 1; + s.RefCount = 1; + memcpy(s.Hash, hash, kHashSize); + curPos += packSize; + + streams.Add(s); + } + } // needWritePass if (ui.AltStreamIndex < 0) mi.HashIndex = index; else mi.AltStreams[ui.AltStreamIndex].HashIndex = index; - } + } // (size != 0) } } fileInStream.Release(); complexity += size; - RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) } while (secureBlocks.Size() < numNewImages) @@ -1730,15 +1761,15 @@ for (i = 0; i < numNewImages; i++) { lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) if (i < isChangedImage.Size() && !isChangedImage[i]) { CStreamInfo s = _db.MetaStreams[i]; - RINOK(_volumes[1].Stream->Seek(s.Resource.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_volumes[1].Stream, s.Resource.Offset)) inStreamLimitedSpec->Init(s.Resource.PackSize); - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != s.Resource.PackSize) + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != s.Resource.PackSize) return E_FAIL; s.Resource.Offset = curPos; @@ -1774,14 +1805,14 @@ CByteArr meta(pos); - Set32((Byte *)meta + 4, secBufs.Size()); // num security entries + Set32((Byte *)meta + 4, secBufs.Size()) // num security entries pos = kSecuritySize; if (secBufs.Size() == 0) { // we can write 0 here only if there is no security data, imageX does it, // but some programs expect size = 8 - Set32((Byte *)meta, 8); // size of security data + Set32((Byte *)meta, 8) // size of security data // Set32((Byte *)meta, 0); } else @@ -1789,7 +1820,7 @@ unsigned k; for (k = 0; k < secBufs.Size(); k++, pos += 8) { - Set64(meta + pos, secBufs[k].Size()); + Set64(meta + pos, secBufs[k].Size()) } for (k = 0; k < secBufs.Size(); k++) { @@ -1803,10 +1834,10 @@ } while ((pos & 7) != 0) meta[pos++] = 0; - Set32((Byte *)meta, (UInt32)pos); // size of security data + Set32((Byte *)meta, (UInt32)pos) // size of security data } - db.Hashes = &streams.Front(); + db.Hashes = streams.ConstData(); db.WriteTree(tree, (Byte *)meta, pos); { @@ -1833,14 +1864,14 @@ header.BootIndex = _bootIndex; } - RINOK(WriteStream(outStream, (const Byte *)meta, pos)); + RINOK(WriteStream(outStream, (const Byte *)meta, pos)) meta.Free(); curPos += pos; } } lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; header.OffsetResource.Offset = curPos; @@ -1854,7 +1885,7 @@ { Byte buf[kStreamInfoSize]; streams[i].WriteTo(buf); - RINOK(WriteStream(outStream, buf, kStreamInfoSize)); + RINOK(WriteStream(outStream, buf, kStreamInfoSize)) curPos += kStreamInfoSize; } @@ -1862,7 +1893,7 @@ AddTagUInt64_ToString(xml, "TOTALBYTES", curPos); for (i = 0; i < trees.Size(); i++) { - CDir &tree = trees[i]; + const CDir &tree = trees[i]; CXmlItem item; if (_xmls.Size() == 1) @@ -1905,16 +1936,19 @@ UString utf16; if (!ConvertUTF8ToUnicode(xml, utf16)) return S_FALSE; - xmlSize = (utf16.Len() + 1) * 2; + xmlSize = ((size_t)utf16.Len() + 1) * 2; CByteArr xmlBuf(xmlSize); - Set16((Byte *)xmlBuf, 0xFEFF); + Set16((Byte *)xmlBuf, 0xFEFF) for (i = 0; i < (unsigned)utf16.Len(); i++) - Set16((Byte *)xmlBuf + 2 + i * 2, (UInt16)utf16[i]); - RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)); + { + Set16((Byte *)xmlBuf + 2 + (size_t)i * 2, (UInt16)utf16[i]) + } + RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)) } - header.XmlResource.UnpackSize = header.XmlResource.PackSize = xmlSize; + header.XmlResource.UnpackSize = + header.XmlResource.PackSize = xmlSize; header.XmlResource.Offset = curPos; header.XmlResource.Flags = NResourceFlags::kMetadata; @@ -1923,9 +1957,14 @@ { Byte buf[kHeaderSizeMax]; header.WriteTo(buf); - return WriteStream(outStream, buf, kHeaderSizeMax); + RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) } + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + + return S_OK; + COM_TRY_END } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimIn.cpp 2022-01-07 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -34,19 +34,19 @@ namespace NArchive { namespace NWim { -static int inline GetLog(UInt32 num) +static bool inline GetLog_val_min_dest(const UInt32 val, unsigned i, unsigned &dest) { - for (int i = 0; i < 32; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - - -CUnpacker::~CUnpacker() -{ - if (lzmsDecoder) - delete lzmsDecoder; + UInt32 v = (UInt32)1 << i; + for (; i < 32; i++) + { + if (v == val) + { + dest = i; + return true; + } + v += v; + } + return false; } @@ -64,25 +64,27 @@ } else if (method == NMethod::kLZX) { - if (!lzxDecoder) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder(true); - lzxDecoder = lzxDecoderSpec; - } + lzxDecoder.Create_if_Empty(); + lzxDecoder->Set_WimMode(true); } else if (method == NMethod::kLZMS) { - if (!lzmsDecoder) - lzmsDecoder = new NCompress::NLzms::CDecoder(); + lzmsDecoder.Create_if_Empty(); } else return E_NOTIMPL; const size_t chunkSize = (size_t)1 << chunkSizeBits; - - unpackBuf.EnsureCapacity(chunkSize); - if (!unpackBuf.Data) - return E_OUTOFMEMORY; + + { + const unsigned + kAdditionalOutputBufSize = MyMax(NCompress::NLzx:: + kAdditionalOutputBufSize, NCompress::NXpress:: + kAdditionalOutputBufSize); + unpackBuf.EnsureCapacity(chunkSize + kAdditionalOutputBufSize); + if (!unpackBuf.Data) + return E_OUTOFMEMORY; + } HRESULT res = S_FALSE; size_t unpackedSize = 0; @@ -95,36 +97,38 @@ } else if (inSize < chunkSize) { - packBuf.EnsureCapacity(chunkSize); + const unsigned kAdditionalInputSize = 32; + packBuf.EnsureCapacity(chunkSize + kAdditionalInputSize); if (!packBuf.Data) return E_OUTOFMEMORY; - RINOK(ReadStream_FALSE(inStream, packBuf.Data, inSize)); + RINOK(ReadStream_FALSE(inStream, packBuf.Data, inSize)) + memset(packBuf.Data + inSize, 0xff, kAdditionalInputSize); TotalPacked += inSize; if (method == NMethod::kXPRESS) { - res = NCompress::NXpress::Decode(packBuf.Data, inSize, unpackBuf.Data, outSize); + res = NCompress::NXpress::Decode_WithExceedWrite(packBuf.Data, inSize, unpackBuf.Data, outSize); if (res == S_OK) unpackedSize = outSize; } else if (method == NMethod::kLZX) { - res = lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits); + res = lzxDecoder->Set_ExternalWindow_DictBits(unpackBuf.Data, chunkSizeBits); if (res != S_OK) return E_NOTIMPL; - lzxDecoderSpec->KeepHistoryForNext = false; - lzxDecoderSpec->SetKeepHistory(false); - res = lzxDecoderSpec->Code(packBuf.Data, inSize, (UInt32)outSize); - unpackedSize = lzxDecoderSpec->GetUnpackSize(); - if (res == S_OK && !lzxDecoderSpec->WasBlockFinished()) + lzxDecoder->Set_KeepHistoryForNext(false); + lzxDecoder->Set_KeepHistory(false); + res = lzxDecoder->Code_WithExceedReadWrite(packBuf.Data, inSize, (UInt32)outSize); + unpackedSize = lzxDecoder->GetUnpackSize(); + if (res == S_OK && !lzxDecoder->WasBlockFinished()) res = S_FALSE; } else { res = lzmsDecoder->Code(packBuf.Data, inSize, unpackBuf.Data, outSize); - unpackedSize = lzmsDecoder->GetUnpackSize();; + unpackedSize = lzmsDecoder->GetUnpackSize(); } } @@ -141,7 +145,7 @@ if (outStream) { - RINOK(WriteStream(outStream, unpackBuf.Data, outSize)); + RINOK(WriteStream(outStream, unpackBuf.Data, outSize)) } return res; @@ -158,26 +162,21 @@ { if (!resource.IsCompressed() && !resource.IsSolid()) { - if (!copyCoder) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } + copyCoder.Create_if_Empty(); - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream(); - CMyComPtr limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(inStream); + CMyComPtr2_Create limitedStream; + limitedStream->SetStream(inStream); - RINOK(inStream->Seek(resource.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, resource.Offset)) if (resource.PackSize != resource.UnpackSize) return S_FALSE; - limitedStreamSpec->Init(resource.PackSize); + limitedStream->Init(resource.PackSize); TotalPacked += resource.PackSize; - HRESULT res = copyCoder->Code(limitedStream, outStream, NULL, NULL, progress); + HRESULT res = copyCoder.Interface()->Code(limitedStream, outStream, NULL, NULL, progress); - if (res == S_OK && copyCoderSpec->TotalSize != resource.UnpackSize) + if (res == S_OK && copyCoder->TotalSize != resource.UnpackSize) res = S_FALSE; return res; } @@ -221,7 +220,7 @@ size_t cur = chunkSize - offsetInChunk; if (cur > rem) cur = (size_t)rem; - RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)); + RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)) outProcessed += cur; rem -= cur; offsetInChunk = 0; @@ -233,20 +232,20 @@ if (rem == 0) return S_OK; - UInt64 offset = ss.Chunks[chunkIndex]; - UInt64 packSize = ss.GetChunkPackSize(chunkIndex); + const UInt64 offset = ss.Chunks[chunkIndex]; + const UInt64 packSize = ss.GetChunkPackSize(chunkIndex); const CResource &rs = db->DataStreams[ss.StreamIndex].Resource; - RINOK(inStream->Seek(rs.Offset + ss.HeadersSize + offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, rs.Offset + ss.HeadersSize + offset)) size_t cur = chunkSize; - UInt64 unpackRem = ss.UnpackSize - ((UInt64)chunkIndex << chunkSizeBits); + const UInt64 unpackRem = ss.UnpackSize - ((UInt64)chunkIndex << chunkSizeBits); if (cur > unpackRem) cur = (size_t)unpackRem; _solidIndex = -1; _unpackedChunkIndex = 0; - HRESULT res = UnpackChunk(inStream, ss.Method, chunkSizeBits, (size_t)packSize, cur, NULL); + const HRESULT res = UnpackChunk(inStream, (unsigned)ss.Method, chunkSizeBits, (size_t)packSize, cur, NULL); if (res != S_OK) { @@ -266,11 +265,11 @@ if (cur > rem) cur = (size_t)rem; - RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)); + RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)) if (progress) { - RINOK(progress->SetRatioInfo(&packProcessed, &outProcessed)); + RINOK(progress->SetRatioInfo(&packProcessed, &outProcessed)) packProcessed += packSize; outProcessed += cur; } @@ -311,8 +310,8 @@ if (sizesBufSize != sizesBufSize64) return E_OUTOFMEMORY; sizesBuf.AllocAtLeast(sizesBufSize); - RINOK(inStream->Seek(baseOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)); + RINOK(InStream_SeekSet(inStream, baseOffset)) + RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)) baseOffset += sizesBufSize64; numChunks = (size_t)numChunks64; } @@ -341,11 +340,11 @@ if (inSize != inSize64) return S_FALSE; - RINOK(inStream->Seek(baseOffset + offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, baseOffset + offset)) if (progress) { - RINOK(progress->SetRatioInfo(&offset, &outProcessed)); + RINOK(progress->SetRatioInfo(&offset, &outProcessed)) } size_t outSize = (size_t)1 << chunkSizeBits; @@ -353,7 +352,7 @@ if (outSize > rem) outSize = (size_t)rem; - RINOK(UnpackChunk(inStream, header.GetMethod(), chunkSizeBits, inSize, outSize, outStream)); + RINOK(UnpackChunk(inStream, header.GetMethod(), chunkSizeBits, inSize, outSize, outStream)) outProcessed += outSize; offset = nextOffset; @@ -366,24 +365,13 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, const CHeader &header, const CDatabase *db, ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest) { - COutStreamWithSha1 *shaStreamSpec = NULL; - CMyComPtr shaStream; - + CMyComPtr2_Create shaStream; // outStream can be NULL, so we use COutStreamWithSha1 even if sha1 is not required - // if (digest) - { - shaStreamSpec = new COutStreamWithSha1(); - shaStream = shaStreamSpec; - shaStreamSpec->SetStream(outStream); - shaStreamSpec->Init(digest != NULL); - outStream = shaStream; - } - - HRESULT res = Unpack2(inStream, resource, header, db, outStream, progress); - + shaStream->SetStream(outStream); + shaStream->Init(digest != NULL); + const HRESULT res = Unpack2(inStream, resource, header, db, shaStream, progress); if (digest) - shaStreamSpec->Final(digest); - + shaStream->Final(digest); return res; } @@ -394,21 +382,16 @@ CByteBuffer &buf, Byte *digest) { // if (resource.IsSolid()) return E_NOTIMPL; - UInt64 unpackSize64 = resource.UnpackSize; if (db) unpackSize64 = db->Get_UnpackSize_of_Resource(resource); - - size_t size = (size_t)unpackSize64; + const size_t size = (size_t)unpackSize64; if (size != unpackSize64) return E_OUTOFMEMORY; - buf.Alloc(size); - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream(); - CMyComPtr outStream = outStreamSpec; - outStreamSpec->Init((Byte *)buf, size); - + CMyComPtr2_Create outStream; + outStream->Init((Byte *)buf, size); return Unpack(inStream, resource, header, db, outStream, NULL, digest); } @@ -494,8 +477,8 @@ void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCOM::CPropVariant &path) const { unsigned size = 0; - int index = index1; - int imageIndex = Items[index].ImageIndex; + int index = (int)index1; + const int imageIndex = Items[index].ImageIndex; const CImage &image = Images[imageIndex]; unsigned newLevel = 0; @@ -545,7 +528,7 @@ else if (needColon) s[0] = L':'; - index = index1; + index = (int)index1; wchar_t separator = 0; for (;;) @@ -597,7 +580,7 @@ if (OpenCallback && (Items.Size() & 0xFFFF) == 0) { UInt64 numFiles = Items.Size(); - RINOK(OpenCallback->SetCompleted(&numFiles, NULL)); + RINOK(OpenCallback->SetCompleted(&numFiles, NULL)) } const size_t rem = DirSize - pos; @@ -664,7 +647,7 @@ item.Offset = pos; item.Parent = parent; - item.ImageIndex = Images.Size() - 1; + item.ImageIndex = (int)Images.Size() - 1; const unsigned prevIndex = Items.Add(item); @@ -677,7 +660,8 @@ return S_FALSE; const Byte *p2 = DirData + pos; const UInt64 len2 = Get64(p2); - if ((len2 & align) != 0 || rem2 < len2 || len2 < (IsOldVersion ? 0x18 : 0x28)) + if ((len2 & align) != 0 || rem2 < len2 + || len2 < (unsigned)(IsOldVersion ? 0x18 : 0x28)) return S_FALSE; DirProcessed += (size_t)len2; @@ -742,8 +726,8 @@ CItem item2; item2.Offset = pos; item2.IsAltStream = true; - item2.Parent = prevIndex; - item2.ImageIndex = Images.Size() - 1; + item2.Parent = (int)prevIndex; + item2.ImageIndex = (int)Images.Size() - 1; Items.Add(item2); } @@ -775,7 +759,7 @@ if (item.IsDir && subdirOffset != 0) { - RINOK(ParseDirItem((size_t)subdirOffset, prevIndex)); + RINOK(ParseDirItem((size_t)subdirOffset, (int)prevIndex)) } } } @@ -864,7 +848,7 @@ DirStartOffset = DirProcessed = pos; image.StartItem = Items.Size(); - RINOK(ParseDirItem(pos, parent)); + RINOK(ParseDirItem(pos, parent)) image.NumItems = Items.Size() - image.StartItem; if (DirProcessed == DirSize) @@ -899,27 +883,25 @@ ChunkSizeBits = kChunkSizeBits; if (ChunkSize != 0) { - int log = GetLog(ChunkSize); - if (log < 12) + if (!GetLog_val_min_dest(ChunkSize, 12, ChunkSizeBits)) return S_FALSE; - ChunkSizeBits = log; } } - _IsOldVersion = false; - _IsNewVersion = false; + _isOldVersion = false; + _isNewVersion = false; if (IsSolidVersion()) - _IsNewVersion = true; + _isNewVersion = true; else { if (Version < 0x010900) return S_FALSE; - _IsOldVersion = (Version <= 0x010A00); + _isOldVersion = (Version <= 0x010A00); // We don't know details about 1.11 version. So we use headerSize to guess exact features. if (Version == 0x010B00 && headerSize == 0x60) - _IsOldVersion = true; - _IsNewVersion = (Version >= 0x010D00); + _isOldVersion = true; + _isNewVersion = (Version >= 0x010D00); } unsigned offset; @@ -973,7 +955,7 @@ HRESULT ReadHeader(IInStream *inStream, CHeader &h, UInt64 &phySize) { Byte p[kHeaderSizeMax]; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); + RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)) if (memcmp(p, kSignature, kSignatureSize) != 0) return S_FALSE; return h.Parse(p, phySize); @@ -985,7 +967,7 @@ CByteBuffer offsetBuf; CUnpacker unpacker; - RINOK(unpacker.UnpackData(inStream, h.OffsetResource, h, NULL, offsetBuf, NULL)); + RINOK(unpacker.UnpackData(inStream, h.OffsetResource, h, NULL, offsetBuf, NULL)) const size_t streamInfoSize = h.IsOldVersion() ? kStreamInfoSize + 2 : kStreamInfoSize; { @@ -1087,7 +1069,7 @@ IsOldVersion = h.IsOldVersion(); IsOldVersion9 = (h.Version == 0x10900); - RINOK(ReadStreams(inStream, h, *this)); + RINOK(ReadStreams(inStream, h, *this)) bool needBootMetadata = !h.MetadataResource.IsEmpty(); unsigned numNonDeletedImages = 0; @@ -1101,14 +1083,14 @@ if (h.PartNumber != 1 || si.PartNumber != h.PartNumber) continue; - const int userImage = Images.Size() + GetStartImageIndex(); + const unsigned userImage = Images.Size() + GetStartImageIndex(); CImage &image = Images.AddNew(); SetRootNames(image, userImage); CByteBuffer &metadata = image.Meta; Byte hash[kHashSize]; - RINOK(unpacker.UnpackData(inStream, si.Resource, h, this, metadata, hash)); + RINOK(unpacker.UnpackData(inStream, si.Resource, h, this, metadata, hash)) if (memcmp(hash, si.Hash, kHashSize) != 0 && !(h.IsOldVersion() && IsEmptySha(si.Hash))) @@ -1119,7 +1101,7 @@ if (Items.IsEmpty()) Items.ClearAndReserve(numItemsReserve); - RINOK(ParseImageDirs(metadata, -1)); + RINOK(ParseImageDirs(metadata, -1)) if (needBootMetadata) { @@ -1166,12 +1148,12 @@ } -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */) { - RINOZ(MyCompare(p1->PartNumber, p2->PartNumber)); - RINOZ(MyCompare(p1->Resource.Offset, p2->Resource.Offset)); + RINOZ(MyCompare(p1->PartNumber, p2->PartNumber)) + RINOZ(MyCompare(p1->Resource.Offset, p2->Resource.Offset)) return MyCompare(p1->Resource.PackSize, p2->Resource.PackSize); } @@ -1192,11 +1174,11 @@ unsigned left = 0, right = sorted.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - unsigned streamIndex = sorted[mid]; - UInt32 id2 = streams[streamIndex].Id; + const unsigned mid = (left + right) / 2; + const unsigned streamIndex = sorted[mid]; + const UInt32 id2 = streams[streamIndex].Id; if (id == id2) - return streamIndex; + return (int)streamIndex; if (id < id2) right = mid; else @@ -1210,15 +1192,15 @@ unsigned left = 0, right = sorted.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - unsigned streamIndex = sorted[mid]; + const unsigned mid = (left + right) / 2; + const unsigned streamIndex = sorted[mid]; const Byte *hash2 = streams[streamIndex].Hash; unsigned i; for (i = 0; i < kHashSize; i++) if (hash[i] != hash2[i]) break; if (i == kHashSize) - return streamIndex; + return (int)streamIndex; if (hash[i] < hash2[i]) right = mid; else @@ -1237,8 +1219,8 @@ return i1.IsDir ? -1 : 1; if (i1.IsAltStream != i2.IsAltStream) return i1.IsAltStream ? 1 : -1; - RINOZ(MyCompare(i1.StreamIndex, i2.StreamIndex)); - RINOZ(MyCompare(i1.ImageIndex, i2.ImageIndex)); + RINOZ(MyCompare(i1.StreamIndex, i2.StreamIndex)) + RINOZ(MyCompare(i1.ImageIndex, i2.ImageIndex)) return MyCompare(i1.Offset, i2.Offset); } @@ -1286,7 +1268,7 @@ if (si.RefCount != 1) return S_FALSE; - r.SolidIndex = Solids.Size(); + r.SolidIndex = (int)Solids.Size(); CSolid &ss = Solids.AddNew(); ss.StreamIndex = k; @@ -1300,8 +1282,8 @@ const CVolume &vol = volumes[si.PartNumber]; IInStream *inStream = vol.Stream; - RINOK(inStream->Seek(r.Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, (Byte *)header, kSolidHeaderSize)); + RINOK(InStream_SeekSet(inStream, r.Offset)) + RINOK(ReadStream_FALSE(inStream, (Byte *)header, kSolidHeaderSize)) ss.UnpackSize = GetUi64(header); @@ -1313,23 +1295,21 @@ return S_FALSE; const UInt32 solidChunkSize = GetUi32(header + 8); - int log = GetLog(solidChunkSize); - if (log < 8 || log > 31) + if (!GetLog_val_min_dest(solidChunkSize, 8, ss.ChunkSizeBits)) return S_FALSE; - ss.ChunkSizeBits = log; - ss.Method = GetUi32(header + 12); + ss.Method = (Int32)GetUi32(header + 12); - UInt64 numChunks64 = (ss.UnpackSize + (((UInt32)1 << ss.ChunkSizeBits) - 1)) >> ss.ChunkSizeBits; - UInt64 sizesBufSize64 = 4 * numChunks64; + const UInt64 numChunks64 = (ss.UnpackSize + (((UInt32)1 << ss.ChunkSizeBits) - 1)) >> ss.ChunkSizeBits; + const UInt64 sizesBufSize64 = 4 * numChunks64; ss.HeadersSize = kSolidHeaderSize + sizesBufSize64; - size_t sizesBufSize = (size_t)sizesBufSize64; + const size_t sizesBufSize = (size_t)sizesBufSize64; if (sizesBufSize != sizesBufSize64) return E_OUTOFMEMORY; sizesBuf.AllocAtLeast(sizesBufSize); - RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)); + RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)) - size_t numChunks = (size_t)numChunks64; + const size_t numChunks = (size_t)numChunks64; ss.Chunks.Alloc(numChunks + 1); UInt64 offset = 0; @@ -1381,14 +1361,14 @@ CSolid &ss = Solids[solidIndex]; if (r.Offset < ss.SolidOffset) return S_FALSE; - UInt64 relat = r.Offset - ss.SolidOffset; + const UInt64 relat = r.Offset - ss.SolidOffset; if (relat > ss.UnpackSize) return S_FALSE; if (r.PackSize > ss.UnpackSize - relat) return S_FALSE; - r.SolidIndex = solidIndex; + r.SolidIndex = (int)solidIndex; if (ss.FirstSmallStream < 0) - ss.FirstSmallStream = k; + ss.FirstSmallStream = (int)k; sortedByHash.AddInReserved(k); // ss.NumRefs++; @@ -1438,7 +1418,7 @@ { { - const CStreamInfo *streams = &DataStreams.Front(); + const CStreamInfo *streams = DataStreams.ConstData(); if (IsOldVersion) { @@ -1480,7 +1460,7 @@ hash += (item.IsAltStream ? 0x8 : 0x10); UInt32 id = GetUi32(hash); if (id != 0) - item.StreamIndex = FindId(&DataStreams.Front(), sortedByHash, id); + item.StreamIndex = FindId(DataStreams.ConstData(), sortedByHash, id); } } /* @@ -1494,7 +1474,7 @@ hash += (item.IsAltStream ? 0x10 : 0x40); if (!IsEmptySha(hash)) { - item.StreamIndex = FindHash(&DataStreams.Front(), sortedByHash, hash); + item.StreamIndex = FindHash(DataStreams.ConstData(), sortedByHash, hash); } } } @@ -1517,7 +1497,7 @@ for (i = 0; i < Items.Size(); i++) { - int streamIndex = Items[i].StreamIndex; + const int streamIndex = Items[i].StreamIndex; if (streamIndex >= 0) refCounts[streamIndex]++; } @@ -1542,7 +1522,7 @@ { CItem item; item.Offset = 0; - item.StreamIndex = i; + item.StreamIndex = (int)i; item.ImageIndex = -1; Items.Add(item); ThereAreDeletedStreams = true; @@ -1591,7 +1571,7 @@ if (NumExcludededItems != 0) { - ExludedItem = startItem; + ExludedItem = (int)startItem; startItem += NumExcludededItems; } @@ -1603,7 +1583,7 @@ SortedItems.Sort(CompareItems, this); for (i = 0; i < SortedItems.Size(); i++) - Items[SortedItems[i]].IndexInSorted = i; + Items[SortedItems[i]].IndexInSorted = (int)i; if (showImageNumber) for (i = 0; i < Images.Size(); i++) @@ -1611,7 +1591,7 @@ CImage &image = Images[i]; if (image.NumEmptyRootItems != 0) continue; - image.VirtualRootIndex = VirtualRoots.Size(); + image.VirtualRootIndex = (int)VirtualRoots.Size(); VirtualRoots.Add(i); } @@ -1681,7 +1661,7 @@ if ((unpacker.TotalPacked - totalPackedPrev) >= ((UInt32)1 << 16)) { UInt64 numFiles = Items.Size(); - RINOK(openCallback->SetCompleted(&numFiles, &unpacker.TotalPacked)); + RINOK(openCallback->SetCompleted(&numFiles, &unpacker.TotalPacked)) totalPackedPrev = unpacker.TotalPacked; } } @@ -1715,7 +1695,7 @@ if (res == S_FALSE) continue; - RINOK(res); + RINOK(res) if (memcmp(digest, si.Hash, kHashSize) != 0 // && !(h.IsOldVersion() && IsEmptySha(si.Hash)) @@ -1729,11 +1709,11 @@ CByteBuffer &reparse = ReparseItems.AddNew(); reparse.Alloc(8 + buf.Size()); Byte *dest = (Byte *)reparse; - SetUi32(dest, tag); - SetUi32(dest + 4, (UInt32)buf.Size()); + SetUi32(dest, tag) + SetUi32(dest + 4, (UInt32)buf.Size()) if (buf.Size() != 0) memcpy(dest + 8, buf, buf.Size()); - ItemToReparse[itemIndex] = ReparseItems.Size() - 1; + ItemToReparse[itemIndex] = (int)ReparseItems.Size() - 1; } return S_OK; @@ -1772,13 +1752,12 @@ static bool ParseTime(const CXmlItem &item, FILETIME &ft, const char *tag) { - int index = item.FindSubTag(tag); - if (index >= 0) + const CXmlItem *timeItem = item.FindSubTag_GetPtr(tag); + if (timeItem) { - const CXmlItem &timeItem = item.SubItems[index]; UInt32 low = 0, high = 0; - if (ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low) && - ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high)) + if (ParseNumber32(timeItem->GetSubStringForTag("LOWPART"), low) && + ParseNumber32(timeItem->GetSubStringForTag("HIGHPART"), high)) { ft.dwLowDateTime = low; ft.dwHighDateTime = high; @@ -1835,7 +1814,7 @@ if (!Xml.Parse(utf)) return false; - if (Xml.Root.Name != "WIM") + if (!Xml.Root.Name.IsEqualTo("WIM")) return false; FOR_VECTOR (i, Xml.Root.SubItems) @@ -1856,7 +1835,7 @@ return false; } - imageInfo.ItemIndexInXml = i; + imageInfo.ItemIndexInXml = (int)i; Images.Add(imageInfo); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Wim/WimIn.h 2018-12-28 10:40:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Wim/WimIn.h 2024-01-01 09:00:00.000000000 +0000 @@ -1,10 +1,11 @@ // Archive/WimIn.h -#ifndef __ARCHIVE_WIM_IN_H -#define __ARCHIVE_WIM_IN_H +#ifndef ZIP7_INC_ARCHIVE_WIM_IN_H +#define ZIP7_INC_ARCHIVE_WIM_IN_H #include "../../../../C/Alloc.h" +#include "../../../Common/AutoPtr.h" #include "../../../Common/MyBuffer.h" #include "../../../Common/MyXml.h" @@ -192,7 +193,7 @@ UInt64 UnpackSize; int Method; - int ChunkSizeBits; + unsigned ChunkSizeBits; UInt64 HeadersSize; // size_t NumChunks; @@ -258,8 +259,8 @@ UInt32 NumImages; UInt32 BootIndex; - bool _IsOldVersion; // 1.10- - bool _IsNewVersion; // 1.13+ or 0.14 + bool _isOldVersion; // 1.10- + bool _isNewVersion; // 1.13+ or 0.14 CResource OffsetResource; CResource XmlResource; @@ -295,8 +296,8 @@ return mask; } - bool IsOldVersion() const { return _IsOldVersion; } - bool IsNewVersion() const { return _IsNewVersion; } + bool IsOldVersion() const { return _isOldVersion; } + bool IsNewVersion() const { return _isNewVersion; } bool IsSolidVersion() const { return (Version == k_Version_Solid); } bool AreFromOnArchive(const CHeader &h) @@ -457,7 +458,7 @@ bool RefCountError; bool HeadersError; - bool GetStartImageIndex() const { return IsOldVersion9 ? 0 : 1; } + unsigned GetStartImageIndex() const { return IsOldVersion9 ? 0 : 1; } unsigned GetDirAlignMask() const { return IsOldVersion9 ? 3 : 7; } // User Items can contain all images or just one image from all. @@ -583,27 +584,23 @@ { if (size > _size) { - ::MidFree(Data); + ::z7_AlignedFree(Data); _size = 0; - Data = (Byte *)::MidAlloc(size); + Data = (Byte *)::z7_AlignedAlloc(size); if (Data) _size = size; } } - ~CMidBuf() { ::MidFree(Data); } + ~CMidBuf() { ::z7_AlignedFree(Data); } }; class CUnpacker { - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr copyCoder; - - NCompress::NLzx::CDecoder *lzxDecoderSpec; - CMyComPtr lzxDecoder; - - NCompress::NLzms::CDecoder *lzmsDecoder; + CMyComPtr2 copyCoder; + CMyUniquePtr lzxDecoder; + CMyUniquePtr lzmsDecoder; CByteBuffer sizesBuf; @@ -637,7 +634,6 @@ _unpackedChunkIndex(0), TotalPacked(0) {} - ~CUnpacker(); HRESULT Unpack( IInStream *inStream, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/XarHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XarHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/XarHandler.cpp 2021-09-04 11:14:58.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XarHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../C/Sha256.h" +#include "../../../C/Sha512.h" #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" @@ -36,102 +38,279 @@ namespace NArchive { namespace NXar { -static const size_t kXmlSizeMax = ((size_t )1 << 30) - (1 << 14); +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithSha256 + , ISequentialInStream +) + bool _sha512Mode; + CMyComPtr _stream; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; + UInt64 _size; + + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } +public: + CInStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init(bool sha512Mode) + { + _sha512Mode = sha512Mode; + _size = 0; + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } +}; + +Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, realProcessedSize); + else + Sha256_Update(Sha256(), (const Byte *)data, realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSha256 + , ISequentialOutStream +) + bool _sha512Mode; + CMyComPtr _stream; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; + UInt64 _size; + + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } +public: + COutStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool sha512Mode) + { + _sha512Mode = sha512Mode; + _size = 0; + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); + } + UInt64 GetSize() const { return _size; } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } +}; + +Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + // if (_calculate) + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, size); + else + Sha256_Update(Sha256(), (const Byte *)data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +// we limit supported xml sizes: +// ((size_t)1 << (sizeof(size_t) / 2 + 28)) - (1u << 14); +static const size_t kXmlSizeMax = ((size_t)1 << 30) - (1u << 14); static const size_t kXmlPackSizeMax = kXmlSizeMax; -/* -#define XAR_CKSUM_NONE 0 -#define XAR_CKSUM_SHA1 1 -#define XAR_CKSUM_MD5 2 +#define XAR_CKSUM_NONE 0 +#define XAR_CKSUM_SHA1 1 +#define XAR_CKSUM_MD5 2 +#define XAR_CKSUM_SHA256 3 +#define XAR_CKSUM_SHA512 4 +// #define XAR_CKSUM_OTHER 3 +// fork version of xar can use (3) as special case, +// where name of hash is stored as string at the end of header +// we do not support such hash still. -static const char * const k_ChecksumAlgos[] = +static const char * const k_ChecksumNames[] = { - "None" - , "SHA-1" + "NONE" + , "SHA1" , "MD5" + , "SHA256" + , "SHA512" }; -*/ -#define METHOD_NAME_ZLIB "zlib" +static unsigned GetHashSize(int algo) +{ + if (algo <= XAR_CKSUM_NONE || algo > XAR_CKSUM_SHA512) + return 0; + if (algo == XAR_CKSUM_SHA1) + return SHA1_DIGEST_SIZE; + return (16u >> XAR_CKSUM_MD5) << algo; +} + +#define METHOD_NAME_ZLIB "zlib" + +static int Find_ChecksumId_for_Name(const AString &style) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ChecksumNames); i++) + { + // old xars used upper case in "style" + // new xars use lower case in "style" + if (style.IsEqualTo_Ascii_NoCase(k_ChecksumNames[i])) + return (int)i; + } + return -1; +} + + +struct CCheckSum +{ + int AlgoNumber; + bool Error; + CByteBuffer Data; + AString Style; + + CCheckSum(): AlgoNumber(-1), Error(false) {} + void AddNameToString(AString &s) const; +}; + +void CCheckSum::AddNameToString(AString &s) const +{ + if (Style.IsEmpty()) + s.Add_OptSpaced("NO-CHECKSUM"); + else + { + s.Add_OptSpaced(Style); + if (Error) + s += "-ERROR"; + } +} struct CFile { - AString Name; - AString Method; + bool IsDir; + bool Is_SymLink; + bool HasData; + bool Mode_Defined; + bool INode_Defined; + bool UserId_Defined; + bool GroupId_Defined; + // bool Device_Defined; + bool Id_Defined; + + int Parent; + UInt32 Mode; + UInt64 Size; UInt64 PackSize; UInt64 Offset; - - UInt64 CTime; UInt64 MTime; + UInt64 CTime; UInt64 ATime; - UInt32 Mode; + UInt64 INode; + UInt64 UserId; + UInt64 GroupId; + // UInt64 Device; + AString Name; + AString Method; AString User; AString Group; + // AString Id; + AString Type; + AString Link; + // AString LinkType; + // AString LinkFrom; - bool IsDir; - bool HasData; - bool ModeDefined; - bool Sha1IsDefined; - // bool packSha1IsDefined; - - Byte Sha1[SHA1_DIGEST_SIZE]; - // Byte packSha1[SHA1_DIGEST_SIZE]; - - int Parent; - - CFile(): + UInt64 Id; + CCheckSum extracted_checksum; + CCheckSum archived_checksum; + + CFile(int parent): + IsDir(false), + Is_SymLink(false), + HasData(false), + Mode_Defined(false), + INode_Defined(false), + UserId_Defined(false), + GroupId_Defined(false), + // Device_Defined(false), + Id_Defined(false), + Parent(parent), + Mode(0), Size(0), PackSize(0), Offset(0), - CTime(0), MTime(0), ATime(0), Mode(0), - IsDir(false), HasData(false), ModeDefined(false), Sha1IsDefined(false), - /* packSha1IsDefined(false), */ - Parent(-1) + MTime(0), CTime(0), ATime(0), + INode(0) {} bool IsCopyMethod() const { - return Method.IsEmpty() || Method == "octet-stream"; + return Method.IsEmpty() || Method.IsEqualTo("octet-stream"); } void UpdateTotalPackSize(UInt64 &totalSize) const { - UInt64 t = Offset + PackSize; + const UInt64 t = Offset + PackSize; + if (t >= Offset) if (totalSize < t) - totalSize = t; + totalSize = t; } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - UInt64 _dataStartPos; - CMyComPtr _inStream; - CByteArr _xml; - size_t _xmlLen; + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IArchiveGetRawProps, + IInArchiveGetStream +) + bool _is_pkg; + bool _toc_CrcError; CObjectVector _files; - // UInt32 _checkSumAlgo; + CMyComPtr _inStream; + UInt64 _dataStartPos; UInt64 _phySize; + CAlignedBuffer _xmlBuf; + size_t _xmlLen; + // UInt64 CreationTime; + AString CreationTime_String; + UInt32 _checkSumAlgo; Int32 _mainSubfile; - bool _is_pkg; HRESULT Open2(IInStream *stream); - HRESULT Extract(IInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; + static const Byte kArcProps[] = { kpidSubType, - kpidHeadersSize + // kpidHeadersSize, + kpidMethod, + kpidCTime }; +// #define kpidLinkType 250 +// #define kpidLinkFrom 251 + static const Byte kProps[] = { kpidPath, @@ -141,19 +320,25 @@ kpidCTime, kpidATime, kpidPosixAttrib, + kpidType, kpidUser, kpidGroup, - kpidMethod + kpidUserId, + kpidGroupId, + kpidINode, + // kpidDeviceMajor, + // kpidDeviceMinor, + kpidSymLink, + // kpidLinkType, + // kpidLinkFrom, + kpidMethod, + kpidId, + kpidOffset }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -#define PARSE_NUM(_num_, _dest_) \ - { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ - if ((unsigned)(end - p) != _num_) return 0; \ - p += _num_ + 1; } - static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) { const AString s (item.GetSubStringForTag(name)); @@ -164,14 +349,26 @@ return *end == 0; } -static UInt64 ParseTime(const CXmlItem &item, const char *name) + +#define PARSE_NUM(_num_, _dest_) \ + { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ + if ((unsigned)(end - p) != _num_) return 0; \ + p += _num_ + 1; } + +static UInt64 ParseTime(const CXmlItem &item, const char *name /* , bool z_isRequired */ ) { const AString s (item.GetSubStringForTag(name)); - if (s.Len() < 20) + if (s.Len() < 20 /* (z_isRequired ? 20u : 19u) */) return 0; const char *p = s; - if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || - p[13] != ':' || p[16] != ':' || p[19] != 'Z') + if (p[ 4] != '-' || + p[ 7] != '-' || + p[10] != 'T' || + p[13] != ':' || + p[16] != ':') + return 0; + // if (z_isRequired) + if (p[19] != 'Z') return 0; UInt32 year, month, day, hour, min, sec; PARSE_NUM(4, year) @@ -180,177 +377,269 @@ PARSE_NUM(2, hour) PARSE_NUM(2, min) PARSE_NUM(2, sec) - UInt64 numSecs; if (!NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) return 0; return numSecs * 10000000; } -static int HexToByte(unsigned char c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - return -1; -} -static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) +static void ParseChecksum(const CXmlItem &item, const char *name, CCheckSum &checksum) { - int index = item.FindSubTag(name); - if (index < 0) - return false; - const CXmlItem &checkItem = item.SubItems[index]; - const AString style (checkItem.GetPropVal("style")); - if (style == "SHA1") + const CXmlItem *checkItem = item.FindSubTag_GetPtr(name); + if (!checkItem) + return; // false; + checksum.Style = checkItem->GetPropVal("style"); + const AString s (checkItem->GetSubString()); + if ((s.Len() & 1) == 0 && s.Len() <= (2u << 7)) // 1024-bit max { - const AString s (checkItem.GetSubString()); - if (s.Len() != SHA1_DIGEST_SIZE * 2) - return false; - for (unsigned i = 0; i < s.Len(); i += 2) + const size_t size = s.Len() / 2; + CByteBuffer temp(size); + if ((size_t)(ParseHexString(s, temp) - temp) == size) { - int b0 = HexToByte(s[i]); - int b1 = HexToByte(s[i + 1]); - if (b0 < 0 || b1 < 0) - return false; - digest[i / 2] = (Byte)((b0 << 4) | b1); + checksum.Data = temp; + const int index = Find_ChecksumId_for_Name(checksum.Style); + if (index >= 0 && checksum.Data.Size() == GetHashSize(index)) + { + checksum.AlgoNumber = index; + return; + } } - return true; } - return false; + checksum.Error = true; } -static bool AddItem(const CXmlItem &item, CObjectVector &files, int parent) + +static bool AddItem(const CXmlItem &item, CObjectVector &files, int parent, int level) { if (!item.IsTag) return true; - if (item.Name == "file") + if (level >= 1024) + return false; + if (item.Name.IsEqualTo("file")) { - CFile file; - file.Parent = parent; - parent = files.Size(); + CFile file(parent); + parent = (int)files.Size(); + { + const AString id = item.GetPropVal("id"); + const char *end; + file.Id = ConvertStringToUInt64(id, &end); + if (*end == 0) + file.Id_Defined = true; + } file.Name = item.GetSubStringForTag("name"); - const AString type (item.GetSubStringForTag("type")); - if (type == "directory") - file.IsDir = true; - else if (type == "file") - file.IsDir = false; - else - return false; + z7_xml_DecodeString(file.Name); + { + const CXmlItem *typeItem = item.FindSubTag_GetPtr("type"); + if (typeItem) + { + file.Type = typeItem->GetSubString(); + // file.LinkFrom = typeItem->GetPropVal("link"); + if (file.Type.IsEqualTo("directory")) + file.IsDir = true; + else + { + // file.IsDir = false; + /* + else if (file.Type.IsEqualTo("file")) + {} + else if (file.Type.IsEqualTo("hardlink")) + {} + else + */ + if (file.Type.IsEqualTo("symlink")) + file.Is_SymLink = true; + // file.IsDir = false; + } + } + } + { + const CXmlItem *linkItem = item.FindSubTag_GetPtr("link"); + if (linkItem) + { + // file.LinkType = linkItem->GetPropVal("type"); + file.Link = linkItem->GetSubString(); + z7_xml_DecodeString(file.Link); + } + } - int dataIndex = item.FindSubTag("data"); - if (dataIndex >= 0 && !file.IsDir) + const CXmlItem *dataItem = item.FindSubTag_GetPtr("data"); + if (dataItem && !file.IsDir) { file.HasData = true; - const CXmlItem &dataItem = item.SubItems[dataIndex]; - if (!ParseUInt64(dataItem, "size", file.Size)) + if (!ParseUInt64(*dataItem, "size", file.Size)) return false; - if (!ParseUInt64(dataItem, "length", file.PackSize)) + if (!ParseUInt64(*dataItem, "length", file.PackSize)) return false; - if (!ParseUInt64(dataItem, "offset", file.Offset)) + if (!ParseUInt64(*dataItem, "offset", file.Offset)) return false; - file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); - // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); - int encodingIndex = dataItem.FindSubTag("encoding"); - if (encodingIndex >= 0) + ParseChecksum(*dataItem, "extracted-checksum", file.extracted_checksum); + ParseChecksum(*dataItem, "archived-checksum", file.archived_checksum); + const CXmlItem *encodingItem = dataItem->FindSubTag_GetPtr("encoding"); + if (encodingItem) { - const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; - if (encodingItem.IsTag) + AString s (encodingItem->GetPropVal("style")); + if (!s.IsEmpty()) { - AString s (encodingItem.GetPropVal("style")); - if (!s.IsEmpty()) + const AString appl ("application/"); + if (s.IsPrefixedBy(appl)) { - const AString appl ("application/"); - if (s.IsPrefixedBy(appl)) + s.DeleteFrontal(appl.Len()); + const AString xx ("x-"); + if (s.IsPrefixedBy(xx)) { - s.DeleteFrontal(appl.Len()); - const AString xx ("x-"); - if (s.IsPrefixedBy(xx)) - { - s.DeleteFrontal(xx.Len()); - if (s == "gzip") - s = METHOD_NAME_ZLIB; - } + s.DeleteFrontal(xx.Len()); + if (s.IsEqualTo("gzip")) + s = METHOD_NAME_ZLIB; } - file.Method = s; } + file.Method = s; } } } + file.INode_Defined = ParseUInt64(item, "inode", file.INode); + file.UserId_Defined = ParseUInt64(item, "uid", file.UserId); + file.GroupId_Defined = ParseUInt64(item, "gid", file.GroupId); + // file.Device_Defined = ParseUInt64(item, "deviceno", file.Device); + file.MTime = ParseTime(item, "mtime"); // z_IsRequied = true file.CTime = ParseTime(item, "ctime"); - file.MTime = ParseTime(item, "mtime"); file.ATime = ParseTime(item, "atime"); - { const AString s (item.GetSubStringForTag("mode")); if (s[0] == '0') { const char *end; file.Mode = ConvertOctStringToUInt32(s, &end); - file.ModeDefined = (*end == 0); + file.Mode_Defined = (*end == 0); } } - file.User = item.GetSubStringForTag("user"); file.Group = item.GetSubStringForTag("group"); files.Add(file); } + FOR_VECTOR (i, item.SubItems) - if (!AddItem(item.SubItems[i], files, parent)) + if (!AddItem(item.SubItems[i], files, parent, level + 1)) return false; return true; } -HRESULT CHandler::Open2(IInStream *stream) + + +struct CInStreamWithHash { - const UInt32 kHeaderSize = 0x1C; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - - UInt32 size = Get16(buf + 4); - // UInt32 ver = Get16(buf + 6); // == 1 - if (Get32(buf) != 0x78617221 || size != kHeaderSize) - return S_FALSE; + CMyComPtr2_Create inStreamSha1; + CMyComPtr2_Create inStreamSha256; + CMyComPtr2_Create inStreamLim; + + void SetStreamAndInit(ISequentialInStream *stream, int algo); + bool CheckHash(int algo, const Byte *digest_from_arc) const; +}; - UInt64 packSize = Get64(buf + 8); - UInt64 unpackSize = Get64(buf + 0x10); - // _checkSumAlgo = Get32(buf + 0x18); +void CInStreamWithHash::SetStreamAndInit(ISequentialInStream *stream, int algo) +{ + if (algo == XAR_CKSUM_SHA1) + { + inStreamSha1->SetStream(stream); + inStreamSha1->Init(); + stream = inStreamSha1; + } + else if (algo == XAR_CKSUM_SHA256 + || algo == XAR_CKSUM_SHA512) + { + inStreamSha256->SetStream(stream); + inStreamSha256->Init(algo == XAR_CKSUM_SHA512); + stream = inStreamSha256; + } + inStreamLim->SetStream(stream); +} +bool CInStreamWithHash::CheckHash(int algo, const Byte *digest_from_arc) const +{ + if (algo == XAR_CKSUM_SHA1) + { + Byte digest[SHA1_DIGEST_SIZE]; + inStreamSha1->Final(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + else if (algo == XAR_CKSUM_SHA256) + { + Byte digest[SHA256_DIGEST_SIZE]; + inStreamSha256->Final256(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + else if (algo == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + inStreamSha256->Final512(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + return true; +} + + +HRESULT CHandler::Open2(IInStream *stream) +{ + const unsigned kHeaderSize = 28; + UInt32 buf32[kHeaderSize / sizeof(UInt32)]; + RINOK(ReadStream_FALSE(stream, buf32, kHeaderSize)) + const unsigned headerSize = Get16((const Byte *)(const void *)buf32 + 4); + // xar library now writes 1 to version field. + // some old xars could have version == 0 ? + // specification allows (headerSize != 28), + // but we don't expect big value in (headerSize). + // so we restrict (headerSize) with 64 bytes to reduce false open. + const unsigned kHeaderSize_MAX = 64; + if (Get32(buf32) != 0x78617221 // signature: "xar!" + || headerSize < kHeaderSize + || headerSize > kHeaderSize_MAX + || Get16((const Byte *)(const void *)buf32 + 6) > 1 // version + ) + return S_FALSE; + _checkSumAlgo = Get32(buf32 + 6); + const UInt64 packSize = Get64(buf32 + 2); + const UInt64 unpackSize = Get64(buf32 + 4); if (packSize >= kXmlPackSizeMax || unpackSize >= kXmlSizeMax) return S_FALSE; - - _dataStartPos = kHeaderSize + packSize; + /* some xar archives can have padding bytes at offset 28, + or checksum algorithm name at offset 28 (in xar fork, if cksum_alg==3) + But we didn't see such xar archives. + */ + if (headerSize != kHeaderSize) + { + RINOK(InStream_SeekSet(stream, headerSize)) + } + _dataStartPos = headerSize + packSize; _phySize = _dataStartPos; - _xml.Alloc((size_t)unpackSize + 1); + _xmlBuf.Alloc((size_t)unpackSize + 1); + if (!_xmlBuf.IsAllocated()) + return E_OUTOFMEMORY; _xmlLen = (size_t)unpackSize; - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLim(inStreamLimSpec); - inStreamLimSpec->SetStream(stream); - inStreamLimSpec->Init(packSize); - - CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream; - CMyComPtr outStreamLim(outStreamLimSpec); - outStreamLimSpec->Init(_xml, (size_t)unpackSize); - - RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL)); - - if (outStreamLimSpec->GetPos() != (size_t)unpackSize) + CInStreamWithHash hashStream; + { + CMyComPtr2_Create zlibCoder; + hashStream.SetStreamAndInit(stream, (int)(unsigned)_checkSumAlgo); + hashStream.inStreamLim->Init(packSize); + CMyComPtr2_Create outStreamLim; + outStreamLim->Init(_xmlBuf, (size_t)unpackSize); + RINOK(zlibCoder.Interface()->Code(hashStream.inStreamLim, outStreamLim, NULL, &unpackSize, NULL)) + if (outStreamLim->GetPos() != (size_t)unpackSize) + return S_FALSE; + } + _xmlBuf[(size_t)unpackSize] = 0; + if (strlen((const char *)(const Byte *)_xmlBuf) != (size_t)unpackSize) return S_FALSE; - - _xml[(size_t)unpackSize] = 0; - if (strlen((const char *)(const Byte *)_xml) != unpackSize) return S_FALSE; - CXml xml; - if (!xml.Parse((const char *)(const Byte *)_xml)) + if (!xml.Parse((const char *)(const Byte *)_xmlBuf)) return S_FALSE; if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1) @@ -358,7 +647,40 @@ const CXmlItem &toc = xml.Root.SubItems[0]; if (!toc.IsTagged("toc")) return S_FALSE; - if (!AddItem(toc, _files, -1)) + + // CreationTime = ParseTime(toc, "creation-time", false); // z_IsRequied + CreationTime_String = toc.GetSubStringForTag("creation-time"); + { + // we suppose that offset of checksum is always 0; + // but [TOC].xml contains exact offset value in block. + const UInt64 offset = 0; + const unsigned hashSize = GetHashSize((int)(unsigned)_checkSumAlgo); + if (hashSize) + { + /* + const CXmlItem *csItem = toc.FindSubTag_GetPtr("checksum"); + if (csItem) + { + const int checkSumAlgo2 = Find_ChecksumId_for_Name(csItem->GetPropVal("style")); + UInt64 csSize, csOffset; + if (ParseUInt64(*csItem, "size", csSize) && + ParseUInt64(*csItem, "offset", csOffset) && + csSize == hashSize && + (unsigned)checkSumAlgo2 == _checkSumAlgo) + offset = csOffset; + } + */ + CByteBuffer digest_from_arc(hashSize); + RINOK(InStream_SeekSet(stream, _dataStartPos + offset)) + RINOK(ReadStream_FALSE(stream, digest_from_arc, hashSize)) + if (!hashStream.CheckHash((int)(unsigned)_checkSumAlgo, digest_from_arc)) + _toc_CrcError = true; + } + } + + if (!AddItem(toc, _files, + -1, // parent + 0)) // level return S_FALSE; UInt64 totalPackSize = 0; @@ -368,56 +690,67 @@ { const CFile &file = _files[i]; file.UpdateTotalPackSize(totalPackSize); - if (file.Name == "Payload" || file.Name == "Content") + if (file.Parent == -1) { - _mainSubfile = i; - numMainFiles++; + if (file.Name.IsEqualTo("Payload") || + file.Name.IsEqualTo("Content")) + { + _mainSubfile = (Int32)(int)i; + numMainFiles++; + } + else if (file.Name.IsEqualTo("PackageInfo")) + _is_pkg = true; } - else if (file.Name == "PackageInfo") - _is_pkg = true; } if (numMainFiles > 1) _mainSubfile = -1; - - _phySize = _dataStartPos + totalPackSize; + + const UInt64 k_PhySizeLim = (UInt64)1 << 62; + _phySize = (totalPackSize > k_PhySizeLim - _dataStartPos) ? + k_PhySizeLim : + _dataStartPos + totalPackSize; return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) + IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN { Close(); - if (Open2(stream) != S_OK) - return S_FALSE; + RINOK(Open2(stream)) _inStream = stream; } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _phySize = 0; + _dataStartPos = 0; _inStream.Release(); _files.Clear(); _xmlLen = 0; - _xml.Free(); + _xmlBuf.Free(); _mainSubfile = -1; _is_pkg = false; + _toc_CrcError = false; + _checkSumAlgo = 0; + // CreationTime = 0; + CreationTime_String.Empty(); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _files.Size() - #ifdef XAR_SHOW_RAW +#ifdef XAR_SHOW_RAW + 1 - #endif +#endif ; return S_OK; } @@ -443,85 +776,189 @@ } } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; switch (propID) { - case kpidHeadersSize: prop = _dataStartPos; break; + // case kpidHeadersSize: prop = _dataStartPos; break; case kpidPhySize: prop = _phySize; break; case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; case kpidSubType: if (_is_pkg) prop = "pkg"; break; case kpidExtension: prop = _is_pkg ? "pkg" : "xar"; break; + case kpidCTime: + { + // it's local time. We can transfer it to UTC time, if we use FILETIME. + // TimeToProp(CreationTime, prop); break; + if (!CreationTime_String.IsEmpty()) + prop = CreationTime_String; + break; + } + case kpidMethod: + { + AString s; + if (_checkSumAlgo < Z7_ARRAY_SIZE(k_ChecksumNames)) + s = k_ChecksumNames[_checkSumAlgo]; + else + { + s += "Checksum"; + s.Add_UInt32(_checkSumAlgo); + } + prop = s; + break; + } + case kpidWarningFlags: + { + UInt32 v = 0; + if (_toc_CrcError) v |= kpv_ErrorFlags_CrcError; + prop = v; + break; + } + case kpidINode: prop = true; break; + case kpidIsTree: prop = true; break; } prop.Detach(value); return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) + +/* +inline UInt32 MY_dev_major(UInt64 dev) +{ + return ((UInt32)(dev >> 8) & (UInt32)0xfff) | ((UInt32)(dev >> 32) & ~(UInt32)0xfff); +} +inline UInt32 MY_dev_minor(UInt64 dev) +{ + return ((UInt32)(dev) & 0xff) | ((UInt32)(dev >> 12) & ~(UInt32)0xff); +} +*/ + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) { switch (propID) { - case kpidPath: prop = "[TOC].xml"; break; + case kpidName: + case kpidPath: + prop = "[TOC].xml"; break; case kpidSize: case kpidPackSize: prop = (UInt64)_xmlLen; break; } } else - #endif +#endif { const CFile &item = _files[index]; switch (propID) { - case kpidMethod: Utf8StringToProp(item.Method, prop); break; - case kpidPath: { AString path; - int cur = index; - do + unsigned cur = index; + for (;;) { const CFile &item2 = _files[cur]; if (!path.IsEmpty()) path.InsertAtFront(CHAR_PATH_SEPARATOR); +// #define XAR_EMPTY_NAME_REPLACEMENT "[]" if (item2.Name.IsEmpty()) - path.Insert(0, "unknown"); + { + AString s('['); + s.Add_UInt32(cur); + s.Add_Char(']'); + path.Insert(0, s); + } else path.Insert(0, item2.Name); - cur = item2.Parent; + if (item2.Parent < 0) + break; + cur = (unsigned)item2.Parent; } - while (cur >= 0); - Utf8StringToProp(path, prop); break; } - + + case kpidName: + { + if (item.Name.IsEmpty()) + { + AString s('['); + s.Add_UInt32(index); + s.Add_Char(']'); + prop = s; + } + else + Utf8StringToProp(item.Name, prop); + break; + } + case kpidIsDir: prop = item.IsDir; break; - case kpidSize: if (!item.IsDir) prop = item.Size; break; - case kpidPackSize: if (!item.IsDir) prop = item.PackSize; break; + case kpidSize: if (item.HasData && !item.IsDir) prop = item.Size; break; + case kpidPackSize: if (item.HasData && !item.IsDir) prop = item.PackSize; break; + + case kpidMethod: + { + if (item.HasData) + { + AString s = item.Method; + item.extracted_checksum.AddNameToString(s); + item.archived_checksum.AddNameToString(s); + Utf8StringToProp(s, prop); + } + break; + } + case kpidMTime: TimeToProp(item.MTime, prop); break; case kpidCTime: TimeToProp(item.CTime, prop); break; case kpidATime: TimeToProp(item.ATime, prop); break; + case kpidPosixAttrib: - if (item.ModeDefined) + if (item.Mode_Defined) { UInt32 mode = item.Mode; if ((mode & MY_LIN_S_IFMT) == 0) - mode |= (item.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG); + mode |= ( + item.Is_SymLink ? MY_LIN_S_IFLNK : + item.IsDir ? MY_LIN_S_IFDIR : + MY_LIN_S_IFREG); prop = mode; } break; - case kpidUser: Utf8StringToProp(item.User, prop); break; + + case kpidType: Utf8StringToProp(item.Type, prop); break; + case kpidUser: Utf8StringToProp(item.User, prop); break; case kpidGroup: Utf8StringToProp(item.Group, prop); break; + case kpidSymLink: if (item.Is_SymLink) Utf8StringToProp(item.Link, prop); break; + + case kpidUserId: if (item.UserId_Defined) prop = item.UserId; break; + case kpidGroupId: if (item.GroupId_Defined) prop = item.GroupId; break; + case kpidINode: if (item.INode_Defined) prop = item.INode; break; + case kpidId: if (item.Id_Defined) prop = item.Id; break; + // Utf8StringToProp(item.Id, prop); + /* + case kpidDeviceMajor: if (item.Device_Defined) prop = (UInt32)MY_dev_major(item.Device); break; + case kpidDeviceMinor: if (item.Device_Defined) prop = (UInt32)MY_dev_minor(item.Device); break; + case kpidLinkType: + if (!item.LinkType.IsEmpty()) + Utf8StringToProp(item.LinkType, prop); + break; + case kpidLinkFrom: + if (!item.LinkFrom.IsEmpty()) + Utf8StringToProp(item.LinkFrom, prop); + break; + */ + case kpidOffset: + if (item.HasData) + prop = _dataStartPos + item.Offset; + break; } } prop.Detach(value); @@ -529,143 +966,264 @@ COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) + +// for debug: +// #define Z7_XAR_SHOW_CHECKSUM_PACK + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK +enum +{ + kpidChecksumPack = kpidUserDefined +}; +#endif + +static const Byte kRawProps[] = +{ + kpidChecksum +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + , kpidCRC // instead of kpidUserDefined / kpidCRC +#endif +}; + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + if (index != 0) + { + *propID = kpidChecksumPack; + *name = NWindows::NCOM::AllocBstrFromAscii("archived-checksum"); + } +#endif + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + return S_OK; +#endif + { + const CFile &item = _files[index]; + *parent = (UInt32)(Int32)item.Parent; + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + // COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (propID == kpidChecksum) + { +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + // case kpidPath: prop = "[TOC].xml"; break; + } + else +#endif + { + const CFile &item = _files[index]; + const size_t size = item.extracted_checksum.Data.Size(); + if (size != 0) + { + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + *data = item.extracted_checksum.Data; + } + } + } + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + if (propID == kpidChecksumPack) + { +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + // we can show digest check sum here + } + else +#endif + { + const CFile &item = _files[index]; + const size_t size = (UInt32)item.archived_checksum.Data.Size(); + if (size != 0) + { + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + *data = item.archived_checksum.Data; + } + } + } +#endif + return S_OK; +} + + + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) - numItems = _files.Size(); + numItems = _files.Size() +#ifdef XAR_SHOW_RAW + + 1 +#endif + ; if (numItems == 0) return S_OK; UInt64 totalSize = 0; UInt32 i; for (i = 0; i < numItems; i++) { - UInt32 index = (allFilesMode ? i : indices[i]); - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) + const UInt32 index = allFilesMode ? i : indices[i]; +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) totalSize += _xmlLen; else - #endif +#endif totalSize += _files[index].Size; } - extractCallback->SetTotal(totalSize); - - UInt64 currentPackTotal = 0; - UInt64 currentUnpTotal = 0; - UInt64 currentPackSize = 0; - UInt64 currentUnpSize = 0; - - const UInt32 kZeroBufSize = (1 << 14); - CByteBuffer zeroBuf(kZeroBufSize); - memset(zeroBuf, 0, kZeroBufSize); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; + RINOK(extractCallback->SetTotal(totalSize)) - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - CMyComPtr bzip2Coder = bzip2CoderSpec; - - NCompress::NDeflate::NDecoder::CCOMCoder *deflateCoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder(); - CMyComPtr deflateCoder = deflateCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - - CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(inStreamSpec); - inStreamSpec->SetStream(_inStream); - + CInStreamWithHash inHashStream; + CMyComPtr2_Create outStreamSha1; + CMyComPtr2_Create outStreamSha256; + CMyComPtr2_Create outStreamLim; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create zlibCoder; + CMyComPtr2_Create bzip2Coder; + bzip2Coder->FinishMode = true; - CLimitedSequentialOutStream *outStreamLimSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamLimSpec); + UInt64 cur_PackSize, cur_UnpSize; - COutStreamWithSha1 *outStreamSha1Spec = new COutStreamWithSha1; + for (i = 0;; i++, + lps->InSize += cur_PackSize, + lps->OutSize += cur_UnpSize) { - CMyComPtr outStreamSha1(outStreamSha1Spec); - outStreamLimSpec->SetStream(outStreamSha1); - } + cur_PackSize = 0; + cur_UnpSize = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + break; - for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) - { - lps->InSize = currentPackTotal; - lps->OutSize = currentUnpTotal; - currentPackSize = 0; - currentUnpSize = 0; - RINOK(lps->SetCur()); CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (index < _files.Size()) { const CFile &item = _files[index]; if (item.IsDir) { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) continue; } } if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSha1Spec->SetStream(realOutStream); - realOutStream.Release(); + RINOK(extractCallback->PrepareOperation(askMode)) Int32 opRes = NExtract::NOperationResult::kOK; - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) + +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) { - outStreamSha1Spec->Init(false); - outStreamLimSpec->Init(_xmlLen); - RINOK(WriteStream(outStream, _xml, _xmlLen)); - currentPackSize = currentUnpSize = _xmlLen; + cur_PackSize = cur_UnpSize = _xmlLen; + if (realOutStream) + RINOK(WriteStream(realOutStream, _xmlBuf, _xmlLen)) + realOutStream.Release(); } else - #endif +#endif { const CFile &item = _files[index]; - if (item.HasData) + if (!item.HasData) + realOutStream.Release(); + else { - currentPackSize = item.PackSize; - currentUnpSize = item.Size; + cur_PackSize = item.PackSize; + cur_UnpSize = item.Size; - RINOK(_inStream->Seek(_dataStartPos + item.Offset, STREAM_SEEK_SET, NULL)); - inStreamSpec->Init(item.PackSize); - outStreamSha1Spec->Init(item.Sha1IsDefined); - outStreamLimSpec->Init(item.Size); + RINOK(InStream_SeekSet(_inStream, _dataStartPos + item.Offset)) + + inHashStream.SetStreamAndInit(_inStream, item.archived_checksum.AlgoNumber); + inHashStream.inStreamLim->Init(item.PackSize); + + const int checksum_method = item.extracted_checksum.AlgoNumber; + if (checksum_method == XAR_CKSUM_SHA1) + { + outStreamLim->SetStream(outStreamSha1); + outStreamSha1->SetStream(realOutStream); + outStreamSha1->Init(); + } + else if (checksum_method == XAR_CKSUM_SHA256 + || checksum_method == XAR_CKSUM_SHA512) + { + outStreamLim->SetStream(outStreamSha256); + outStreamSha256->SetStream(realOutStream); + outStreamSha256->Init(checksum_method == XAR_CKSUM_SHA512); + } + else + outStreamLim->SetStream(realOutStream); + + realOutStream.Release(); + + // outStreamSha1->Init(item.Sha1IsDefined); + + outStreamLim->Init(item.Size); HRESULT res = S_OK; ICompressCoder *coder = NULL; if (item.IsCopyMethod()) + { if (item.PackSize == item.Size) coder = copyCoder; else opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (item.Method == METHOD_NAME_ZLIB) + } + else if (item.Method.IsEqualTo(METHOD_NAME_ZLIB)) coder = zlibCoder; - else if (item.Method == "bzip2") + else if (item.Method.IsEqualTo("bzip2")) coder = bzip2Coder; else opRes = NExtract::NOperationResult::kUnsupportedMethod; if (coder) - res = coder->Code(inStream, outStream, NULL, NULL, progress); + res = coder->Code(inHashStream.inStreamLim, outStreamLim, NULL, &item.Size, lps); if (res != S_OK) { - if (!outStreamLimSpec->IsFinishedOK()) + if (!outStreamLim->IsFinishedOK()) opRes = NExtract::NOperationResult::kDataError; else if (res != S_FALSE) return res; @@ -675,45 +1233,63 @@ if (opRes == NExtract::NOperationResult::kOK) { - if (outStreamLimSpec->IsFinishedOK() && - outStreamSha1Spec->GetSize() == item.Size) + if (outStreamLim->IsFinishedOK()) { - if (!outStreamLimSpec->IsFinishedOK()) + if (checksum_method == XAR_CKSUM_SHA1) { - opRes = NExtract::NOperationResult::kDataError; + Byte digest[SHA1_DIGEST_SIZE]; + outStreamSha1->Final(digest); + if (memcmp(digest, item.extracted_checksum.Data, SHA1_DIGEST_SIZE) != 0) + opRes = NExtract::NOperationResult::kCRCError; } - else if (item.Sha1IsDefined) + else if (checksum_method == XAR_CKSUM_SHA256) { - Byte digest[SHA1_DIGEST_SIZE]; - outStreamSha1Spec->Final(digest); - if (memcmp(digest, item.Sha1, SHA1_DIGEST_SIZE) != 0) + Byte digest[SHA256_DIGEST_SIZE]; + outStreamSha256->Final256(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) opRes = NExtract::NOperationResult::kCRCError; } + else if (checksum_method == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + outStreamSha256->Final512(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) + opRes = NExtract::NOperationResult::kCRCError; + } + if (opRes == NExtract::NOperationResult::kOK) + if (!inHashStream.CheckHash( + item.archived_checksum.AlgoNumber, + item.archived_checksum.Data)) + opRes = NExtract::NOperationResult::kCRCError; } else opRes = NExtract::NOperationResult::kDataError; } + if (checksum_method == XAR_CKSUM_SHA1) + outStreamSha1->ReleaseStream(); + else if (checksum_method == XAR_CKSUM_SHA256) + outStreamSha256->ReleaseStream(); } + outStreamLim->ReleaseStream(); } - outStreamSha1Spec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { *stream = NULL; COM_TRY_BEGIN - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) { - Create_BufInStream_WithNewBuffer(_xml, _xmlLen, stream); + Create_BufInStream_WithNewBuffer(_xmlBuf, _xmlLen, stream); return S_OK; } else - #endif +#endif { const CFile &item = _files[index]; if (item.HasData && item.IsCopyMethod() && item.PackSize == item.Size) @@ -723,10 +1299,15 @@ COM_TRY_END } -static const Byte k_Signature[] = { 'x', 'a', 'r', '!', 0, 0x1C }; +// 0x1c == 28 is expected header size value for most archives. +// but we want to support another (rare case) headers sizes. +// so we must reduce signature to 4 or 5 bytes. +static const Byte k_Signature[] = +// { 'x', 'a', 'r', '!', 0, 0x1C, 0 }; + { 'x', 'a', 'r', '!', 0 }; REGISTER_ARC_I( - "Xar", "xar pkg xip", 0, 0xE1, + "Xar", "xar pkg xip", NULL, 0xE1, k_Signature, 0, 0, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/XzHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/XzHandler.cpp 2022-05-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.cpp 2025-07-03 11:00:00.000000000 +0000 @@ -43,29 +43,48 @@ }; -class CHandler: +Z7_class_CHandler_final: public IInArchive, public IArchiveOpenSeq, public IInArchiveGetStream, public ISetProperties, - - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public IOutArchive, - #endif - + #endif public CMyUnknownImp, + #ifndef Z7_EXTRACT_ONLY + public CMultiMethodProps + #else + public CCommonMethodProps + #endif +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveOpenSeq) + Z7_COM_QI_ENTRY(IInArchiveGetStream) + Z7_COM_QI_ENTRY(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveOpenSeq) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif - #ifndef EXTRACT_ONLY - public CMultiMethodProps - #else - public CCommonMethodProps - #endif -{ - CXzStatInfo _stat; // it's stat from backward parsing - CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called - SRes _stat2_decode_SRes; bool _stat_defined; bool _stat2_defined; + bool _isArc; + bool _needSeekToStart; + bool _firstBlockWasRead; + SRes _stat2_decode_SRes; + + CXzStatInfo _stat; // it's stat from backward parsing + CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called const CXzStatInfo *GetStat() const { @@ -74,14 +93,10 @@ return NULL; } - bool _isArc; - bool _needSeekToStart; - bool _firstBlockWasRead; - AString _methodsString; - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY UInt32 _filterId; UInt64 _numSolidBytes; @@ -89,7 +104,7 @@ void InitXz() { _filterId = 0; - _numSolidBytes = XZ_PROPS__BLOCK_SIZE__AUTO; + _numSolidBytes = XZ_PROPS_BLOCK_SIZE_AUTO; } #endif @@ -97,7 +112,7 @@ void Init() { - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY InitXz(); CMultiMethodProps::Init(); #else @@ -114,12 +129,12 @@ ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - #ifndef _7ZIP_ST + #ifndef Z7_ST decoder._numThreads = _numThreads; #endif decoder._memUsage = _memUsage_Decompress; - HRESULT hres = decoder.Decode(seqInStream, outStream, + const HRESULT hres = decoder.Decode(seqInStream, outStream, NULL, // *outSizeLimit true, // finishStream progress); @@ -136,29 +151,15 @@ } } + if (hres == S_OK && progress) + { + // RINOK( + progress->SetRatioInfo(&decoder.Stat.InSize, &decoder.Stat.OutSize); + } return hres; } public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq) - MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) - #endif - CBlockInfo *_blocks; size_t _blocksArraySize; UInt64 _maxBlocksSize; @@ -172,7 +173,7 @@ HRESULT SeekToPackPos(UInt64 pos) { - return _stream->Seek((Int64)pos, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(_stream, pos); } }; @@ -181,7 +182,7 @@ _blocks(NULL), _blocksArraySize(0) { - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY InitXz(); #endif } @@ -211,17 +212,6 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -static inline char GetHex(unsigned value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} - -static inline void AddHexToString(AString &s, Byte value) -{ - s += GetHex(value >> 4); - s += GetHex(value & 0xF); -} - static void Lzma2PropToString(AString &s, unsigned prop) { char c = 0; @@ -240,7 +230,7 @@ } s.Add_UInt32(size); if (c != 0) - s += c; + s.Add_Char(c); } struct CMethodNamePair @@ -259,13 +249,15 @@ { XZ_ID_ARM, "ARM" }, { XZ_ID_ARMT, "ARMT" }, { XZ_ID_SPARC, "SPARC" }, + { XZ_ID_ARM64, "ARM64" }, + { XZ_ID_RISCV, "RISCV" }, { XZ_ID_LZMA2, "LZMA2" } }; static void AddMethodString(AString &s, const CXzFilter &f) { const char *p = NULL; - for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) if (g_NamePairs[i].Id == f.id) { p = g_NamePairs[i].Name; @@ -282,17 +274,23 @@ if (f.propsSize > 0) { - s += ':'; + s.Add_Colon(); if (f.id == XZ_ID_LZMA2 && f.propsSize == 1) Lzma2PropToString(s, f.props[0]); else if (f.id == XZ_ID_Delta && f.propsSize == 1) s.Add_UInt32((UInt32)f.props[0] + 1); + else if (f.id == XZ_ID_ARM64 && f.propsSize == 1) + s.Add_UInt32((UInt32)f.props[0] + 16 + 2); else { - s += '['; + s.Add_Char('['); for (UInt32 bi = 0; bi < f.propsSize; bi++) - AddHexToString(s, f.props[bi]); - s += ']'; + { + const unsigned v = f.props[bi]; + s.Add_Char(GET_HEX_CHAR_UPPER(v >> 4)); + s.Add_Char(GET_HEX_CHAR_UPPER(v & 15)); + } + s.Add_Char(']'); } } } @@ -337,7 +335,7 @@ } } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -388,19 +386,20 @@ // if (_blocks) prop = (UInt32)0; break; } + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN const CXzStatInfo *stat = GetStat(); @@ -410,6 +409,7 @@ case kpidSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break; case kpidPackSize: if (stat) prop = stat->InSize; break; case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; + default: break; } prop.Detach(value); return S_OK; @@ -427,9 +427,9 @@ void Init(IArchiveOpenCallback *progress); }; -static SRes OpenCallbackProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 /* outSize */) +static SRes OpenCallbackProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 /* outSize */) { - COpenCallbackWrap *p = CONTAINER_FROM_VTBL(pp, COpenCallbackWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(COpenCallbackWrap) if (p->OpenCallback) p->Res = p->OpenCallback->SetCompleted(NULL, &inSize); return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); @@ -446,7 +446,7 @@ struct CXzsCPP { CXzs p; - CXzsCPP() { Xzs_Construct(&p); } + CXzsCPP() { Xzs_CONSTRUCT(&p) } ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); } }; @@ -489,6 +489,7 @@ case SZ_ERROR_NO_ARCHIVE: return S_FALSE; */ + default: break; } return S_FALSE; } @@ -535,6 +536,9 @@ if (res2 == SZ_ERROR_ARCHIVE) return S_FALSE; + // what codes are possible here ? + // ?? res2 == SZ_ERROR_MEM : is possible here + // ?? res2 == SZ_ERROR_UNSUPPORTED : is possible here } else if (!isIndex) { @@ -551,10 +555,10 @@ } } - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.InSize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, _stat.InSize)) if (callback) { - RINOK(callback->SetTotal(NULL, &_stat.InSize)); + RINOK(callback->SetTotal(NULL, &_stat.InSize)) } CSeekInStreamWrap inStreamImp; @@ -569,7 +573,7 @@ return E_OUTOFMEMORY; lookStream.realStream = &inStreamImp.vt; - LookToRead2_Init(&lookStream); + LookToRead2_INIT(&lookStream) COpenCallbackWrap openWrap; openWrap.Init(callback); @@ -660,7 +664,7 @@ res = SZ_OK; } - RINOK(SRes_to_Open_HRESULT(res)); + RINOK(SRes_to_Open_HRESULT(res)) _stream = inStream; _seqStream = inStream; @@ -670,7 +674,7 @@ -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { @@ -680,7 +684,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _seqStream = stream; @@ -689,7 +693,7 @@ return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { XzStatInfo_Clear(&_stat); XzStatInfo_Clear(&_stat2); @@ -738,12 +742,12 @@ } -class CInStream: - public IInStream, - public CMyUnknownImp -{ -public: +Z7_CLASS_IMP_IInStream( + CInStream +) + UInt64 _virtPos; +public: UInt64 Size; UInt64 _cacheStartPos; size_t _cacheSize; @@ -759,23 +763,16 @@ // _startPos = startPos; } - CHandler *_handlerSpec; - CMyComPtr _handler; - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - ~CInStream(); + CMyComPtr2 _handlerSpec; + // ~CInStream(); }; - +/* CInStream::~CInStream() { // _cache.Free(); } - +*/ static size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos) { @@ -845,7 +842,7 @@ ECoderStatus status; - SRes res = XzUnpacker_Code(&xzu.p, + const SRes res = XzUnpacker_Code(&xzu.p, // dest + outPos, NULL, &outLen, @@ -868,7 +865,7 @@ packRem -= inLen; - BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); + const BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); if ((inLen == 0 && outLen == 0) || blockFinished) { @@ -882,7 +879,7 @@ } -STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { COM_TRY_BEGIN @@ -906,7 +903,7 @@ if (_virtPos < _cacheStartPos || _virtPos >= _cacheStartPos + _cacheSize) { - size_t bi = FindBlock(_handlerSpec->_blocks, _handlerSpec->_blocksArraySize, _virtPos); + const size_t bi = FindBlock(_handlerSpec->_blocks, _handlerSpec->_blocksArraySize, _virtPos); const CBlockInfo &block = _handlerSpec->_blocks[bi]; const UInt64 unpackSize = _handlerSpec->_blocks[bi + 1].UnpackPos - block.UnpackPos; if (_cache.Size() < unpackSize) @@ -914,19 +911,19 @@ _cacheSize = 0; - RINOK(_handlerSpec->SeekToPackPos(block.PackPos)); + RINOK(_handlerSpec->SeekToPackPos(block.PackPos)) RINOK(DecodeBlock(xz, _handlerSpec->_seqStream, block.StreamFlags, block.PackSize, - (size_t)unpackSize, _cache)); + (size_t)unpackSize, _cache)) _cacheStartPos = block.UnpackPos; _cacheSize = (size_t)unpackSize; } { - size_t offset = (size_t)(_virtPos - _cacheStartPos); - size_t rem = _cacheSize - offset; + const size_t offset = (size_t)(_virtPos - _cacheStartPos); + const size_t rem = _cacheSize - offset; if (size > rem) size = (UInt32)rem; - memcpy(data, _cache + offset, size); + memcpy(data, _cache.ConstData() + offset, size); _virtPos += size; if (processedSize) *processedSize = size; @@ -937,7 +934,7 @@ } -STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -958,7 +955,7 @@ static const UInt64 kMaxBlockSize_for_GetStream = (UInt64)1 << 40; -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN @@ -973,23 +970,23 @@ || _maxBlocksSize != (size_t)_maxBlocksSize) return S_FALSE; - UInt64 memSize; + size_t memSize; if (!NSystem::GetRamSize(memSize)) - memSize = (UInt64)(sizeof(size_t)) << 28; + memSize = (size_t)sizeof(size_t) << 28; { if (_maxBlocksSize > memSize / 4) return S_FALSE; } - CInStream *spec = new CInStream; - CMyComPtr specStream = spec; + CMyComPtr2 spec; + spec.Create_if_Empty(); spec->_cache.Alloc((size_t)_maxBlocksSize); - spec->_handlerSpec = this; - spec->_handler = (IInArchive *)this; + spec->_handlerSpec.SetFromCls(this); + // spec->_handler = (IInArchive *)this; spec->Size = _stat.OutSize; spec->InitAndSeek(); - *stream = specStream.Detach(); + *stream = spec.Detach(); return S_OK; COM_TRY_END @@ -1024,8 +1021,8 @@ -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -1036,31 +1033,32 @@ const CXzStatInfo *stat = GetStat(); if (stat) - extractCallback->SetTotal(stat->InSize); + RINOK(extractCallback->SetTotal(stat->InSize)) UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) + Int32 opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr lpsRef = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); if (_needSeekToStart) { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _needSeekToStart = true; @@ -1068,26 +1066,27 @@ NCompress::NXz::CDecoder decoder; - HRESULT hres = Decode(decoder, _seqStream, realOutStream, lpsRef); + const HRESULT hres = Decode(decoder, _seqStream, realOutStream, lps); if (!decoder.MainDecodeSRes_wasUsed) return hres == S_OK ? E_FAIL : hres; - Int32 opRes = Get_Extract_OperationResult(decoder); + opRes = Get_Extract_OperationResult(decoder); if (opRes == NExtract::NOperationResult::kOK && hres != S_OK) opRes = NExtract::NOperationResult::kDataError; - realOutStream.Release(); + // realOutStream.Release(); + } return extractCallback->SetOperationResult(opRes); COM_TRY_END } -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; // *timeType = NFileTimeType::kUnix; @@ -1095,8 +1094,8 @@ } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN @@ -1111,17 +1110,25 @@ if (numItems != 1) return E_INVALIDARG; + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) if (IntToBool(newProps)) { { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) if (prop.vt != VT_EMPTY) if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; @@ -1133,16 +1140,15 @@ UInt64 dataSize; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; dataSize = prop.uhVal.QuadPart; } - NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder; - CMyComPtr encoder = encoderSpec; + CMyComPtr2_Create encoder; - CXzProps &xzProps = encoderSpec->xzProps; + CXzProps &xzProps = encoder->xzProps; CLzma2EncProps &lzma2Props = xzProps.lzma2Props; lzma2Props.lzmaProps.level = GetLevel(); @@ -1151,11 +1157,18 @@ /* { NCOM::CPropVariant prop = (UInt64)dataSize; - RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop)); + RINOK(encoder->SetCoderProp(NCoderPropID::kReduceSize, prop)) } */ - #ifndef _7ZIP_ST + #ifndef Z7_ST + +#ifdef _WIN32 + // we don't use chunk multithreading inside lzma2 stream. + // so we don't set xzProps.lzma2Props.numThreadGroups. + if (_numThreadGroups > 1) + xzProps.numThreadGroups = _numThreadGroups; +#endif UInt32 numThreads = _numThreads; @@ -1180,13 +1193,15 @@ CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads); } + // printf("\n====== GetProcessGroupAffinity : \n"); + UInt64 cs = _numSolidBytes; - if (cs != XZ_PROPS__BLOCK_SIZE__AUTO) + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO) oneMethodInfo.AddProp_BlockSize2(cs); cs = oneMethodInfo.Get_Xz_BlockSize(); - if (cs != XZ_PROPS__BLOCK_SIZE__AUTO && - cs != XZ_PROPS__BLOCK_SIZE__SOLID) + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO && + cs != XZ_PROPS_BLOCK_SIZE_SOLID) { const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); const UInt32 numBlockThreads_Original = numThreads / lzmaThreads; @@ -1218,16 +1233,16 @@ } xzProps.numTotalThreads = (int)numThreads; - #endif // _7ZIP_ST + #endif // Z7_ST xzProps.blockSize = _numSolidBytes; - if (_numSolidBytes == XZ_PROPS__BLOCK_SIZE__SOLID) + if (_numSolidBytes == XZ_PROPS_BLOCK_SIZE_SOLID) { - xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID; + xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; } - RINOK(encoderSpec->SetCheckSize(_crcSize)); + RINOK(encoder->SetCheckSize(_crcSize)) { CXzFilterProps &filter = xzProps.filterProps; @@ -1262,13 +1277,13 @@ FOR_VECTOR (j, m.Props) { const CProp &prop = m.Props[j]; - RINOK(encoderSpec->SetCoderProp(prop.Id, prop.Value)); + RINOK(encoder->SetCoderProp(prop.Id, prop.Value)) } } { CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); + RINOK(updateCallback->GetStream(0, &fileInStream)) if (!fileInStream) return S_FALSE; { @@ -1281,11 +1296,10 @@ dataSize = size; } } - RINOK(updateCallback->SetTotal(dataSize)); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + RINOK(updateCallback->SetTotal(dataSize)) + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - RINOK(encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress)); + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) } return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); @@ -1294,8 +1308,9 @@ if (indexInArchive != 0) return E_INVALIDARG; - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) if (opCallback) { RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate)) @@ -1305,15 +1320,16 @@ { const CXzStatInfo *stat = GetStat(); if (stat) - RINOK(updateCallback->SetTotal(stat->InSize)); - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + { + RINOK(updateCallback->SetTotal(stat->InSize)) + } + RINOK(InStream_SeekToBegin(_stream)) } - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(updateCallback, true); - return NCompress::CopyStream(_stream, outStream, progress); + return NCompress::CopyStream(_stream, outStream, lps); COM_TRY_END } @@ -1328,7 +1344,7 @@ if (name.IsEmpty()) return E_INVALIDARG; - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY if (name[0] == L's') { @@ -1349,7 +1365,7 @@ } if (!useStr) { - _numSolidBytes = (isSolid ? XZ_PROPS__BLOCK_SIZE__SOLID : XZ_PROPS__BLOCK_SIZE__AUTO); + _numSolidBytes = (isSolid ? XZ_PROPS_BLOCK_SIZE_SOLID : XZ_PROPS_BLOCK_SIZE_AUTO); return S_OK; } } @@ -1375,7 +1391,7 @@ -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN @@ -1383,15 +1399,15 @@ for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetProperty(names[i], values[i])); + RINOK(SetProperty(names[i], values[i])) } - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY if (!_filterMethod.MethodName.IsEmpty()) { unsigned k; - for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++) + for (k = 0; k < Z7_ARRAY_SIZE(g_NamePairs); k++) { const CMethodNamePair &pair = g_NamePairs[k]; if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name)) @@ -1400,7 +1416,7 @@ break; } } - if (k == ARRAY_SIZE(g_NamePairs)) + if (k == Z7_ARRAY_SIZE(g_NamePairs)) return E_INVALIDARG; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/XzHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/XzHandler.h 2017-01-30 14:07:17.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/XzHandler.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // XzHandler.h -#ifndef __XZ_HANDLER_H -#define __XZ_HANDLER_H +#ifndef ZIP7_INC_XZ_HANDLER_H +#define ZIP7_INC_XZ_HANDLER_H namespace NArchive { namespace NXz { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ZHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ZHandler.cpp 2015-02-11 09:25:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZHandler.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -17,17 +17,12 @@ namespace NArchive { namespace NZ { -class CHandler: - public IInArchive, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_0 + CMyComPtr _stream; UInt64 _packSize; // UInt64 _unpackSize; // bool _unpackSize_Defined; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) }; static const Byte kProps[] = @@ -38,13 +33,13 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; switch (propID) @@ -55,7 +50,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NWindows::NCOM::CPropVariant prop; switch (propID) @@ -68,22 +63,21 @@ } /* -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp + , ICompressProgressInfo +) CMyComPtr Callback; public: - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); void Init(IArchiveOpenCallback *callback) { Callback = callback; } }; -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { + outSize = outSize; if (Callback) { - UInt64 files = 1; + const UInt64 files = 1; return Callback->SetCompleted(&files, inSize); } return S_OK; @@ -95,30 +89,30 @@ if (size < 3) return k_IsArc_Res_NEED_MORE; if (size > NCompress::NZ::kRecommendedCheckSize) - size = NCompress::NZ::kRecommendedCheckSize; + size = NCompress::NZ::kRecommendedCheckSize; if (!NCompress::NZ::CheckStream(p, size)) return k_IsArc_Res_NO; return k_IsArc_Res_YES; } } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openCallback */) + IArchiveOpenCallback * /* openCallback */)) { COM_TRY_BEGIN { - // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); + // RINOK(InStream_GetPos(stream, _streamStartPosition)); Byte buffer[NCompress::NZ::kRecommendedCheckSize]; // Byte buffer[1500]; size_t size = NCompress::NZ::kRecommendedCheckSize; // size = 700; - RINOK(ReadStream(stream, buffer, &size)); + RINOK(ReadStream(stream, buffer, &size)) if (!NCompress::NZ::CheckStream(buffer, size)) return S_FALSE; UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) _packSize = endPos; /* @@ -142,7 +136,7 @@ UInt64 files = 1; RINOK(openCallback->SetTotal(&files, &endPos)); } - RINOK(stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(stream, _streamStartPosition + kSignatureSize)) HRESULT res = decoder->Code(stream, outStream, NULL, NULL, openCallback ? compressProgress : NULL); if (res != S_OK) return S_FALSE; @@ -155,7 +149,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _packSize = 0; // _unpackSize_Defined = false; @@ -164,62 +158,57 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) return S_OK; if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - - extractCallback->SetTotal(_packSize); - + RINOK(extractCallback->SetTotal(_packSize)) UInt64 currentTotalPacked = 0; + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - + int opRes; + { CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, true); - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) - NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; - CMyComPtr decoder = decoderSpec; - - int opRes; + NCompress::NZ::CDecoder decoder; { - HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress); - if (result == S_FALSE) + const HRESULT hres = decoder.Code(_stream, outStream, lps); + if (hres == S_FALSE) opRes = NExtract::NOperationResult::kDataError; else { - RINOK(result); + RINOK(hres) opRes = NExtract::NOperationResult::kOK; } } // _unpackSize = outStreamSpec->GetSize(); // _unpackSize_Defined = true; - outStream.Release(); + // outStream.Release(); + } return extractCallback->SetOperationResult(opRes); COM_TRY_END } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.cpp 2020-11-29 13:55:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -30,43 +30,28 @@ using namespace NFileHeader; -static const UInt32 kLzmaPropsSize = 5; -static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize; +static const unsigned kLzmaPropsSize = 5; +static const unsigned kLzmaHeaderSize = 4 + kLzmaPropsSize; -class CLzmaEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressSetCoderPropertiesOpt, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_3( + CLzmaEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressSetCoderPropertiesOpt +) public: - NCompress::NLzma::CEncoder *EncoderSpec; - CMyComPtr Encoder; + CMyComPtr2 Encoder; Byte Header[kLzmaHeaderSize]; - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - MY_UNKNOWN_IMP2( - ICompressSetCoderProperties, - ICompressSetCoderPropertiesOpt) }; -STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - if (!Encoder) - { - EncoderSpec = new NCompress::NLzma::CEncoder; - Encoder = EncoderSpec; - } - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(Header + 4, kLzmaPropsSize); - RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps)); - RINOK(EncoderSpec->WriteCoderProperties(outStream)); - if (outStreamSpec->GetPos() != kLzmaPropsSize) + Encoder.Create_if_Empty(); + CMyComPtr2_Create outStream; + outStream->Init(Header + 4, kLzmaPropsSize); + RINOK(Encoder->SetCoderProperties(propIDs, props, numProps)) + RINOK(Encoder->WriteCoderProperties(outStream)) + if (outStream->GetPos() != kLzmaPropsSize) return E_FAIL; Header[0] = MY_VER_MAJOR; Header[1] = MY_VER_MINOR; @@ -75,23 +60,21 @@ return S_OK; } -STDMETHODIMP CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - return EncoderSpec->SetCoderPropertiesOpt(propIDs, props, numProps); + return Encoder->SetCoderPropertiesOpt(propIDs, props, numProps); } -STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { - RINOK(WriteStream(outStream, Header, kLzmaHeaderSize)); - return Encoder->Code(inStream, outStream, inSize, outSize, progress); + RINOK(WriteStream(outStream, Header, kLzmaHeaderSize)) + return Encoder.Interface()->Code(inStream, outStream, inSize, outSize, progress); } CAddCommon::CAddCommon(): - _copyCoderSpec(NULL), _isLzmaEos(false), - _cryptoStreamSpec(NULL), _buf(NULL) {} @@ -120,7 +103,7 @@ for (;;) { UInt32 processed; - RINOK(inStream->Read(_buf, kBufSize, &processed)); + RINOK(inStream->Read(_buf, kBufSize, &processed)) if (processed == 0) { resultCRC = CRC_GET_DIGEST(crc); @@ -148,9 +131,9 @@ if (opRes.PackSize < unpackSize) opRes.PackSize = unpackSize; - Byte method = _options.MethodSequence[0]; + const Byte method = _options.MethodSequence[0]; - if (method == NCompressionMethod::kStore && !_options.PasswordIsDefined) + if (method == NCompressionMethod::kStore && !_options.Password_Defined) opRes.PackSize = unpackSize; opRes.CRC = 0; @@ -160,7 +143,7 @@ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; opRes.DescriptorMode = outSeqMode; - if (_options.PasswordIsDefined) + if (_options.Password_Defined) { opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto; if (_options.IsAesMode) @@ -190,9 +173,10 @@ opRes.LzmaEos = oneMethodMain->Get_Lzma_Eos(); break; } + default: break; } if (opRes.ExtractVersion < ver) - opRes.ExtractVersion = ver; + opRes.ExtractVersion = ver; return S_OK; } @@ -202,10 +186,11 @@ DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, IOutStream *outStream, bool inSeqMode, bool outSeqMode, - UInt32 fileTime, UInt64 expectedDataSize, + UInt32 fileTime, + UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed, ICompressProgressInfo *progress, CCompressingResult &opRes) { - opRes.LzmaEos = false; + // opRes.LzmaEos = false; if (!inStream) { @@ -213,8 +198,7 @@ return E_INVALIDARG; } - CSequentialInStreamWithCRC *inSecCrcStreamSpec = new CSequentialInStreamWithCRC; - CMyComPtr inCrcStream = inSecCrcStreamSpec; + CMyComPtr2_Create inCrcStream; CMyComPtr inStream2; if (!inSeqMode) @@ -228,10 +212,12 @@ } } - inSecCrcStreamSpec->SetStream(inStream); - inSecCrcStreamSpec->Init(); + inCrcStream->SetStream(inStream); + inCrcStream->SetFullSize(expectedDataSize_IsConfirmed ? expectedDataSize : (UInt64)(Int64)-1); + // inCrcStream->Init(); unsigned numTestMethods = _options.MethodSequence.Size(); + // numTestMethods != 0 bool descriptorMode = outSeqMode; @@ -240,7 +226,7 @@ // The descriptor allows to use ZipCrypto check field without CRC (InfoZip's modification). if (!outSeqMode) - if (inSeqMode && _options.PasswordIsDefined && !_options.IsAesMode) + if (inSeqMode && _options.Password_Defined && !_options.IsAesMode) descriptorMode = true; opRes.DescriptorMode = descriptorMode; @@ -251,28 +237,27 @@ UInt32 crc = 0; bool crc_IsCalculated = false; - Byte method = 0; CFilterCoder::C_OutStream_Releaser outStreamReleaser; - opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; + // opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; for (unsigned i = 0; i < numTestMethods; i++) { - opRes.LzmaEos = false; - opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; - + inCrcStream->Init(); + if (i != 0) { - if (inStream2) + // if (inStream2) { - inSecCrcStreamSpec->Init(); - RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(inStream2)) } - - RINOK(outStream->SetSize(0)); - RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(outStream->SetSize(0)) } - method = _options.MethodSequence[i]; + opRes.LzmaEos = false; + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; + + const Byte method = _options.MethodSequence[i]; if (method == NCompressionMethod::kStore && descriptorMode) { // we still can create descriptor_mode archives with "Store" method, but they are not good for 100% @@ -281,32 +266,29 @@ bool needCode = true; - if (_options.PasswordIsDefined) + if (_options.Password_Defined) { opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto; - if (!_cryptoStream) - { - _cryptoStreamSpec = new CFilterCoder(true); - _cryptoStream = _cryptoStreamSpec; - } + if (!_cryptoStream.IsDefined()) + _cryptoStream.SetFromCls(new CFilterCoder(true)); if (_options.IsAesMode) { opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes; - if (!_cryptoStreamSpec->Filter) + if (!_cryptoStream->Filter) { - _cryptoStreamSpec->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder; + _cryptoStream->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder; _filterAesSpec->SetKeyMode(_options.AesKeyMode); - RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len())); + RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len())) } - RINOK(_filterAesSpec->WriteHeader(outStream)); + RINOK(_filterAesSpec->WriteHeader(outStream)) } else { - if (!_cryptoStreamSpec->Filter) + if (!_cryptoStream->Filter) { - _cryptoStreamSpec->Filter = _filterSpec = new NCrypto::NZip::CEncoder; + _cryptoStream->Filter = _filterSpec = new NCrypto::NZip::CEncoder; _filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len()); } @@ -321,27 +303,27 @@ { if (!crc_IsCalculated) { - RINOK(CalcStreamCRC(inStream, crc)); + RINOK(CalcStreamCRC(inStream, crc)) crc_IsCalculated = true; - RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL)); - inSecCrcStreamSpec->Init(); + RINOK(InStream_SeekToBegin(inStream2)) + inCrcStream->Init(); } check = (crc >> 16); } - RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check)); + RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check)) } if (method == NCompressionMethod::kStore) { needCode = false; - RINOK(_cryptoStreamSpec->Code(inCrcStream, outStream, NULL, NULL, progress)); + RINOK(_cryptoStream->Code(inCrcStream, outStream, NULL, NULL, progress)) } else { - RINOK(_cryptoStreamSpec->SetOutStream(outStream)); - RINOK(_cryptoStreamSpec->InitEncoder()); - outStreamReleaser.FilterCoder = _cryptoStreamSpec; + RINOK(_cryptoStream->SetOutStream(outStream)) + RINOK(_cryptoStream->InitEncoder()) + outStreamReleaser.FilterCoder = _cryptoStream.ClsPtr(); } } @@ -351,17 +333,13 @@ { case NCompressionMethod::kStore: { - if (!_copyCoderSpec) - { - _copyCoderSpec = new NCompress::CCopyCoder; - _copyCoder = _copyCoderSpec; - } + _copyCoder.Create_if_Empty(); CMyComPtr outStreamNew; - if (_options.PasswordIsDefined) + if (_options.Password_Defined) outStreamNew = _cryptoStream; else outStreamNew = outStream; - RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); + RINOK(_copyCoder.Interface()->Code(inCrcStream, outStreamNew, NULL, NULL, progress)) break; } @@ -406,7 +384,7 @@ } RINOK(CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS - methodId, true, _compressEncoder)); + methodId, true, _compressEncoder)) if (!_compressEncoder) return E_NOTIMPL; @@ -428,19 +406,19 @@ COneMethodInfo *oneMethodMain = &_options._methods[0]; RINOK(oneMethodMain->SetCoderProps(setCoderProps, - _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL)); + _options.DataSizeReduce_Defined ? &_options.DataSizeReduce : NULL)) } } } if (method == NCompressionMethod::kLZMA) - _isLzmaEos = _lzmaEncoder->EncoderSpec->IsWriteEndMark(); + _isLzmaEos = _lzmaEncoder->Encoder->IsWriteEndMark(); } if (method == NCompressionMethod::kLZMA) opRes.LzmaEos = _isLzmaEos; CMyComPtr outStreamNew; - if (_options.PasswordIsDefined) + if (_options.Password_Defined) outStreamNew = _cryptoStream; else outStreamNew = outStream; @@ -452,41 +430,45 @@ _compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps); if (optProps) { - PROPID propID = NCoderPropID::kExpectedDataSize; + const PROPID propID = NCoderPropID::kExpectedDataSize; NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; - RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)); + RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) } } try { - RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); + RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)) } catch (...) { return E_FAIL; } break; } } // switch end - if (_options.PasswordIsDefined) + if (_options.Password_Defined) { - RINOK(_cryptoStreamSpec->OutStreamFinish()); + RINOK(_cryptoStream->OutStreamFinish()) } } - if (_options.PasswordIsDefined) + if (_options.Password_Defined) { if (_options.IsAesMode) { - RINOK(_filterAesSpec->WriteFooter(outStream)); + RINOK(_filterAesSpec->WriteFooter(outStream)) } } - RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize)); + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize)) { - opRes.CRC = inSecCrcStreamSpec->GetCRC(); - opRes.UnpackSize = inSecCrcStreamSpec->GetSize(); + opRes.CRC = inCrcStream->GetCRC(); + opRes.UnpackSize = inCrcStream->GetSize(); + opRes.Method = method; } - if (_options.PasswordIsDefined) + if (!inCrcStream->WasFinished()) + return E_FAIL; + + if (_options.Password_Defined) { if (opRes.PackSize < opRes.UnpackSize + (_options.IsAesMode ? _filterAesSpec->GetAddPackSize() : NCrypto::NZip::kHeaderSize)) @@ -496,8 +478,6 @@ break; } - - opRes.Method = method; return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.h 2020-11-29 13:54:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipAddCommon.h 2023-12-19 21:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZipAddCommon.h -#ifndef __ZIP_ADD_COMMON_H -#define __ZIP_ADD_COMMON_H +#ifndef ZIP7_INC_ZIP_ADD_COMMON_H +#define ZIP7_INC_ZIP_ADD_COMMON_H #include "../../ICoder.h" #include "../../IProgress.h" @@ -39,15 +39,13 @@ class CAddCommon MY_UNCOPYABLE { CCompressionMethodMode _options; - NCompress::CCopyCoder *_copyCoderSpec; - CMyComPtr _copyCoder; + CMyComPtr2 _copyCoder; CMyComPtr _compressEncoder; Byte _compressExtractVersion; bool _isLzmaEos; - CFilterCoder *_cryptoStreamSpec; - CMyComPtr _cryptoStream; + CMyComPtr2 _cryptoStream; NCrypto::NZip::CEncoder *_filterSpec; NCrypto::NWzAes::CEncoder *_filterAesSpec; @@ -68,7 +66,8 @@ DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, IOutStream *outStream, bool inSeqMode, bool outSeqMode, - UInt32 fileTime, UInt64 expectedDataSize, + UInt32 fileTime, + UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed, ICompressProgressInfo *progress, CCompressingResult &opRes); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipCompressionMode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipCompressionMode.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipCompressionMode.h 2019-10-10 17:34:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipCompressionMode.h 2023-05-04 17:00:00.000000000 +0000 @@ -1,11 +1,11 @@ // CompressionMode.h -#ifndef __ZIP_COMPRESSION_MODE_H -#define __ZIP_COMPRESSION_MODE_H +#ifndef ZIP7_INC_ZIP_COMPRESSION_MODE_H +#define ZIP7_INC_ZIP_COMPRESSION_MODE_H #include "../../../Common/MyString.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/System.h" #endif @@ -34,20 +34,26 @@ struct CCompressionMethodMode: public CBaseProps { CRecordVector MethodSequence; - bool PasswordIsDefined; AString Password; // _Wipe + bool Password_Defined; + bool Force_SeqOutMode; + bool DataSizeReduce_Defined; + UInt64 DataSizeReduce; - UInt64 _dataSizeReduce; - bool _dataSizeReduceDefined; - - bool IsRealAesMode() const { return PasswordIsDefined && IsAesMode; } + bool IsRealAesMode() const { return Password_Defined && IsAesMode; } - CCompressionMethodMode(): PasswordIsDefined(false) + CCompressionMethodMode() { - _dataSizeReduceDefined = false; - _dataSizeReduce = 0; + Password_Defined = false; + Force_SeqOutMode = false; + DataSizeReduce_Defined = false; + DataSizeReduce = 0; } +#ifdef Z7_CPP_IS_SUPPORTED_default + CCompressionMethodMode(const CCompressionMethodMode &) = default; + CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default; +#endif ~CCompressionMethodMode() { Password.Wipe_and_Empty(); } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.cpp 2022-05-07 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.cpp 2024-05-12 12:00:00.000000000 +0000 @@ -18,22 +18,15 @@ #include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" - -#ifdef EXTERNAL_CODECS -#ifndef SUPPORT_LZFSE -#define SUPPORT_LZFSE -#endif -#endif - -#ifdef SUPPORT_LZFSE +#ifndef Z7_ZIP_LZFSE_DISABLE #include "../../Compress/LzfseDecoder.h" #endif - #include "../../Compress/LzmaDecoder.h" #include "../../Compress/ImplodeDecoder.h" #include "../../Compress/PpmdZip.h" #include "../../Compress/ShrinkDecoder.h" #include "../../Compress/XzDecoder.h" +#include "../../Compress/ZstdDecoder.h" #include "../../Crypto/WzAes.h" #include "../../Crypto/ZipCrypto.h" @@ -92,18 +85,20 @@ , "BZip2" , NULL , "LZMA" + /* , NULL , NULL , NULL , NULL , NULL - , "zstd-pk" + , "zstd-pk" // deprecated + */ }; const char * const kMethodNames2[kNumMethodNames2] = { - "zstd-wz" + "zstd" , "MP3" , "xz" , "Jpeg" @@ -129,6 +124,7 @@ { { 0, "Encrypt" }, { 3, "Descriptor" }, + // { 4, "Enhanced" }, // { 5, "Patched" }, { 6, kMethod_StrongCrypto }, { 11, "UTF8" }, @@ -221,7 +217,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -338,12 +334,13 @@ } // case kpidIsAltStream: prop = true; break; + default: break; } return prop.Detach(value); COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = m_Items.Size(); return S_OK; @@ -377,7 +374,7 @@ } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -521,7 +518,7 @@ if (extra.GetWzAes(aesField)) { m += kMethod_AES; - m += '-'; + m.Add_Minus(); m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64); id = aesField.Method; isWzAes = true; @@ -537,13 +534,13 @@ f.AlgId = 0; if (extra.GetStrongCrypto(f)) { - const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); + const char *s = FindNameForId(k_StrongCryptoPairs, Z7_ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); if (s) m += s; else { m += kMethod_StrongCrypto; - m += ':'; + m.Add_Colon(); m.Add_UInt32(f.AlgId); } if (f.CertificateIsUsed()) @@ -564,7 +561,7 @@ s = kMethodNames1[id]; else { - int id2 = (int)id - (int)kMethodNames2Start; + const int id2 = (int)id - (int)kMethodNames2Start; if (id2 >= 0 && (unsigned)id2 < kNumMethodNames2) s = kMethodNames2[id2]; } @@ -585,7 +582,7 @@ } else if (id == NFileHeader::NCompressionMethod::kDeflate) { - m += ':'; + m.Add_Colon(); m += kDeflateLevels[level]; level = 0; } @@ -629,7 +626,7 @@ if (flags != 0) { - AString s2 = FlagsToString(g_HeaderCharacts, ARRAY_SIZE(g_HeaderCharacts), flags); + const AString s2 = FlagsToString(g_HeaderCharacts, Z7_ARRAY_SIZE(g_HeaderCharacts), flags); if (!s2.IsEmpty()) { if (!s.IsEmpty()) @@ -681,6 +678,7 @@ } break; */ + default: break; } return prop.Detach(value); @@ -690,13 +688,13 @@ /* -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) { UNUSED_VAR(index); *propID = 0; @@ -704,7 +702,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; @@ -720,7 +718,7 @@ return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) { UNUSED_VAR(index); UNUSED_VAR(propID); @@ -767,13 +765,16 @@ } */ -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN try { Close(); + m_Archive.Force_ReadLocals_Mode = _force_OpenSeq; + // m_Archive.Disable_VolsRead = _force_OpenSeq; + // m_Archive.Disable_FindMarker = _force_OpenSeq; HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items); if (res != S_OK) { @@ -787,7 +788,7 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { m_Items.Clear(); m_Archive.Close(); @@ -795,44 +796,26 @@ } -class CLzmaDecoder: - public ICompressCoder, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_3( + CLzmaDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) public: - NCompress::NLzma::CDecoder *DecoderSpec; - CMyComPtr Decoder; - - MY_UNKNOWN_IMP2( - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - - CLzmaDecoder(); + CMyComPtr2_Create Decoder; }; -CLzmaDecoder::CLzmaDecoder() -{ - DecoderSpec = new NCompress::NLzma::CDecoder; - Decoder = DecoderSpec; -} - static const unsigned kZipLzmaPropsSize = 4 + LZMA_PROPS_SIZE; -HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { Byte buf[kZipLzmaPropsSize]; - RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize)); + RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize)) if (buf[2] != LZMA_PROPS_SIZE || buf[3] != 0) return E_NOTIMPL; - RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE)); + RINOK(Decoder->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE)) UInt64 inSize2 = 0; if (inSize) { @@ -841,18 +824,18 @@ return S_FALSE; inSize2 -= kZipLzmaPropsSize; } - return Decoder->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress); + return Decoder.Interface()->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress); } -STDMETHODIMP CLzmaDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CLzmaDecoder::SetFinishMode(UInt32 finishMode)) { - DecoderSpec->FinishStream = (finishMode != 0); + Decoder->FinishStream = (finishMode != 0); return S_OK; } -STDMETHODIMP CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value)) { - *value = DecoderSpec->GetInputProcessedSize() + kZipLzmaPropsSize; + *value = Decoder->GetInputProcessedSize() + kZipLzmaPropsSize; return S_OK; } @@ -872,27 +855,18 @@ class CZipDecoder { - NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; - NCrypto::NZipStrong::CDecoder *_pkAesDecoderSpec; - NCrypto::NWzAes::CDecoder *_wzAesDecoderSpec; - - CMyComPtr _zipCryptoDecoder; - CMyComPtr _pkAesDecoder; - CMyComPtr _wzAesDecoder; + CMyComPtr2 _zipCryptoDecoder; + CMyComPtr2 _pkAesDecoder; + CMyComPtr2 _wzAesDecoder; - CFilterCoder *filterStreamSpec; - CMyComPtr filterStream; + CMyComPtr2 filterStream; CMyComPtr getTextPassword; CObjectVector methodItems; CLzmaDecoder *lzmaDecoderSpec; public: CZipDecoder(): - _zipCryptoDecoderSpec(0), - _pkAesDecoderSpec(0), - _wzAesDecoderSpec(0), - filterStreamSpec(0), - lzmaDecoderSpec(0) + lzmaDecoderSpec(NULL) {} HRESULT Decode( @@ -901,7 +875,7 @@ ISequentialOutStream *realOutStream, IArchiveExtractCallback *extractCallback, ICompressProgressInfo *compressProgress, - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 numThreads, UInt64 memUsage, #endif Int32 &res); @@ -919,7 +893,7 @@ for (;;) { size_t size = kBufSize; - RINOK(ReadStream(stream, buf, &size)); + RINOK(ReadStream(stream, buf, &size)) if (size == 0) return S_OK; thereAreData = true; @@ -927,25 +901,23 @@ if ((packSize - prev) >= (1 << 22)) { prev = packSize; - RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)) } } } -class COutStreamWithPadPKCS7: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithPadPKCS7 + , ISequentialOutStream +) CMyComPtr _stream; UInt64 _size; UInt64 _padPos; UInt32 _padSize; bool _padFailure; public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } @@ -962,7 +934,7 @@ }; -STDMETHODIMP COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 written = 0; HRESULT result = S_OK; @@ -1003,7 +975,7 @@ ISequentialOutStream *realOutStream, IArchiveExtractCallback *extractCallback, ICompressProgressInfo *compressProgress, - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 numThreads, UInt64 memUsage, #endif Int32 &res) @@ -1056,15 +1028,12 @@ } } - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream = outStreamSpec; - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(needCRC); + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(needCRC); CMyComPtr packStream; - - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(limitedStreamSpec); + CMyComPtr2_Create inStream; { UInt64 packSize = item.PackSize; @@ -1074,14 +1043,14 @@ return S_OK; packSize -= NCrypto::NWzAes::kMacSize; } - RINOK(archive.GetItemStream(item, true, packStream)); + RINOK(archive.GetItemStream(item, true, packStream)) if (!packStream) { res = NExtract::NOperationResult::kUnavailable; return S_OK; } - limitedStreamSpec->SetStream(packStream); - limitedStreamSpec->Init(packSize); + inStream->SetStream(packStream); + inStream->Init(packSize); } @@ -1094,13 +1063,9 @@ if (wzAesMode) { id = aesField.Method; - if (!_wzAesDecoder) - { - _wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder; - _wzAesDecoder = _wzAesDecoderSpec; - } + _wzAesDecoder.Create_if_Empty(); cryptoFilter = _wzAesDecoder; - if (!_wzAesDecoderSpec->SetKeyMode(aesField.Strength)) + if (!_wzAesDecoder->SetKeyMode(aesField.Strength)) { res = NExtract::NOperationResult::kUnsupportedMethod; return S_OK; @@ -1108,25 +1073,17 @@ } else if (pkAesMode) { - if (!_pkAesDecoder) - { - _pkAesDecoderSpec = new NCrypto::NZipStrong::CDecoder; - _pkAesDecoder = _pkAesDecoderSpec; - } + _pkAesDecoder.Create_if_Empty(); cryptoFilter = _pkAesDecoder; } else { - if (!_zipCryptoDecoder) - { - _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder; - _zipCryptoDecoder = _zipCryptoDecoderSpec; - } + _zipCryptoDecoder.Create_if_Empty(); cryptoFilter = _zipCryptoDecoder; } CMyComPtr cryptoSetPassword; - RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); + RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)) if (!cryptoSetPassword) return E_FAIL; @@ -1136,19 +1093,21 @@ if (getTextPassword) { CMyComBSTR_Wipe password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); + RINOK(getTextPassword->CryptoGetTextPassword(&password)) AString_Wipe charPassword; if (password) { - /* - // 22.00: do we need UTF-8 passwords here ? - if (item.IsUtf8()) // 22.00 +#if 0 && defined(_WIN32) + // do we need UTF-8 passwords here ? + if (item.GetHostOS() == NFileHeader::NHostOS::kUnix // 24.05 + // || item.IsUtf8() // 22.00 + ) { // throw 1; ConvertUnicodeToUTF8((LPCOLESTR)password, charPassword); } else - */ +#endif { UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP); } @@ -1207,10 +1166,12 @@ mi.Coder = new NCompress::NXz::CComDecoder; else if (id == NFileHeader::NCompressionMethod::kPPMd) mi.Coder = new NCompress::NPpmdZip::CDecoder(true); - #ifdef SUPPORT_LZFSE + else if (id == NFileHeader::NCompressionMethod::kZstdWz) + mi.Coder = new NCompress::NZstd::CDecoder(); +#ifndef Z7_ZIP_LZFSE_DISABLE else if (id == NFileHeader::NCompressionMethod::kWzAES) mi.Coder = new NCompress::NLzfse::CDecoder; - #endif +#endif else { CMethodId szMethodID; @@ -1226,7 +1187,7 @@ szMethodID = kMethodId_ZipBase + (Byte)id; } - RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder)); + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder)) if (!mi.Coder) { @@ -1241,13 +1202,13 @@ ICompressCoder *coder = mi.Coder; - #ifndef _7ZIP_ST + #ifndef Z7_ST { CMyComPtr setCoderMt; coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); if (setCoderMt) { - RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + RINOK(setCoderMt->SetNumberOfThreads(numThreads)) } } // if (memUsage != 0) @@ -1256,7 +1217,7 @@ coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit); if (setMemLimit) { - RINOK(setMemLimit->SetMemLimit(memUsage)); + RINOK(setMemLimit->SetMemLimit(memUsage)) } } #endif @@ -1267,7 +1228,7 @@ if (setDecoderProperties) { Byte properties = (Byte)item.Flags; - RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); + RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)) } } @@ -1293,21 +1254,18 @@ HRESULT result = S_OK; if (item.IsEncrypted()) { - if (!filterStream) - { - filterStreamSpec = new CFilterCoder(false); - filterStream = filterStreamSpec; - } + if (!filterStream.IsDefined()) + filterStream.SetFromCls(new CFilterCoder(false)); - filterReleaser.FilterCoder = filterStreamSpec; - filterStreamSpec->Filter = cryptoFilter; + filterReleaser.FilterCoder = filterStream.ClsPtr(); + filterStream->Filter = cryptoFilter; if (wzAesMode) { - result = _wzAesDecoderSpec->ReadHeader(inStream); + result = _wzAesDecoder->ReadHeader(inStream); if (result == S_OK) { - if (!_wzAesDecoderSpec->Init_and_CheckPassword()) + if (!_wzAesDecoder->Init_and_CheckPassword()) { res = NExtract::NOperationResult::kWrongPassword; return S_OK; @@ -1317,11 +1275,11 @@ else if (pkAesMode) { isFullStreamExpected = false; - result =_pkAesDecoderSpec->ReadHeader(inStream, item.Crc, item.Size); + result = _pkAesDecoder->ReadHeader(inStream, item.Crc, item.Size); if (result == S_OK) { bool passwOK; - result = _pkAesDecoderSpec->Init_and_CheckPassword(passwOK); + result = _pkAesDecoder->Init_and_CheckPassword(passwOK); if (result == S_OK && !passwOK) { res = NExtract::NOperationResult::kWrongPassword; @@ -1331,10 +1289,10 @@ } else { - result = _zipCryptoDecoderSpec->ReadHeader(inStream); + result = _zipCryptoDecoder->ReadHeader(inStream); if (result == S_OK) { - _zipCryptoDecoderSpec->Init_BeforeDecode(); + _zipCryptoDecoder->Init_BeforeDecode(); /* Info-ZIP modification to ZipCrypto format: if bit 3 of the general purpose bit flag is set, @@ -1342,10 +1300,10 @@ Info-ZIP code probably writes 2 bytes of File Time. We check only 1 byte. */ - // UInt32 v1 = GetUi16(_zipCryptoDecoderSpec->_header + NCrypto::NZip::kHeaderSize - 2); + // UInt32 v1 = GetUi16(_zipCryptoDecoder->_header + NCrypto::NZip::kHeaderSize - 2); // UInt32 v2 = (item.HasDescriptor() ? (item.Time & 0xFFFF) : (item.Crc >> 16)); - Byte v1 = _zipCryptoDecoderSpec->_header[NCrypto::NZip::kHeaderSize - 1]; + Byte v1 = _zipCryptoDecoder->_header[NCrypto::NZip::kHeaderSize - 1]; Byte v2 = (Byte)(item.HasDescriptor() ? (item.Time >> 8) : (item.Crc >> 24)); if (v1 != v2) @@ -1363,10 +1321,10 @@ coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); if (setFinishMode) { - RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))); + RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))) } - const UInt64 coderPackSize = limitedStreamSpec->GetRem(); + const UInt64 coderPackSize = inStream->GetRem(); if (id == NFileHeader::NCompressionMethod::kStore && item.IsEncrypted()) { @@ -1382,7 +1340,7 @@ { padStreamSpec = new COutStreamWithPadPKCS7; padStream = padStreamSpec; - padSize = _pkAesDecoderSpec->GetPadSize((UInt32)item.Size); + padSize = _pkAesDecoder->GetPadSize((UInt32)item.Size); padStreamSpec->SetStream(outStream); padStreamSpec->Init(item.Size, padSize); } @@ -1399,12 +1357,12 @@ size = expectedSize; } - result = filterStreamSpec->Code(inStream, padStream ? - (ISequentialOutStream *)padStream : - (ISequentialOutStream *)outStream, + result = filterStream->Code(inStream, padStream ? + padStream.Interface() : + outStream.Interface(), NULL, &size, compressProgress); - if (outStreamSpec->GetSize() != item.Size) + if (outStream->GetSize() != item.Size) truncatedError = true; if (pkAesMode) @@ -1420,20 +1378,20 @@ if (item.IsEncrypted()) { readFromFilter = true; - inStreamReleaser.FilterCoder = filterStreamSpec; - RINOK(filterStreamSpec->SetInStream(inStream)); + inStreamReleaser.FilterCoder = filterStream.ClsPtr(); + RINOK(filterStream->SetInStream(inStream)) /* IFilter::Init() does nothing in all zip crypto filters. So we can call any Initialize function in CFilterCoder. */ - RINOK(filterStreamSpec->Init_NoSubFilterInit()); - // RINOK(filterStreamSpec->SetOutStreamSize(NULL)); + RINOK(filterStream->Init_NoSubFilterInit()) + // RINOK(filterStream->SetOutStreamSize(NULL)); } try { result = coder->Code(readFromFilter ? - (ISequentialInStream *)filterStream : - (ISequentialInStream *)inStream, + filterStream.Interface() : + inStream.Interface(), outStream, isFullStreamExpected ? &coderPackSize : NULL, // NULL, @@ -1448,12 +1406,12 @@ if (getInStreamProcessedSize && setFinishMode) { UInt64 processed; - RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)); + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) if (processed != (UInt64)(Int64)-1) { if (pkAesMode) { - const UInt32 padSize = _pkAesDecoderSpec->GetPadSize((UInt32)processed); + const UInt32 padSize = _pkAesDecoder->GetPadSize((UInt32)processed); if (processed + padSize > coderPackSize) truncatedError = true; else if (processed + padSize < coderPackSize) @@ -1474,7 +1432,7 @@ UInt32 processedSize = 0; if (readInStream) { - RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize)); + RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize)) } if (processedSize > padSize) dataAfterEnd = true; @@ -1519,7 +1477,7 @@ } if (result == S_OK && id == NFileHeader::NCompressionMethod::kLZMA) - if (!lzmaDecoderSpec->DecoderSpec->CheckFinishStatus(item.IsLzmaEOS())) + if (!lzmaDecoderSpec->Decoder->CheckFinishStatus(item.IsLzmaEOS())) lzmaEosError = true; } @@ -1532,38 +1490,38 @@ return S_OK; } - RINOK(result); + RINOK(result) } bool crcOK = true; bool authOk = true; if (needCRC) - crcOK = (outStreamSpec->GetCRC() == item.Crc); + crcOK = (outStream->GetCRC() == item.Crc); if (useUnpackLimit) - if (outStreamSpec->GetSize() != item.Size) + if (outStream->GetSize() != item.Size) truncatedError = true; if (wzAesMode) { - const UInt64 unpackSize = outStreamSpec->GetSize(); - const UInt64 packSize = limitedStreamSpec->GetSize(); + const UInt64 unpackSize = outStream->GetSize(); + const UInt64 packSize = inStream->GetSize(); bool thereAreData = false; // read to the end from filter or from packed stream if (SkipStreamData(readFromFilter ? - (ISequentialInStream *)filterStream : - (ISequentialInStream *)inStream, + filterStream.Interface() : + inStream.Interface(), compressProgress, packSize, unpackSize, thereAreData) != S_OK) authOk = false; if (needReminderCheck && thereAreData) dataAfterEnd = true; - if (limitedStreamSpec->GetRem() != 0) + if (inStream->GetRem() != 0) truncatedError = true; else { - limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize); - if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) + inStream->Init(NCrypto::NWzAes::kMacSize); + if (_wzAesDecoder->CheckMac(inStream, authOk) != S_OK) authOk = false; } } @@ -1600,66 +1558,60 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - CZipDecoder myDecoder; - UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = m_Items.Size(); if (numItems == 0) return S_OK; + UInt64 total = 0; // , totalPacked = 0; UInt32 i; for (i = 0; i < numItems; i++) { const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; - totalUnPacked += item.Size; - totalPacked += item.PackSize; + total += item.Size; + // totalPacked += item.PackSize; } - RINOK(extractCallback->SetTotal(totalUnPacked)); + RINOK(extractCallback->SetTotal(total)) - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; + CZipDecoder myDecoder; + UInt64 cur_Unpacked, cur_Packed; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - for (i = 0; i < numItems; i++, - currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - currentItemUnPacked = 0; - currentItemPacked = 0; - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - RINOK(lps->SetCur()); + for (i = 0;; i++, + lps->OutSize += cur_Unpacked, + lps->InSize += cur_Packed) + { + RINOK(lps->SetCur()) + if (i >= numItems) + return S_OK; + const UInt32 index = allFilesMode ? i : indices[i]; + CItemEx item = m_Items[index]; + cur_Unpacked = item.Size; + cur_Packed = item.PackSize; - CMyComPtr realOutStream; - Int32 askMode = testMode ? + const bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item); + const bool skip = !isLocalOffsetOK && !item.IsDir(); + const Int32 askMode = skip ? + NExtract::NAskMode::kSkip : testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - CItemEx item = m_Items[index]; - bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item); - bool skip = !isLocalOffsetOK && !item.IsDir(); - if (skip) - askMode = NExtract::NAskMode::kSkip; - - currentItemUnPacked = item.Size; - currentItemPacked = item.PackSize; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + Int32 opRes; + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) if (!isLocalOffsetOK) { - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)) continue; } @@ -1668,30 +1620,30 @@ if (!item.FromLocal) { bool isAvail = true; - HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail, headersError); - if (res == S_FALSE) + const HRESULT hres = m_Archive.Read_LocalItem_After_CdItem(item, isAvail, headersError); + if (hres == S_FALSE) { if (item.IsDir() || realOutStream || testMode) { - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); RINOK(extractCallback->SetOperationResult( isAvail ? NExtract::NOperationResult::kHeadersError : - NExtract::NOperationResult::kUnavailable)); + NExtract::NOperationResult::kUnavailable)) } continue; } - RINOK(res); + RINOK(hres) } if (item.IsDir()) { // if (!testMode) { - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) } continue; } @@ -1699,30 +1651,26 @@ if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) - Int32 res; - HRESULT hres = myDecoder.Decode( + const HRESULT hres = myDecoder.Decode( EXTERNAL_CODECS_VARS m_Archive, item, realOutStream, extractCallback, - progress, - #ifndef _7ZIP_ST + lps, + #ifndef Z7_ST _props._numThreads, _props._memUsage_Decompress, #endif - res); + opRes); - RINOK(hres); - realOutStream.Release(); + RINOK(hres) + // realOutStream.Release(); - if (res == NExtract::NOperationResult::kOK && headersError) - res = NExtract::NOperationResult::kHeadersError; - - RINOK(extractCallback->SetOperationResult(res)) + if (opRes == NExtract::NOperationResult::kOK && headersError) + opRes = NExtract::NOperationResult::kHeadersError; + } + RINOK(extractCallback->SetOperationResult(opRes)) } - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - return lps->SetCur(); + COM_TRY_END } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.h 2022-05-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandler.h 2023-03-26 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Zip/Handler.h -#ifndef __ZIP_HANDLER_H -#define __ZIP_HANDLER_H +#ifndef ZIP7_INC_ZIP_HANDLER_H +#define ZIP7_INC_ZIP_HANDLER_H #include "../../../Common/DynamicBuffer.h" #include "../../ICoder.h" @@ -23,46 +23,43 @@ extern const char * const kMethodNames2[kNumMethodNames2]; -class CHandler: +class CHandler Z7_final: public IInArchive, // public IArchiveGetRawProps, public IOutArchive, public ISetProperties, - PUBLIC_ISetCompressCodecsInfo + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC public CMyUnknownImp { -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - // MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IOutArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - // INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IOutArchive(;) - - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - + Z7_COM_QI_BEGIN2(IInArchive) + // Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IOutArchive) + Z7_COM_QI_ENTRY(ISetProperties) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + // Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IOutArchive) + Z7_IFACE_COM7_IMP(ISetProperties) DECL_ISetCompressCodecsInfo - CHandler(); private: CObjectVector m_Items; CInArchive m_Archive; CBaseProps _props; + CHandlerTimeOptions TimeOptions; int m_MainMethod; bool m_ForceAesMode; - - CHandlerTimeOptions TimeOptions; - + bool _removeSfxBlock; bool m_ForceLocal; bool m_ForceUtf8; + bool _force_SeqOutMode; // for creation + bool _force_OpenSeq; bool _forceCodePage; UInt32 _specifiedCodePage; @@ -71,13 +68,15 @@ void InitMethodProps() { _props.Init(); - m_MainMethod = -1; - m_ForceAesMode = false; TimeOptions.Init(); TimeOptions.Prec = k_PropVar_TimePrec_0; + m_MainMethod = -1; + m_ForceAesMode = false; _removeSfxBlock = false; m_ForceLocal = false; m_ForceUtf8 = false; + _force_SeqOutMode = false; + _force_OpenSeq = false; _forceCodePage = false; _specifiedCodePage = CP_OEMCP; } @@ -85,6 +84,9 @@ // void MarkAltStreams(CObjectVector &items); HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value); + +public: + CHandler(); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp 2022-05-07 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp 2023-10-14 18:00:00.000000000 +0000 @@ -28,7 +28,7 @@ namespace NArchive { namespace NZip { -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { *timeType = TimeOptions.Prec; return S_OK; @@ -79,7 +79,7 @@ { filetime.dwHighDateTime = filetime.dwLowDateTime = 0; NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propID, &prop)); + RINOK(callback->GetProperty(index, propID, &prop)) if (prop.vt == VT_FILETIME) filetime = prop.filetime; else if (prop.vt != VT_EMPTY) @@ -88,8 +88,8 @@ } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) { COM_TRY_BEGIN2 @@ -122,7 +122,7 @@ if (!callback) return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) name.Empty(); ui.Clear(); @@ -147,7 +147,7 @@ { { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidAttrib, &prop)); + RINOK(callback->GetProperty(i, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) ui.Attrib = 0; else if (prop.vt != VT_UI4) @@ -158,7 +158,7 @@ { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPath, &prop)); + RINOK(callback->GetProperty(i, kpidPath, &prop)) if (prop.vt == VT_EMPTY) { // name.Empty(); @@ -171,7 +171,7 @@ { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) if (prop.vt == VT_EMPTY) ui.IsDir = false; else if (prop.vt != VT_BOOL) @@ -219,9 +219,9 @@ } */ - if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime)); - if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime)); - if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime)); + if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime)) + if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime)) + if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime)) if (TimeOptions.Prec != k_PropVar_TimePrec_DOS) { @@ -325,7 +325,7 @@ { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidComment, &prop)); + RINOK(callback->GetProperty(i, kpidComment, &prop)) if (prop.vt == VT_EMPTY) { // ui.Comment.Free(); @@ -374,7 +374,7 @@ if (!ui.IsDir) { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; @@ -396,18 +396,18 @@ } CCompressionMethodMode options; (CBaseProps &)options = _props; - options._dataSizeReduce = largestSize; - options._dataSizeReduceDefined = largestSizeDefined; + options.DataSizeReduce = largestSize; + options.DataSizeReduce_Defined = largestSizeDefined; - options.PasswordIsDefined = false; + options.Password_Defined = false; options.Password.Wipe_and_Empty(); if (getTextPassword) { CMyComBSTR_Wipe password; Int32 passwordIsDefined; - RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password)); - options.PasswordIsDefined = IntToBool(passwordIsDefined); - if (options.PasswordIsDefined) + RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password)) + options.Password_Defined = IntToBool(passwordIsDefined); + if (options.Password_Defined) { if (!m_ForceAesMode) options.IsAesMode = thereAreAesUpdates; @@ -439,8 +439,9 @@ { CMethodId methodId; UInt32 numStreams; + bool isFilter; if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true, - methodId, numStreams) < 0) + methodId, numStreams, isFilter) < 0) return E_NOTIMPL; if (numStreams != 1) return E_NOTIMPL; @@ -472,6 +473,8 @@ if (mainMethod != NFileHeader::NCompressionMethod::kStore) options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore); + options.Force_SeqOutMode = _force_SeqOutMode; + CUpdateOptions uo; uo.Write_MTime = TimeOptions.Write_MTime.Val; uo.Write_ATime = TimeOptions.Write_ATime.Val; @@ -493,7 +496,7 @@ -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { InitMethodProps(); @@ -512,17 +515,25 @@ return E_INVALIDARG; { const wchar_t *m = prop.bstrVal; - if (IsString1PrefixedByString2_NoCase_Ascii(m, "aes")) + if (IsString1PrefixedByString2_NoCase_Ascii(m, "AES")) { m += 3; - if (StringsAreEqual_Ascii(m, "128")) - _props.AesKeyMode = 1; - else if (StringsAreEqual_Ascii(m, "192")) - _props.AesKeyMode = 2; - else if (StringsAreEqual_Ascii(m, "256") || m[0] == 0) - _props.AesKeyMode = 3; - else - return E_INVALIDARG; + UInt32 v = 3; + if (*m != 0) + { + if (*m == '-') + m++; + const wchar_t *end; + v = ConvertStringToUInt32(m, &end); + if (*end != 0 || v % 64 != 0) + return E_INVALIDARG; + v /= 64; + v -= 2; + if (v >= 3) + return E_INVALIDARG; + v++; + } + _props.AesKeyMode = (Byte)v; _props.IsAesMode = true; m_ForceAesMode = true; } @@ -540,26 +551,34 @@ else if (name.IsEqualTo("cl")) { - RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal)); + RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal)) if (m_ForceLocal) m_ForceUtf8 = false; } else if (name.IsEqualTo("cu")) { - RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8)); + RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8)) if (m_ForceUtf8) m_ForceLocal = false; } else if (name.IsEqualTo("cp")) { UInt32 cp = CP_OEMCP; - RINOK(ParsePropToUInt32(L"", prop, cp)); + RINOK(ParsePropToUInt32(L"", prop, cp)) _forceCodePage = true; _specifiedCodePage = cp; } else if (name.IsEqualTo("rsfx")) { - RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock)); + RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock)) + } + else if (name.IsEqualTo("rws")) + { + RINOK(PROPVARIANT_to_bool(prop, _force_SeqOutMode)) + } + else if (name.IsEqualTo("ros")) + { + RINOK(PROPVARIANT_to_bool(prop, _force_OpenSeq)) } else { @@ -573,10 +592,10 @@ else { bool processed = false; - RINOK(TimeOptions.Parse(name, prop, processed)); + RINOK(TimeOptions.Parse(name, prop, processed)) if (!processed) { - RINOK(_props.SetProperty(name, prop)); + RINOK(_props.SetProperty(name, prop)) } } // RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop)); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHeader.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHeader.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipHeader.h 2022-05-05 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZipHeader.h -#ifndef __ARCHIVE_ZIP_HEADER_H -#define __ARCHIVE_ZIP_HEADER_H +#ifndef ZIP7_INC_ARCHIVE_ZIP_HEADER_H +#define ZIP7_INC_ARCHIVE_ZIP_HEADER_H #include "../../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.cpp 2022-05-06 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.cpp 2023-12-20 09:00:00.000000000 +0000 @@ -11,8 +11,6 @@ #include "../../../Windows/PropVariant.h" -#include "../../Common/StreamUtils.h" - #include "../IArchive.h" #include "ZipIn.h" @@ -28,9 +26,38 @@ namespace NArchive { namespace NZip { -// (kBufferSize >= kDataDescriptorSize64 + 4) +/* we try to use same size of Buffer (1 << 17) for all tasks. + it allow to avoid reallocations and cache clearing. */ + +static const size_t kSeqBufferSize = (size_t)1 << 17; -static const size_t kSeqBufferSize = (size_t)1 << 14; +/* +Open() +{ + _inBufMode = false; + ReadVols() + FindCd(); + TryEcd64() + SeekToVol() + FindMarker() + _inBufMode = true; + ReadHeaders() + _inBufMode = false; + ReadCd() + FindCd() + TryEcd64() + TryReadCd() + { + SeekToVol(); + _inBufMode = true; + } + _inBufMode = true; + ReadLocals() + ReadCdItem() + .... +} +FindCd() writes to Buffer without touching (_inBufMode) +*/ /* if (not defined ZIP_SELF_CHECK) : it reads CD and if error in first pass CD reading, it reads LOCALS-CD-MODE @@ -187,11 +214,14 @@ return Stream->Seek((Int64)offset, STREAM_SEEK_SET, &_streamPos); } + +/* SeekToVol() will keep the cached mode, if new volIndex is + same Vols.StreamIndex volume, and offset doesn't go out of cached region */ + HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset) { if (volIndex != Vols.StreamIndex) { - InitBuf(); if (IsMultiVol && volIndex >= 0) { if ((unsigned)volIndex >= Vols.Streams.Size()) @@ -221,12 +251,29 @@ return S_OK; } } - InitBuf(); } + InitBuf(); return Seek_SavePos(offset); } +HRESULT CInArchive::AllocateBuffer(size_t size) +{ + if (size <= Buffer.Size()) + return S_OK; + /* in cached mode virtual_pos is not equal to phy_pos (_streamPos) + so we change _streamPos and do Seek() to virtual_pos before cache clearing */ + if (_bufPos != _bufCached) + { + RINOK(Seek_SavePos(GetVirtStreamPos())) + } + InitBuf(); + Buffer.AllocAtLeast(size); + if (!Buffer.IsAllocated()) + return E_OUTOFMEMORY; + return S_OK; +} + // ---------- ReadFromCache ---------- // reads from cache and from Stream // move to next volume can be allowed if (CanStartNewVol) and only before first byte reading @@ -465,7 +512,7 @@ { if (extraSize < 4) { - // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. + // 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers. // so we return k_IsArc_Res_YES to support such archives. // return k_IsArc_Res_NO; // do we need to support such extra ? return k_IsArc_Res_YES; @@ -508,20 +555,46 @@ -MY_NO_INLINE -static const Byte *FindPK(const Byte *p, const Byte *limit) +/* FindPK_4() is allowed to access data up to and including &limit[3]. + limit[4] access is not allowed. + return: + (return_ptr < limit) : "PK" was found at (return_ptr) + (return_ptr >= limit) : limit was reached or crossed. So no "PK" found before limit +*/ +Z7_NO_INLINE +static const Byte *FindPK_4(const Byte *p, const Byte *limit) { for (;;) { for (;;) { - Byte b0; - b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break; - b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break; + if (p >= limit) + return limit; + Byte b = p[1]; + if (b == 0x4B) { if (p[0] == 0x50) { return p; } p += 1; break; } + if (b == 0x50) { if (p[2] == 0x4B) { return p + 1; } p += 2; break; } + b = p[3]; + p += 4; + if (b == 0x4B) { if (p[-2]== 0x50) { return p - 2; } p -= 1; break; } + if (b == 0x50) { if (p[0] == 0x4B) { return p - 1; } break; } + } + } + /* + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; } - if (p[0] == 0x4B) + if (*p == 0x4B) return p - 1; } + */ } @@ -554,7 +627,7 @@ if (searchLimit && *searchLimit == 0) { Byte startBuf[kMarkerSize]; - RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)); + RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)) UInt32 marker = Get32(startBuf); _signature = marker; @@ -562,7 +635,7 @@ if ( marker == NSignature::kNoSpan || marker == NSignature::kSpan) { - RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)); + RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)) _signature = Get32(startBuf); } @@ -579,16 +652,12 @@ return S_OK; } - const size_t kCheckSize = (size_t)1 << 16; // must be smaller than kBufSize - const size_t kBufSize = (size_t)1 << 17; // must be larger than kCheckSize + // zip specification: (_zip_header_size < (1 << 16)) + // so we need such size to check header + const size_t kCheckSize = (size_t)1 << 16; + const size_t kBufSize = (size_t)1 << 17; // (kBufSize must be > kCheckSize) - if (Buffer.Size() < kBufSize) - { - InitBuf(); - Buffer.AllocAtLeast(kBufSize); - if (!Buffer.IsAllocated()) - return E_OUTOFMEMORY; - } + RINOK(AllocateBuffer(kBufSize)) _inBufMode = true; @@ -596,12 +665,13 @@ for (;;) { - RINOK(LookAhead(kBufSize)); + RINOK(LookAhead(kBufSize)) const size_t avail = GetAvail(); size_t limitPos; - const bool isFinished = (avail != kBufSize); + // (avail > kBufSize) is possible, if (Buffer.Size() > kBufSize) + const bool isFinished = (avail < kBufSize); if (isFinished) { const unsigned kMinAllowed = 4; @@ -618,7 +688,7 @@ if (!s.Stream) break; - RINOK(s.SeekToStart()); + RINOK(s.SeekToStart()) InitBuf(); Vols.StreamIndex++; @@ -651,11 +721,15 @@ for (;; p++) { - p = FindPK(p, limit); + p = FindPK_4(p, limit); if (p >= limit) break; - const size_t rem = (size_t)(pStart + avail - p); - UInt32 res = IsArc_Zip_2(p, rem, isFinished); + size_t rem = (size_t)(pStart + avail - p); + /* 22.02 : we limit check size with kCheckSize to be consistent for + any different combination of _bufPos in Buffer and size of Buffer. */ + if (rem > kCheckSize) + rem = kCheckSize; + const UInt32 res = IsArc_Zip_2(p, rem, isFinished); if (res != k_IsArc_Res_NO) { if (rem < kMarkerSize) @@ -689,7 +763,7 @@ { progressPrev = _cnt; // const UInt64 numFiles64 = 0; - RINOK(Callback->SetCompleted(NULL, &_cnt)); + RINOK(Callback->SetCompleted(NULL, &_cnt)) } } @@ -734,6 +808,8 @@ return S_OK; } + // cache is empty + if (!IsMultiVol) { _cnt += offset; @@ -767,7 +843,7 @@ _cnt += offset; return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos); } - RINOK(Seek_SavePos(s.Size)); + RINOK(Seek_SavePos(s.Size)) offset -= rem; _cnt += rem; } @@ -787,7 +863,7 @@ return S_OK; } Stream = s2.Stream; - RINOK(Seek_SavePos(0)); + RINOK(Seek_SavePos(0)) } } @@ -847,7 +923,7 @@ if (!s.Stream) return S_OK; - RINOK(s.SeekToStart()); + RINOK(s.SeekToStart()) Vols.StreamIndex++; _streamPos = 0; @@ -957,7 +1033,7 @@ if (Callback) { const UInt64 numFiles64 = numFiles; - RINOK(Callback->SetCompleted(&numFiles64, &_cnt)); + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) } } } @@ -1000,6 +1076,7 @@ const UInt32 pair = ReadUInt32(); subBlock.ID = (pair & 0xFFFF); unsigned size = (unsigned)(pair >> 16); + // const unsigned origSize = size; extraSize -= 4; @@ -1068,13 +1145,15 @@ } } + // we can ignore errors, when some zip archiver still write all fields to zip64 extra in local header + // if (&& (cdItem || !isOK || origSize != 8 * 3 + 4 || size != 8 * 1 + 4)) if (!isOK || size != 0) { HeadersWarning = true; extra.Error = true; extra.IsZip64_Error = true; - Skip(size); } + Skip(size); } else { @@ -1092,7 +1171,7 @@ { ExtraMinorError = true; extra.MinorError = true; - // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. + // 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers. // so we don't return false, but just set warning flag // return false; Skip(extraSize); @@ -1184,9 +1263,10 @@ mask &= 0x7FFF; } - // we can ignore utf8 flag, if name is ascii + // we can ignore utf8 flag, if name is ascii, or if only cdItem has utf8 flag if (mask & NFileHeader::NFlags::kUtf8) - if (i1.Name.IsAscii() && i2_cd.Name.IsAscii()) + if ((i1.Name.IsAscii() && i2_cd.Name.IsAscii()) + || (i2_cd.Flags & NFileHeader::NFlags::kUtf8)) mask &= ~NFileHeader::NFlags::kUtf8; // some bad archive in rare case can use descriptor without descriptor flag in Central Dir @@ -1270,11 +1350,8 @@ } -HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError) +HRESULT CInArchive::Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError) { - InitBuf(); - _inBufMode = false; - isAvail = true; headersError = false; if (item.FromLocal) @@ -1315,13 +1392,16 @@ } } - RINOK(Seek_SavePos(offset)); - - /* - // we can check buf mode + _inBufMode = false; + RINOK(Seek_SavePos(offset)) InitBuf(); + /* + // we can use buf mode with small buffer to reduce + // the number of Read() calls in ReadLocalItem() _inBufMode = true; - Buffer.AllocAtLeast(1 << 10); + Buffer.Alloc(1 << 10); + if (!Buffer.IsAllocated()) + return E_OUTOFMEMORY; */ CItemEx localItem; @@ -1405,7 +1485,7 @@ // size_t processedSize; CanStartNewVol = true; - RINOK(LookAhead(descriptorSize4)); + RINOK(LookAhead(descriptorSize4)) const size_t avail = GetAvail(); if (avail < descriptorSize4) @@ -1429,7 +1509,7 @@ // descriptor signature field is Info-ZIP's extension to pkware Zip specification. // New ZIP specification also allows descriptorSignature. - p = FindPK(p, limit + 1); + p = FindPK_4(p, limit + 1); if (p > limit) break; @@ -1487,7 +1567,7 @@ { progressPrev = _cnt; const UInt64 numFiles64 = numFiles; - RINOK(Callback->SetCompleted(&numFiles64, &_cnt)); + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) } } } @@ -1501,7 +1581,7 @@ // pkzip's version without descriptor signature is not supported bool isFinished = false; - RINOK(IncreaseRealPosition(item.PackSize, isFinished)); + RINOK(IncreaseRealPosition(item.PackSize, isFinished)) if (isFinished) return S_FALSE; @@ -1548,7 +1628,7 @@ } -HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) +HRESULT CInArchive::Read_LocalItem_After_CdItem_Full(CItemEx &item) { if (item.FromLocal) return S_OK; @@ -1556,7 +1636,7 @@ { bool isAvail = true; bool headersError = false; - RINOK(ReadLocalItemAfterCdItem(item, isAvail, headersError)); + RINOK(Read_LocalItem_After_CdItem(item, isAvail, headersError)) if (headersError) return S_FALSE; if (item.HasDescriptor()) @@ -1606,14 +1686,22 @@ } +/* +TryEcd64() + (_inBufMode == false) is expected here + so TryEcd64() can't change the Buffer. + if (Ecd64 is not covered by cached region), + TryEcd64() can change cached region ranges (_bufCached, _bufPos) and _streamPos. +*/ + HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) { if (offset >= ((UInt64)1 << 63)) return S_FALSE; Byte buf[kEcd64_FullSize]; - RINOK(SeekToVol(Vols.StreamIndex, offset)); - RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize)); + RINOK(SeekToVol(Vols.StreamIndex, offset)) + RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize)) if (Get32(buf) != NSignature::kEcd64) return S_FALSE; @@ -1625,6 +1713,9 @@ } +/* FindCd() doesn't use previous cached region, + but it uses Buffer. So it sets new cached region */ + HRESULT CInArchive::FindCd(bool checkOffsetMode) { CCdInfo &cdInfo = Vols.ecd; @@ -1635,7 +1726,7 @@ // So here we don't use cache data from previous operations . InitBuf(); - RINOK(Stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(InStream_GetSize_SeekToEnd(Stream, endPos)) _streamPos = endPos; // const UInt32 kBufSizeMax2 = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize; @@ -1646,15 +1737,9 @@ return S_FALSE; // CByteArr byteBuffer(bufSize); - if (Buffer.Size() < kBufSizeMax) - { - // InitBuf(); - Buffer.AllocAtLeast(kBufSizeMax); - if (!Buffer.IsAllocated()) - return E_OUTOFMEMORY; - } + RINOK(AllocateBuffer(kBufSizeMax)) - RINOK(Seek_SavePos(endPos - bufSize)); + RINOK(Seek_SavePos(endPos - bufSize)) size_t processed = bufSize; HRESULT res = ReadStream(Stream, Buffer, &processed); @@ -1799,14 +1884,14 @@ // _startLocalFromCd_Disk = (UInt32)(Int32)-1; // _startLocalFromCd_Offset = (UInt64)(Int64)-1; - RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset)); + RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset)) _inBufMode = true; _cnt = 0; if (Callback) { - RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL)); + RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL)) } UInt64 numFileExpected = cdInfo.NumEntries; const UInt64 *totalFilesPtr = &numFileExpected; @@ -1820,7 +1905,7 @@ CanStartNewVol = false; { CItemEx cdItem; - RINOK(ReadCdItem(cdItem)); + RINOK(ReadCdItem(cdItem)) /* if (cdItem.Disk < _startLocalFromCd_Disk || @@ -1854,10 +1939,10 @@ else while (numFiles > numFileExpected) numFileExpected += (UInt32)1 << 16; - RINOK(Callback->SetTotal(totalFilesPtr, NULL)); + RINOK(Callback->SetTotal(totalFilesPtr, NULL)) } - RINOK(Callback->SetCompleted(&numFiles, &_cnt)); + RINOK(Callback->SetCompleted(&numFiles, &_cnt)) } } @@ -1900,7 +1985,7 @@ if (!Vols.ecd_wasRead) { - RINOK(FindCd(checkOffsetMode)); + RINOK(FindCd(checkOffsetMode)) } CCdInfo &cdInfo = Vols.ecd; @@ -2004,7 +2089,7 @@ if (Callback) { - RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL)); + RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL)) } while (_signature == NSignature::kLocalFileHeader) @@ -2023,14 +2108,14 @@ if (item.HasDescriptor()) { - RINOK(FindDescriptor(item, items.Size())); + RINOK(FindDescriptor(item, items.Size())) isFinished = !item.DescriptorWasRead; } else { if (item.PackSize >= ((UInt64)1 << 62)) throw CUnexpectEnd(); - RINOK(IncreaseRealPosition(item.PackSize, isFinished)); + RINOK(IncreaseRealPosition(item.PackSize, isFinished)) } items.Add(item); @@ -2054,7 +2139,7 @@ { progressPrev = _cnt; const UInt64 numFiles = items.Size(); - RINOK(Callback->SetCompleted(&numFiles, &_cnt)); + RINOK(Callback->SetCompleted(&numFiles, &_cnt)) } } @@ -2072,7 +2157,7 @@ UString name; { NWindows::NCOM::CPropVariant prop; - RINOK(volCallback->GetProperty(kpidName, &prop)); + RINOK(volCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) return S_OK; name = prop.bstrVal; @@ -2197,10 +2282,10 @@ { UString volName = Vols.BaseName; { - volName += (char)(Vols.IsUpperCase ? 'Z' : 'z'); - unsigned v = i + 1; + volName.Add_Char(Vols.IsUpperCase ? 'Z' : 'z'); + const unsigned v = i + 1; if (v < 10) - volName += '0'; + volName.Add_Char('0'); volName.Add_UInt32(v); } @@ -2235,11 +2320,8 @@ } } - UInt64 size; - UInt64 pos; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &pos)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(stream->Seek((Int64)pos, STREAM_SEEK_SET, NULL)); + UInt64 pos, size; + RINOK(InStream_GetPos_GetSize(stream, pos, size)) while (i >= Vols.Streams.Size()) Vols.Streams.AddNew(); @@ -2270,7 +2352,7 @@ if (!volCallback) return S_OK; - RINOK(Vols.ParseArcName(volCallback)); + RINOK(Vols.ParseArcName(volCallback)) // const int startZIndex = Vols.StartVolIndex; @@ -2324,7 +2406,7 @@ if (cdDisk != zipDisk) { // get volumes required for cd. - RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols)); + RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols)) if (numMissingVols != 0) { // cdOK = false; @@ -2352,7 +2434,7 @@ { // get volumes that were no requested still const unsigned kNumMissingVolsMax = 1 << 12; - RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols)); + RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols)) } // if (Vols.StartVolIndex >= 0) @@ -2364,7 +2446,7 @@ || !Vols.Streams[(unsigned)Vols.StartVolIndex].Stream) { // we get volumes starting from StartVolIndex, if they we not requested before know the volume index (if FindCd() was ok) - RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols)); + RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols)) } } @@ -2377,7 +2459,7 @@ if (zipDisk >= 0) { // we create item in Streams for ZipStream, if we know the volume index (if FindCd() was ok) - RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols)); + RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols)) } } @@ -2428,7 +2510,7 @@ return S_FALSE; if (NeedSeek) { - RINOK(s.SeekToStart()); + RINOK(s.SeekToStart()) NeedSeek = false; } UInt32 realProcessedSize = 0; @@ -2444,7 +2526,7 @@ } } -STDMETHODIMP CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { return Vols->Read(data, size, processedSize); } @@ -2458,14 +2540,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector &items) { - if (Buffer.Size() < kSeqBufferSize) - { - InitBuf(); - Buffer.AllocAtLeast(kSeqBufferSize); - if (!Buffer.IsAllocated()) - return E_OUTOFMEMORY; - } + // buffer that can be used for cd reading + RINOK(AllocateBuffer(kSeqBufferSize)) + // here we can read small records. So we switch off _inBufMode. _inBufMode = false; HRESULT res = S_OK; @@ -2488,6 +2566,13 @@ UInt64 cdAbsOffset = 0; // absolute cd offset, for LOCALS-CD-MODE only. +if (Force_ReadLocals_Mode) +{ + IsArc = true; + res = S_FALSE; // we will use LOCALS-CD-MODE mode +} +else +{ if (!MarkerIsFound || !MarkerIsSafe) { IsArc = true; @@ -2497,7 +2582,7 @@ else if (res != S_FALSE) return res; } - else + else // (MarkerIsFound && MarkerIsSafe) { // _signature must be kLocalFileHeader or kEcd or kEcd64 @@ -2528,7 +2613,7 @@ return S_FALSE; } - RINOK(Skip64(recordSize - kEcd64_MainSize, 0)); + RINOK(Skip64(recordSize - kEcd64_MainSize, 0)) } ReadSignature(); @@ -2568,7 +2653,7 @@ ArcInfo.Base = (Int64)ArcInfo.MarkerPos; IsArc = true; // check it: we need more tests? - RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)); + RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)) ReadSignature(); } else @@ -2650,8 +2735,9 @@ } } } - } + } // (MarkerIsFound && MarkerIsSafe) +} // (!onlyLocalsMode) CObjectVector cdItems; @@ -2676,17 +2762,20 @@ HeadersWarning = false; ExtraMinorError = false; - // we can use any mode: with buffer and without buffer - // without buffer : skips packed data : fast for big files : slow for small files - // with buffer : reads packed data : slow for big files : fast for small files - - _inBufMode = false; - // _inBufMode = true; - - InitBuf(); + /* we can use any mode: with buffer and without buffer + without buffer : skips packed data : fast for big files : slow for small files + with buffer : reads packed data : slow for big files : fast for small files + Buffer mode is more effective. */ + // _inBufMode = false; + _inBufMode = true; + // we could change the buffer size here, if we want smaller Buffer. + // RINOK(ReAllocateBuffer(kSeqBufferSize)); + // InitBuf() ArcInfo.Base = 0; + if (!Disable_FindMarker) + { if (!MarkerIsFound) { if (!IsMultiVol) @@ -2695,7 +2784,7 @@ return S_FALSE; // if (StartParsingVol == 0) and we didn't find marker, we use default zero marker. // so we suppose that there is no sfx stub - RINOK(SeekToVol(0, ArcInfo.MarkerPos2)); + RINOK(SeekToVol(0, ArcInfo.MarkerPos2)) } else { @@ -2710,17 +2799,16 @@ */ ArcInfo.Base = (Int64)ArcInfo.MarkerPos2; } - - RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)); + RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)) } - + } _cnt = 0; ReadSignature(); LocalsWereRead = true; - RINOK(ReadLocals(items)); + RINOK(ReadLocals(items)) if (_signature != NSignature::kCentralFileHeader) { @@ -2775,14 +2863,14 @@ { CItemEx cdItem; - RINOK(ReadCdItem(cdItem)); + RINOK(ReadCdItem(cdItem)) cdItems.Add(cdItem); if (Callback && (cdItems.Size() & 0xFFF) == 0) { const UInt64 numFiles = items.Size(); const UInt64 numBytes = _cnt; - RINOK(Callback->SetCompleted(&numFiles, &numBytes)); + RINOK(Callback->SetCompleted(&numFiles, &numBytes)) } ReadSignature(); if (_signature != NSignature::kCentralFileHeader) @@ -2842,7 +2930,7 @@ cdInfo.ParseEcd64e(buf); } - RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size())); + RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size())) } @@ -2886,12 +2974,12 @@ ecd.Parse(buf); } - COPY_ECD_ITEM_16(ThisDisk); - COPY_ECD_ITEM_16(CdDisk); - COPY_ECD_ITEM_16(NumEntries_in_ThisDisk); - COPY_ECD_ITEM_16(NumEntries); - COPY_ECD_ITEM_32(Size); - COPY_ECD_ITEM_32(Offset); + COPY_ECD_ITEM_16(ThisDisk) + COPY_ECD_ITEM_16(CdDisk) + COPY_ECD_ITEM_16(NumEntries_in_ThisDisk) + COPY_ECD_ITEM_16(NumEntries) + COPY_ECD_ITEM_32(Size) + COPY_ECD_ITEM_32(Offset) bool cdOK = true; @@ -3040,7 +3128,7 @@ if ((i & 0x3FFF) == 0) { const UInt64 numFiles64 = items.Size() + items2.Size(); - RINOK(Callback->SetCompleted(&numFiles64, &_cnt)); + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) } const CItemEx &cdItem = cdItems[i]; @@ -3093,6 +3181,9 @@ item.ExternalAttrib = cdItem.ExternalAttrib; item.Comment = cdItem.Comment; item.FromCentral = cdItem.FromCentral; + // 22.02: we force utf8 flag, if central header has utf8 flag + if (cdItem.Flags & NFileHeader::NFlags::kUtf8) + item.Flags |= NFileHeader::NFlags::kUtf8; } FOR_VECTOR (k, items2) @@ -3175,8 +3266,8 @@ Close(); UInt64 startPos; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &startPos)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileEndPos)); + RINOK(InStream_GetPos(stream, startPos)) + RINOK(InStream_GetSize_SeekToEnd(stream, ArcInfo.FileEndPos)) _streamPos = ArcInfo.FileEndPos; StartStream = stream; @@ -3187,18 +3278,30 @@ bool volWasRequested = false; + if (!Disable_VolsRead) if (callback && (startPos == 0 || !searchLimit || *searchLimit != 0)) { // we try to read volumes only if it's first call (offset == 0) or scan is allowed. volWasRequested = true; - RINOK(ReadVols()); + RINOK(ReadVols()) } + if (Disable_FindMarker) + { + RINOK(SeekToVol(-1, startPos)) + StreamRef = stream; + Stream = stream; + MarkerIsFound = true; + MarkerIsSafe = true; + ArcInfo.MarkerPos = startPos; + ArcInfo.MarkerPos2 = startPos; + } + else if (IsMultiVol && Vols.StartParsingVol == 0 && (unsigned)Vols.StartParsingVol < Vols.Streams.Size()) { // only StartParsingVol = 0 is safe search. - RINOK(SeekToVol(0, 0)); + RINOK(SeekToVol(0, 0)) // if (Stream) { // UInt64 limit = 1 << 22; // for sfx @@ -3222,11 +3325,11 @@ && (unsigned)Vols.StartParsingVol < Vols.Streams.Size() && Vols.Streams[(unsigned)Vols.StartParsingVol].Stream) { - RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0)); + RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0)) } else { - RINOK(SeekToVol(-1, startPos)); + RINOK(SeekToVol(-1, startPos)) } // UInt64 limit = 1 << 22; @@ -3242,8 +3345,8 @@ else if (!IsMultiVol) { /* - // if (startPos != 0), probably CD copuld be already tested with another call with (startPos == 0). - // so we don't want to try to open CD again in that ase. + // if (startPos != 0), probably CD could be already tested with another call with (startPos == 0). + // so we don't want to try to open CD again in that case. if (startPos != 0) return res; // we can try to open CD, if there is no Marker and (startPos == 0). @@ -3254,7 +3357,7 @@ if (ArcInfo.IsSpanMode && !volWasRequested) { - RINOK(ReadVols()); + RINOK(ReadVols()) if (IsMultiVol && MarkerIsFound && ArcInfo.MarkerVolIndex < 0) ArcInfo.MarkerVolIndex = Vols.StartVolIndex; } @@ -3271,7 +3374,7 @@ Stream = Vols.Streams[(unsigned)Vols.StartVolIndex].Stream; if (Stream) { - RINOK(Seek_SavePos(curPos)); + RINOK(Seek_SavePos(curPos)) } else IsMultiVol = false; @@ -3287,7 +3390,7 @@ Stream = StartStream; Vols.StreamIndex = -1; InitBuf(); - RINOK(Seek_SavePos(curPos)); + RINOK(Seek_SavePos(curPos)) } ArcInfo.MarkerVolIndex = -1; @@ -3356,7 +3459,7 @@ if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex) return S_OK; pos = (UInt64)((Int64)pos + ArcInfo.Base); - RINOK(StreamRef->Seek((Int64)pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(StreamRef, pos)) stream = StreamRef; return S_OK; } @@ -3367,7 +3470,7 @@ IInStream *str2 = Vols.Streams[item.Disk].Stream; if (!str2) return S_OK; - RINOK(str2->Seek((Int64)pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(str2, pos)) Vols.NeedSeek = false; Vols.StreamIndex = (int)item.Disk; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.h 2021-07-30 07:34:44.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipIn.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,11 +1,12 @@ // Archive/ZipIn.h -#ifndef __ZIP_IN_H -#define __ZIP_IN_H +#ifndef ZIP7_INC_ZIP_IN_H +#define ZIP7_INC_ZIP_IN_H #include "../../../Common/MyBuffer2.h" #include "../../../Common/MyCom.h" +#include "../../Common/StreamUtils.h" #include "../../IStream.h" #include "ZipHeader.h" @@ -154,7 +155,7 @@ CMyComPtr Stream; UInt64 Size; - HRESULT SeekToStart() const { return Stream->Seek(0, STREAM_SEEK_SET, NULL); } + HRESULT SeekToStart() const { return InStream_SeekToBegin(Stream); } CSubStreamInfo(): Size(0) {} }; @@ -233,16 +234,12 @@ }; -class CVolStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CVolStream + , ISequentialInStream +) public: CVols *Vols; - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; @@ -269,6 +266,8 @@ _cnt += skip; } + HRESULT AllocateBuffer(size_t size); + UInt64 GetVirtStreamPos() { return _streamPos - _bufCached + _bufPos; } bool _inBufMode; @@ -353,12 +352,19 @@ UInt32 EcdVolIndex; CVols Vols; + + bool Force_ReadLocals_Mode; + bool Disable_VolsRead; + bool Disable_FindMarker; CInArchive(): IsArcOpen(false), Stream(NULL), StartStream(NULL), - Callback(NULL) + Callback(NULL), + Force_ReadLocals_Mode(false), + Disable_VolsRead(false), + Disable_FindMarker(false) {} UInt64 GetPhySize() const @@ -412,8 +418,8 @@ HRESULT CheckDescriptor(const CItemEx &item); - HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError); - HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); + HRESULT Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError); + HRESULT Read_LocalItem_After_CdItem_Full(CItemEx &item); HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr &stream); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.cpp 2022-05-05 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -45,7 +45,7 @@ void CExtraSubBlock::PrintInfo(AString &s) const { - for (unsigned i = 0; i < ARRAY_SIZE(g_ExtraTypes); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExtraTypes); i++) { const CUInt32PCharPair &pair = g_ExtraTypes[i]; if (pair.Value == ID) @@ -55,15 +55,15 @@ { if (Data.Size() >= 1) { - s += ':'; + s.Add_Colon(); const Byte flags = Data[0]; - if (flags & 1) s += 'M'; - if (flags & 2) s += 'A'; - if (flags & 4) s += 'C'; + if (flags & 1) s.Add_Char('M'); + if (flags & 2) s.Add_Char('A'); + if (flags & 4) s.Add_Char('C'); const UInt32 size = (UInt32)(Data.Size()) - 1; if (size % 4 == 0) { - s += ':'; + s.Add_Colon(); s.Add_UInt32(size / 4); } } @@ -88,7 +88,7 @@ } } { - char sz[32]; + char sz[16]; sz[0] = '0'; sz[1] = 'x'; ConvertUInt32ToHex(ID, sz + 2); @@ -291,6 +291,7 @@ case NHostOS::kHPFS: case NHostOS::kVFAT: return true; + default: break; } } @@ -360,6 +361,7 @@ // #endif } break; + default: break; } if (IsDir()) // test it; winAttrib |= FILE_ATTRIBUTE_DIRECTORY; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.h 2022-05-05 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Archive/ZipItem.h -#ifndef __ARCHIVE_ZIP_ITEM_H -#define __ARCHIVE_ZIP_ITEM_H +#ifndef ZIP7_INC_ARCHIVE_ZIP_ITEM_H +#define ZIP7_INC_ARCHIVE_ZIP_ITEM_H #include "../../../../C/CpuArch.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.cpp 2022-05-08 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.cpp 2023-03-26 11:00:00.000000000 +0000 @@ -12,6 +12,20 @@ namespace NArchive { namespace NZip { +HRESULT COutArchive::ClearRestriction() +{ + if (SetRestriction) + return SetRestriction->SetRestriction(0, 0); + return S_OK; +} + +HRESULT COutArchive::SetRestrictionFromCurrent() +{ + if (SetRestriction) + return SetRestriction->SetRestriction(m_Base + m_CurPos, (UInt64)(Int64)-1); + return S_OK; +} + HRESULT COutArchive::Create(IOutStream *outStream) { m_CurPos = 0; @@ -97,7 +111,7 @@ } -#define WRITE_32_VAL_SPEC(__v, __isZip64) Write32((__isZip64) ? 0xFFFFFFFF : (UInt32)(__v)); +#define WRITE_32_VAL_SPEC(_v_, _isZip64_) Write32((_isZip64_) ? 0xFFFFFFFF : (UInt32)(_v_)); void COutArchive::WriteUtfName(const CItemOut &item) @@ -192,8 +206,8 @@ size = 0; } - WRITE_32_VAL_SPEC(packSize, isZip64); - WRITE_32_VAL_SPEC(size, isZip64); + WRITE_32_VAL_SPEC(packSize, isZip64) + WRITE_32_VAL_SPEC(size, isZip64) Write16((UInt16)item.Name.Len()); @@ -249,19 +263,19 @@ void COutArchive::WriteDescriptor(const CItemOut &item) { Byte buf[kDataDescriptorSize64]; - SetUi32(buf, NSignature::kDataDescriptor); - SetUi32(buf + 4, item.Crc); + SetUi32(buf, NSignature::kDataDescriptor) + SetUi32(buf + 4, item.Crc) unsigned descriptorSize; if (m_IsZip64) { - SetUi64(buf + 8, item.PackSize); - SetUi64(buf + 16, item.Size); + SetUi64(buf + 8, item.PackSize) + SetUi64(buf + 16, item.Size) descriptorSize = kDataDescriptorSize64; } else { - SetUi32(buf + 8, (UInt32)item.PackSize); - SetUi32(buf + 12, (UInt32)item.Size); + SetUi32(buf + 8, (UInt32)item.PackSize) + SetUi32(buf + 12, (UInt32)item.Size) descriptorSize = kDataDescriptorSize32; } WriteBytes(buf, descriptorSize); @@ -283,8 +297,8 @@ WriteCommonItemInfo(item, isZip64); Write32(item.Crc); - WRITE_32_VAL_SPEC(item.PackSize, isPack64); - WRITE_32_VAL_SPEC(item.Size, isUnPack64); + WRITE_32_VAL_SPEC(item.PackSize, isPack64) + WRITE_32_VAL_SPEC(item.Size, isUnPack64) Write16((UInt16)item.Name.Len()); @@ -306,10 +320,10 @@ const UInt16 commentSize = (UInt16)item.Comment.Size(); Write16(commentSize); - Write16(0); // DiskNumberStart; + Write16(0); // DiskNumberStart Write16(item.InternalAttrib); Write32(item.ExternalAttrib); - WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64); + WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64) WriteBytes((const char *)item.Name, item.Name.Len()); if (isZip64) @@ -332,8 +346,10 @@ WriteBytes(item.Comment, commentSize); } -void COutArchive::WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment) +HRESULT COutArchive::WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment) { + RINOK(ClearRestriction()) + const UInt64 cdOffset = GetCurPos(); FOR_VECTOR (i, items) WriteCentralHeader(items[i]); @@ -357,8 +373,8 @@ Write16(45); // made by version Write16(45); // extract version - Write32(0); // ThisDiskNumber = 0; - Write32(0); // StartCentralDirectoryDiskNumber;; + Write32(0); // ThisDiskNumber + Write32(0); // StartCentralDirectoryDiskNumber Write64((UInt64)items.Size()); Write64((UInt64)items.Size()); Write64((UInt64)cdSize); @@ -373,19 +389,20 @@ } Write32(NSignature::kEcd); - Write16(0); // ThisDiskNumber = 0; - Write16(0); // StartCentralDirectoryDiskNumber; + Write16(0); // ThisDiskNumber + Write16(0); // StartCentralDirectoryDiskNumber Write16((UInt16)(items64 ? 0xFFFF: items.Size())); Write16((UInt16)(items64 ? 0xFFFF: items.Size())); - WRITE_32_VAL_SPEC(cdSize, cdSize64); - WRITE_32_VAL_SPEC(cdOffset, cdOffset64); + WRITE_32_VAL_SPEC(cdSize, cdSize64) + WRITE_32_VAL_SPEC(cdOffset, cdOffset64) const UInt16 commentSize = (UInt16)(comment ? comment->Size() : 0); Write16((UInt16)commentSize); if (commentSize != 0) WriteBytes((const Byte *)*comment, commentSize); m_OutBuffer.FlushWithCheck(); + return S_OK; } void COutArchive::CreateStreamForCompressing(CMyComPtr &outStream) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.h 2022-01-26 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipOut.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZipOut.h -#ifndef __ZIP_OUT_H -#define __ZIP_OUT_H +#ifndef ZIP7_INC_ZIP_OUT_H +#define ZIP7_INC_ZIP_OUT_H #include "../../../Common/MyCom.h" @@ -74,6 +74,10 @@ void SeekToCurPos(); public: + CMyComPtr SetRestriction; + + HRESULT ClearRestriction(); + HRESULT SetRestrictionFromCurrent(); HRESULT Create(IOutStream *outStream); UInt64 GetCurPos() const { return m_CurPos; } @@ -88,7 +92,7 @@ void WriteDescriptor(const CItemOut &item); - void WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment); + HRESULT WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment); void CreateStreamForCompressing(CMyComPtr &outStream); void CreateStreamForCopying(CMyComPtr &outStream); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipRegister.cpp 2022-05-08 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -17,7 +17,7 @@ 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; // NoSpan REGISTER_ARC_IO( - "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", 0, 1, + "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", NULL, 1, k_Signature, 0, NArcInfoFlags::kFindSignature diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2022-05-07 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2025-07-03 09:00:00.000000000 +0000 @@ -2,6 +2,15 @@ #include "StdAfx.h" +// #define DEBUG_CACHE + +#ifdef DEBUG_CACHE +#include + #define PRF(x) x +#else + #define PRF(x) +#endif + #include "../../../../C/Alloc.h" #include "../../../Common/AutoPtr.h" @@ -15,12 +24,13 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/OutMemStream.h" #include "../../Common/ProgressUtils.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Common/ProgressMt.h" #endif #include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" +// #include "../../Compress/ZstdEncoderProps.h" #include "ZipAddCommon.h" #include "ZipOut.h" @@ -107,7 +117,7 @@ item.ExtractVersion.HostOS = kExtractHostOS; item.InternalAttrib = 0; // test it - item.SetEncrypted(!isDir && options.PasswordIsDefined); + item.SetEncrypted(!isDir && options.Password_Defined); item.SetDescriptorMode(useDescriptor); if (isDir) @@ -156,7 +166,7 @@ } -#ifndef _7ZIP_ST +#ifndef Z7_ST struct CMtSem { @@ -191,7 +201,7 @@ struct CThreadInfo { - DECL_EXTERNAL_CODECS_LOC_VARS2; + DECL_EXTERNAL_CODECS_LOC_VARS_DECL NWindows::CThread Thread; NWindows::NSynchronization::CAutoResetEvent CompressEvent; @@ -211,19 +221,24 @@ HRESULT Result; CCompressingResult CompressingResult; + bool IsFree; bool InSeqMode; bool OutSeqMode; - bool IsFree; + bool ExpectedDataSize_IsConfirmed; + UInt32 UpdateIndex; UInt32 FileTime; UInt64 ExpectedDataSize; CThreadInfo(): + MtSem(NULL), ExitThread(false), ProgressSpec(NULL), OutStreamSpec(NULL), + IsFree(true), InSeqMode(false), OutSeqMode(false), + ExpectedDataSize_IsConfirmed(false), FileTime(0), ExpectedDataSize((UInt64)(Int64)-1) {} @@ -235,13 +250,26 @@ HRESULT CreateEvents() { - WRes wres = CompressEvent.CreateIfNotCreated_Reset(); + const WRes wres = CompressEvent.CreateIfNotCreated_Reset(); return HRESULT_FROM_WIN32(wres); } - HRESULT CreateThread() + // (group < 0) means no_group. + HRESULT CreateThread_with_group( +#ifdef _WIN32 + int group +#endif + ) { - WRes wres = Thread.Create(CoderThread, this); + // tested in win10: If thread is created by another thread, + // child thread probably uses same group as parent thread. + // So we don't need to send (group) to encoder in created thread. + const WRes wres = +#ifdef _WIN32 + group >= 0 ? + Thread.Create_With_Group(CoderThread, this, (unsigned)group) : +#endif + Thread.Create(CoderThread, this); return HRESULT_FROM_WIN32(wres); } @@ -270,6 +298,7 @@ EXTERNAL_CODECS_LOC_VARS InStream, OutStream, InSeqMode, OutSeqMode, FileTime, ExpectedDataSize, + ExpectedDataSize_IsConfirmed, Progress, CompressingResult); if (Result == S_OK && Progress) @@ -313,7 +342,7 @@ public: CMemBlockManagerMt *Manager; CObjectVector Refs; - CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ; + CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ~CMemRefs() { FOR_VECTOR (i, Refs) @@ -321,10 +350,11 @@ } }; -class CMtProgressMixer2: - public ICompressProgressInfo, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CMtProgressMixer2 + , ICompressProgressInfo +) UInt64 ProgressOffset; UInt64 InSizes[2]; UInt64 OutSizes[2]; @@ -333,12 +363,10 @@ bool _inSizeIsMain; public: NWindows::NSynchronization::CCriticalSection CriticalSection; - MY_UNKNOWN_IMP void Create(IProgress *progress, bool inSizeIsMain); void SetProgressOffset(UInt64 progressOffset); void SetProgressOffset_NoLock(UInt64 progressOffset); HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize); - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; void CMtProgressMixer2::Create(IProgress *progress, bool inSizeIsMain) @@ -367,7 +395,7 @@ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); if (index == 0 && RatioProgress) { - RINOK(RatioProgress->SetRatioInfo(inSize, outSize)); + RINOK(RatioProgress->SetRatioInfo(inSize, outSize)) } if (inSize) InSizes[index] = *inSize; @@ -379,21 +407,20 @@ return Progress->SetCompleted(&v); } -STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { return SetRatioInfo(0, inSize, outSize); } -class CMtProgressMixer: - public ICompressProgressInfo, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CMtProgressMixer + , ICompressProgressInfo +) public: CMtProgressMixer2 *Mixer2; CMyComPtr RatioProgress; void Create(IProgress *progress, bool inSizeIsMain); - MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; void CMtProgressMixer::Create(IProgress *progress, bool inSizeIsMain) @@ -403,7 +430,7 @@ Mixer2->Create(progress, inSizeIsMain); } -STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { return Mixer2->SetRatioInfo(1, inSize, outSize); } @@ -431,11 +458,17 @@ UInt64 rangeSize; + RINOK(archive.ClearRestriction()) + if (ui.NewProps) { if (item.HasDescriptor()) - return E_NOTIMPL; - + { + // we know compressed / uncompressed sizes and crc. + // so we remove descriptor here + item.Flags = (UInt16)(item.Flags & ~NFileHeader::NFlags::kDescriptorUsedMask); + // return E_NOTIMPL; + } // we keep ExternalAttrib and some another properties from old archive // item.ExternalAttrib = ui.Attrib; // if we don't change Comment, we keep Comment from OldProperties @@ -456,7 +489,7 @@ CMyComPtr packStream; - RINOK(inArchive->GetItemStream(itemEx, ui.NewProps, packStream)); + RINOK(inArchive->GetItemStream(itemEx, ui.NewProps, packStream)) if (!packStream) return E_NOTIMPL; @@ -470,11 +503,13 @@ } -static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, +static HRESULT WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, const CUpdateItem &ui, CItemOut &item) { SetFileHeader(*options, ui, false, item); + RINOK(archive.ClearRestriction()) archive.WriteLocalHeader(item); + return S_OK; } @@ -485,37 +520,55 @@ { CMyComPtr getProps; fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); - if (!getProps) - return; - - FILETIME cTime, aTime, mTime; - UInt64 size; - UInt32 attrib; - if (getProps->GetProps(&size, &cTime, &aTime, &mTime, &attrib) != S_OK) - return; + UInt64 size = (UInt64)(Int64)-1; + bool size_WasSet = false; - if (size != item.Size && size != (UInt64)(Int64)-1) + if (getProps) { - const Int64 newComplexity = (Int64)totalComplexity + ((Int64)size - (Int64)item.Size); - if (newComplexity > 0) + FILETIME cTime, aTime, mTime; + UInt32 attrib; + if (getProps->GetProps(&size, &cTime, &aTime, &mTime, &attrib) == S_OK) { - totalComplexity = (UInt64)newComplexity; - updateCallback->SetTotal(totalComplexity); + if (options.Write_MTime) + if (!FILETIME_IsZero(mTime)) + { + item.Ntfs_MTime = mTime; + NTime::UtcFileTime_To_LocalDosTime(mTime, item.Time); + } + + if (options.Write_CTime) if (!FILETIME_IsZero(cTime)) item.Ntfs_CTime = cTime; + if (options.Write_ATime) if (!FILETIME_IsZero(aTime)) item.Ntfs_ATime = aTime; + + item.Attrib = attrib; + size_WasSet = true; } - item.Size = size; } - if (options.Write_MTime) - if (!FILETIME_IsZero(mTime)) + if (!size_WasSet) + { + CMyComPtr streamGetSize; + fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize); + if (streamGetSize) { - item.Ntfs_MTime = mTime; - NTime::UtcFileTime_To_LocalDosTime(mTime, item.Time); + if (streamGetSize->GetSize(&size) == S_OK) + size_WasSet = true; } + } - if (options.Write_CTime) if (!FILETIME_IsZero(cTime)) item.Ntfs_CTime = cTime; - if (options.Write_ATime) if (!FILETIME_IsZero(aTime)) item.Ntfs_ATime = aTime; - - item.Attrib = attrib; + if (size_WasSet && size != (UInt64)(Int64)-1) + { + item.Size_WasSetFromStream = true; + if (size != item.Size) + { + const Int64 newComplexity = (Int64)totalComplexity + ((Int64)size - (Int64)item.Size); + if (newComplexity > 0) + { + totalComplexity = (UInt64)newComplexity; + updateCallback->SetTotal(totalComplexity); + } + item.Size = size; + } + } } @@ -613,7 +666,7 @@ { lps->InSize = unpackSizeTotal; lps->OutSize = packSizeTotal; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CUpdateItem &ui = updateItems[itemIndex]; CItemEx itemEx; CItemOut item; @@ -623,7 +676,7 @@ // Note: for (ui.NewProps && !ui.NewData) it copies Props from old archive, // But we will rewrite all important properties later. But we can keep some properties like Comment itemEx = inputItems[(unsigned)ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) return E_NOTIMPL; (CItem &)item = itemEx; } @@ -634,7 +687,7 @@ bool isDir = ui.IsDir; if (isDir) { - WriteDirHeader(archive, options, ui, item); + RINOK(WriteDirHeader(archive, options, ui, item)) } else { @@ -644,10 +697,10 @@ if (res == S_FALSE) { lps->ProgressOffset += ui.Size; - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) continue; } - RINOK(res); + RINOK(res) if (!fileInStream) return E_INVALIDARG; @@ -667,7 +720,7 @@ RINOK(compressor.Set_Pre_CompressionResult( inSeqMode, outSeqMode, ui.Size, - compressingResult)); + compressingResult)) SetFileHeader(*options, ui, compressingResult.DescriptorMode, item); @@ -675,6 +728,7 @@ SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item); + RINOK(archive.SetRestrictionFromCurrent()) archive.WriteLocalHeader(item); CMyComPtr outStream; @@ -684,8 +738,9 @@ EXTERNAL_CODECS_LOC_VARS fileInStream, outStream, inSeqMode, outSeqMode, - ui.Time, ui.Size, - progress, compressingResult)); + ui.Time, + ui.Size, ui.Size_WasSetFromStream, + progress, compressingResult)) if (item.HasDescriptor() != compressingResult.DescriptorMode) return E_FAIL; @@ -695,7 +750,7 @@ archive.WriteLocalHeader_Replace(item); } // if (reportArcProp) RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options->IsRealAesMode())) - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) unpackSizeTotal += item.Size; packSizeTotal += item.PackSize; } @@ -705,7 +760,7 @@ UInt64 complexity = 0; lps->SendRatio = false; - RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)); + RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)) lps->SendRatio = true; lps->ProgressOffset += complexity; @@ -717,9 +772,9 @@ lps->InSize = unpackSizeTotal; lps->OutSize = packSizeTotal; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) - archive.WriteCentralDir(items, comment); + RINOK(archive.WriteCentralDir(items, comment)) /* CTotalStats stat; @@ -733,6 +788,130 @@ return lps->SetCur(); } +#ifndef Z7_ST + + +static const size_t kBlockSize = 1 << 16; +// kMemPerThread must be >= kBlockSize +// +static const size_t kMemPerThread = (size_t)sizeof(size_t) << 23; +// static const size_t kMemPerThread = (size_t)sizeof(size_t) << 16; // for debug +// static const size_t kMemPerThread = (size_t)1 << 16; // for debug + +/* +in: + nt_Zip >= 1: the starting maximum number of ZIP threads for search +out: + nt_Zip: calculated number of ZIP threads + returns: calculated number of ZSTD threads +*/ +/* +static UInt32 CalcThreads_for_ZipZstd(CZstdEncProps *zstdProps, + UInt64 memLimit, UInt32 totalThreads, + UInt32 &nt_Zip) +{ + for (; nt_Zip > 1; nt_Zip--) + { + UInt64 mem1 = memLimit / nt_Zip; + if (mem1 <= kMemPerThread) + continue; + mem1 -= kMemPerThread; + UInt32 n_ZSTD = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + zstdProps, mem1, totalThreads / nt_Zip); + // we don't allow (nbWorkers == 1) here + if (n_ZSTD <= 1) + n_ZSTD = 0; + zstdProps->nbWorkers = n_ZSTD; + mem1 = ZstdEncProps_GetMemUsage(zstdProps); + if ((mem1 + kMemPerThread) * nt_Zip <= memLimit) + return n_ZSTD; + } + return ZstdEncProps_GetNumThreads_for_MemUsageLimit( + zstdProps, memLimit, totalThreads); +} + + +static UInt32 SetZstdThreads( + const CCompressionMethodMode &options, + COneMethodInfo *oneMethodMain, + UInt32 numThreads, + UInt32 numZipThreads_limit, + UInt64 numFilesToCompress, + UInt64 numBytesToCompress) +{ + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(encoderProps.SetFromMethodProps(*oneMethodMain)); + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + if (oneMethodMain->FindProp(NCoderPropID::kNumThreads) >= 0) + { + // threads for ZSTD are fixed + if (zstdProps.nbWorkers > 1) + numThreads /= zstdProps.nbWorkers; + if (numThreads > numZipThreads_limit) + numThreads = numZipThreads_limit; + if (options._memUsage_WasSet + && !options._numThreads_WasForced) + { + const UInt64 mem1 = ZstdEncProps_GetMemUsage(&zstdProps); + const UInt64 numZipThreads = options._memUsage_Compress / (mem1 + kMemPerThread); + if (numThreads > numZipThreads) + numThreads = (UInt32)numZipThreads; + } + return numThreads; + } + { + // threads for ZSTD are not fixed + + // calculate estimated required number of ZST threads per file size statistics + UInt32 t = MY_ZSTDMT_NBWORKERS_MAX; + { + UInt64 averageNumberOfBlocks = 0; + const UInt64 averageSize = numBytesToCompress / numFilesToCompress; + const UInt64 jobSize = zstdProps.jobSize; + if (jobSize != 0) + averageNumberOfBlocks = averageSize / jobSize + 0; + if (t > averageNumberOfBlocks) + t = (UInt32)averageNumberOfBlocks; + } + if (t > numThreads) + t = numThreads; + + // calculate the nuber of zip threads + UInt32 numZipThreads = numThreads; + if (t > 1) + numZipThreads = numThreads / t; + if (numZipThreads > numZipThreads_limit) + numZipThreads = numZipThreads_limit; + if (numZipThreads < 1) + numZipThreads = 1; + { + // recalculate the number of ZSTD threads via the number of ZIP threads + const UInt32 t2 = numThreads / numZipThreads; + if (t < t2) + t = t2; + } + + if (options._memUsage_WasSet + && !options._numThreads_WasForced) + { + t = CalcThreads_for_ZipZstd(&zstdProps, + options._memUsage_Compress, numThreads, numZipThreads); + numThreads = numZipThreads; + } + // we don't use (nbWorkers = 1) here + if (t <= 1) + t = 0; + oneMethodMain->AddProp_NumThreads(t); + return numThreads; + } +} +*/ + +#endif + + + static HRESULT Update2( DECL_EXTERNAL_CODECS_LOC_VARS @@ -755,8 +934,10 @@ bool unknownComplexity = false; UInt64 complexity = 0; + #ifndef Z7_ST UInt64 numFilesToCompress = 0; UInt64 numBytesToCompress = 0; + #endif unsigned i; @@ -769,8 +950,10 @@ unknownComplexity = true; else complexity += ui.Size; + #ifndef Z7_ST numBytesToCompress += ui.Size; numFilesToCompress++; + #endif /* if (ui.Commented) complexity += ui.CommentRange.Size; @@ -779,7 +962,7 @@ else { CItemEx inputItem = inputItems[(unsigned)ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK) + if (inArchive->Read_LocalItem_After_CdItem_Full(inputItem) != S_OK) return E_NOTIMPL; complexity += inputItem.GetLocalFullSize(); // complexity += inputItem.GetCentralExtraPlusCommentSize(); @@ -810,7 +993,7 @@ complexity = 0; - const Byte method = options.MethodSequence.Front(); + const Byte method = options.MethodSequence.FrontItem(); COneMethodInfo *oneMethodMain = NULL; if (!options2._methods.IsEmpty()) @@ -831,17 +1014,30 @@ } - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 numThreads = options._numThreads; +#ifdef _WIN32 + const UInt32 numThreadGroups = options._numThreadGroups; +#endif + + UInt32 numZipThreads_limit = numThreads; + if (numZipThreads_limit > numFilesToCompress) + numZipThreads_limit = (UInt32)numFilesToCompress; + if (numZipThreads_limit > 1) { + const unsigned numFiles_OPEN_MAX = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + // printf("\nzip:numFiles_OPEN_MAX =%d\n", (unsigned)numFiles_OPEN_MAX); + if (numZipThreads_limit > numFiles_OPEN_MAX) + numZipThreads_limit = (UInt32)numFiles_OPEN_MAX; + } + + { + // we reduce number of threads for 32-bit to reduce memory usege to 256 MB const UInt32 kNumMaxThreads = - #ifdef _WIN32 - 64; // _WIN32 supports only 64 threads in one group. So no need for more threads here - #else - 128; - #endif + // _WIN32 (64-bit) supports only 64 threads in one group. + 8 << (sizeof(size_t) / 2); // 32 threads for 32-bit : 128 threads for 64-bit if (numThreads > kNumMaxThreads) numThreads = kNumMaxThreads; } @@ -849,11 +1045,13 @@ if (numThreads > MAXIMUM_WAIT_OBJECTS) // is 64 in Windows numThreads = MAXIMUM_WAIT_OBJECTS; */ + + + /* + // zstd supports (numThreads == 0); if (numThreads < 1) numThreads = 1; - - const size_t kMemPerThread = (size_t)sizeof(size_t) << 23; - const size_t kBlockSize = 1 << 16; + */ bool mtMode = (numThreads > 1); @@ -864,21 +1062,46 @@ if (!mtMode) { + // if (oneMethodMain) { + /* + if (method == NFileHeader::NCompressionMethod::kZstdWz) + { + if (oneMethodMain->FindProp(NCoderPropID::kNumThreads) < 0) + { + // numZstdThreads was not forced in oneMethodMain + if (numThreads >= 1 + && options._memUsage_WasSet + && !options._numThreads_WasForced) + { + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(encoderProps.SetFromMethodProps(*oneMethodMain)) + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + numThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps, options._memUsage_Compress, numThreads); + // we allow (nbWorkers = 1) here. + } + oneMethodMain->AddProp_NumThreads(numThreads); + } + } // kZstdWz + */ + // } // oneMethodMain + FOR_VECTOR (mi, options2._methods) { COneMethodInfo &onem = options2._methods[mi]; if (onem.FindProp(NCoderPropID::kNumThreads) < 0) { - // fixme: we should check the number of threads for xz mehod also + // fixme: we should check the number of threads for xz method also // fixed for 9.31. bzip2 default is just one thread. onem.AddProp_NumThreads(numThreads); } } } - else + else // mtMode { - if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined) + if (method == NFileHeader::NCompressionMethod::kStore && !options.Password_Defined) numThreads = 1; if (oneMethodMain) @@ -925,6 +1148,15 @@ } numThreads /= (unsigned)numXzThreads; } + /* + else if (method == NFileHeader::NCompressionMethod::kZstdWz) + { + numThreads = SetZstdThreads(options, + oneMethodMain, numThreads, + numZipThreads_limit, + numFilesToCompress, numBytesToCompress); + } + */ else if ( method == NFileHeader::NCompressionMethod::kDeflate || method == NFileHeader::NCompressionMethod::kDeflate64 @@ -964,8 +1196,8 @@ } } // (oneMethodMain) - if (numThreads > numFilesToCompress) - numThreads = (UInt32)numFilesToCompress; + if (numThreads > numZipThreads_limit) + numThreads = numZipThreads_limit; if (numThreads <= 1) { mtMode = false; @@ -989,13 +1221,15 @@ ); - #ifndef _7ZIP_ST + #ifndef Z7_ST /* CTotalStats stat; stat.Size = 0; stat.PackSize = 0; */ + if (numThreads < 1) + numThreads = 1; CObjectVector items; @@ -1022,7 +1256,7 @@ CUIntVector threadIndices; // list threads in order of updateItems { - RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize))); + RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize))) for (i = 0; i < updateItems.Size(); i++) refs.Refs.Add(CMemBlocks2()); @@ -1035,25 +1269,27 @@ for (i = 0; i < numThreads; i++) { CThreadInfo &threadInfo = threads.Threads[i]; - threadInfo.SetOptions(options2); ; - #ifdef EXTERNAL_CODECS - threadInfo.__externalCodecs = __externalCodecs; + threadInfo.ThreadIndex = i; + threadInfo.SetOptions(options2); + #ifdef Z7_EXTERNAL_CODECS + threadInfo._externalCodecs = _externalCodecs; #endif - RINOK(threadInfo.CreateEvents()); + RINOK(threadInfo.CreateEvents()) threadInfo.OutStreamSpec = new COutMemStream(&memManager); - RINOK(threadInfo.OutStreamSpec->CreateEvents(SYNC_WFMO(&memManager.Synchro))); + RINOK(threadInfo.OutStreamSpec->CreateEvents(SYNC_WFMO(&memManager.Synchro))) threadInfo.OutStream = threadInfo.OutStreamSpec; - threadInfo.IsFree = true; threadInfo.ProgressSpec = new CMtCompressProgress(); threadInfo.Progress = threadInfo.ProgressSpec; threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, i); - threadInfo.InSeqMode = false; - threadInfo.OutSeqMode = false; - threadInfo.FileTime = 0; - threadInfo.ExpectedDataSize = (UInt64)(Int64)-1; - threadInfo.ThreadIndex = i; threadInfo.MtSem = &mtSem; - RINOK(threadInfo.CreateThread()); + const HRESULT hres = + threadInfo.CreateThread_with_group( +#ifdef _WIN32 + (numThreadGroups > 1 && numThreads > 1) ? + (int)(i % numThreadGroups) : -1 +#endif + ); + RINOK(hres) } } @@ -1084,7 +1320,7 @@ else { itemEx = inputItems[(unsigned)ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) return E_NOTIMPL; (CItem &)item = itemEx; if (item.IsDir() != ui.IsDir) @@ -1099,21 +1335,21 @@ { NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection); - HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); + const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res == S_FALSE) { complexity += ui.Size; complexity += kLocalHeaderSize; mtProgressMixerSpec->Mixer2->SetProgressOffset_NoLock(complexity); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) memRef2.Skip = true; continue; } - RINOK(res); + RINOK(res) if (!fileInStream) return E_INVALIDARG; UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) } UInt32 k; @@ -1151,6 +1387,7 @@ threadInfo.OutSeqMode = outSeqMode; threadInfo.FileTime = ui.Time; // FileTime is used for ZipCrypto only in seqMode threadInfo.ExpectedDataSize = ui.Size; + threadInfo.ExpectedDataSize_IsConfirmed = ui.Size_WasSetFromStream; threadInfo.CompressEvent.Set(); @@ -1175,7 +1412,7 @@ if (!ui.NewProps || !ui.NewData) { itemEx = inputItems[(unsigned)ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) return E_NOTIMPL; (CItem &)item = itemEx; } @@ -1183,11 +1420,11 @@ if (ui.NewData) { // bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); - bool isDir = ui.IsDir; + const bool isDir = ui.IsDir; if (isDir) { - WriteDirHeader(archive, &options, ui, item); + RINOK(WriteDirHeader(archive, &options, ui, item)) } else { @@ -1206,12 +1443,21 @@ SetItemInfoFromCompressingResult(memRef.CompressingResult, options.IsRealAesMode(), options.AesKeyMode, item); + RINOK(archive.ClearRestriction()) archive.WriteLocalHeader(item); // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); CMyComPtr outStream; archive.CreateStreamForCopying(outStream); memRef.WriteToStream(memManager.GetBlockSize(), outStream); - archive.MoveCurPos(item.PackSize); + // v23: we fixed the bug: we need to write descriptor also + if (item.HasDescriptor()) + { + /* that function doesn't rewrite local header, if item.HasDescriptor(). + it just writes descriptor */ + archive.WriteLocalHeader_Replace(item); + } + else + archive.MoveCurPos(item.PackSize); memRef.FreeOpt(&memManager); /* if (reportArcProp) @@ -1237,7 +1483,7 @@ RINOK(compressor.Set_Pre_CompressionResult( memRef.InSeqMode, outSeqMode, ui.Size, - compressingResult)); + compressingResult)) memRef.PreDescriptorMode = compressingResult.DescriptorMode; SetFileHeader(options, ui, compressingResult.DescriptorMode, item); @@ -1245,11 +1491,12 @@ SetItemInfoFromCompressingResult(compressingResult, options.IsRealAesMode(), options.AesKeyMode, item); // file Size can be 64-bit !!! + RINOK(archive.SetRestrictionFromCurrent()) archive.WriteLocalHeader(item); } { - CThreadInfo &thread = threads.Threads[threadIndices.Front()]; + CThreadInfo &thread = threads.Threads[threadIndices.FrontItem()]; if (!thread.OutStreamSpec->WasUnlockEventSent()) { CMyComPtr outStream; @@ -1259,18 +1506,18 @@ } } - WRes wres = mtSem.Semaphore.Lock(); + const WRes wres = mtSem.Semaphore.Lock(); if (wres != 0) return HRESULT_FROM_WIN32(wres); - int ti = mtSem.GetFreeItem(); + const int ti = mtSem.GetFreeItem(); if (ti < 0) return E_FAIL; CThreadInfo &threadInfo = threads.Threads[(unsigned)ti]; threadInfo.InStream.Release(); threadInfo.IsFree = true; - RINOK(threadInfo.Result); + RINOK(threadInfo.Result) unsigned t = 0; @@ -1293,7 +1540,7 @@ if (memRef.PreDescriptorMode != threadInfo.CompressingResult.DescriptorMode) return E_FAIL; - RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); + RINOK(threadInfo.OutStreamSpec->WriteToRealStream()) threadInfo.OutStreamSpec->ReleaseOutStream(); SetFileHeader(options, ui, threadInfo.CompressingResult.DescriptorMode, item); SetItemInfoFromCompressingResult(threadInfo.CompressingResult, @@ -1324,7 +1571,7 @@ } else { - RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)); + RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)) } items.Add(item); @@ -1333,9 +1580,9 @@ itemIndex++; } - RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL)); + RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL)) - archive.WriteCentralDir(items, comment); + RINOK(archive.WriteCentralDir(items, comment)) /* if (reportArcProp) @@ -1351,198 +1598,361 @@ #endif } +/* +// we need CSeekOutStream, if we need Seek(0, STREAM_SEEK_CUR) for seqential stream +Z7_CLASS_IMP_COM_1( + CSeekOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + CMyComPtr _seqStream; + UInt64 _size; +public: + void Init(ISequentialOutStream *seqStream) + { + _size = 0; + _seqStream = seqStream; + } +}; + +Z7_COM7F_IMF(CSeekOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _seqStream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +Z7_COM7F_IMF(CSeekOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (seekOrigin != STREAM_SEEK_CUR || offset != 0) + return E_NOTIMPL; + if (newPosition) + *newPosition = (UInt64)_size; + return S_OK; +} -static const size_t kCacheBlockSize = (1 << 20); -static const size_t kCacheSize = (kCacheBlockSize << 2); -static const size_t kCacheMask = (kCacheSize - 1); - -class CCacheOutStream: - public IOutStream, - public CMyUnknownImp +Z7_COM7F_IMF(CSeekOutStream::SetSize(UInt64 newSize)) { - CMyComPtr _stream; + UNUSED_VAR(newSize) + return E_NOTIMPL; +} +*/ + +static const size_t kCacheBlockSize = 1 << 20; +static const size_t kCacheSize = kCacheBlockSize << 2; +static const size_t kCacheMask = kCacheSize - 1; + +Z7_CLASS_IMP_NOQIB_2( + CCacheOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + HRESULT _hres; CMyComPtr _seqStream; + CMyComPtr _stream; + CMyComPtr _setRestriction; Byte *_cache; + size_t _cachedSize; + UInt64 _cachedPos; UInt64 _virtPos; UInt64 _virtSize; UInt64 _phyPos; - UInt64 _phySize; // <= _virtSize - UInt64 _cachedPos; // (_cachedPos + _cachedSize) <= _virtSize - size_t _cachedSize; + UInt64 _phySize; + UInt64 _restrict_begin; + UInt64 _restrict_end; + + HRESULT FlushFromCache(size_t size); + HRESULT FlushNonRestrictedBlocks(); + HRESULT FlushCache(); + HRESULT SetRestriction_ForWrite(size_t writeSize) const; - HRESULT MyWrite(size_t size); - HRESULT MyWriteBlock() + HRESULT SeekPhy(UInt64 pos) { - return MyWrite(kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1))); + if (pos == _phyPos) + return S_OK; + if (!_stream) + return E_NOTIMPL; + _hres = _stream->Seek((Int64)pos, STREAM_SEEK_SET, &_phyPos); + if (_hres == S_OK && _phyPos != pos) + _hres = E_FAIL; + return _hres; } - HRESULT FlushCache(); + public: CCacheOutStream(): _cache(NULL) {} ~CCacheOutStream(); - bool Allocate(); - HRESULT Init(ISequentialOutStream *seqStream, IOutStream *stream); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); + bool Allocate() + { + if (!_cache) + _cache = (Byte *)::MidAlloc(kCacheSize); + return _cache != NULL; + } + HRESULT Init(ISequentialOutStream *seqStream, IOutStream *stream, IStreamSetRestriction *setRestriction); + HRESULT FinalFlush(); }; -bool CCacheOutStream::Allocate() +CCacheOutStream::~CCacheOutStream() { - if (!_cache) - _cache = (Byte *)::MidAlloc(kCacheSize); - return (_cache != NULL); + ::MidFree(_cache); } -HRESULT CCacheOutStream::Init(ISequentialOutStream *seqStream, IOutStream *stream) + +HRESULT CCacheOutStream::Init(ISequentialOutStream *seqStream, IOutStream *stream, IStreamSetRestriction *setRestriction) { + _hres = S_OK; + _cachedSize = 0; + _cachedPos = 0; _virtPos = 0; - _phyPos = 0; _virtSize = 0; + // by default we have no restriction + _restrict_begin = 0; + _restrict_end = 0; _seqStream = seqStream; _stream = stream; + _setRestriction = setRestriction; if (_stream) { - RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &_virtPos)); - RINOK(_stream->Seek(0, STREAM_SEEK_END, &_virtSize)); - RINOK(_stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, &_virtPos)); + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &_virtPos)) + RINOK(_stream->Seek(0, STREAM_SEEK_END, &_virtSize)) + RINOK(_stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, &_virtPos)) } _phyPos = _virtPos; _phySize = _virtSize; - _cachedPos = 0; - _cachedSize = 0; return S_OK; } -HRESULT CCacheOutStream::MyWrite(size_t size) + +/* we call SetRestriction_ForWrite() just before Write() from cache. + (_phyPos == _cachedPos) + (writeSize != 0) +*/ +HRESULT CCacheOutStream::SetRestriction_ForWrite(size_t writeSize) const { - while (size != 0 && _cachedSize != 0) - { - if (_phyPos != _cachedPos) + if (!_setRestriction) + return S_OK; + PRF(printf("\n-- CCacheOutStream::SetRestriction_ForWrite _cachedPos = 0x%x, writeSize = %d\n", (unsigned)_cachedPos, (unsigned)writeSize)); + UInt64 begin = _restrict_begin; + UInt64 end = _restrict_end; + const UInt64 phyPos = _phyPos; + if (phyPos != _cachedPos) return E_FAIL; + if (phyPos == _phySize) + { + // The writing will be to the end of phy stream. + // So we will try to use non-restricted write, if possible. + if (begin == end) + begin = _virtPos; // _virtSize; // it's supposed that (_virtSize == _virtPos) + if (phyPos + writeSize <= begin) + { + // the write is not restricted + PRF(printf("\n+++ write is not restricted \n")); + begin = 0; + end = 0; + } + else { - if (!_stream) - return E_FAIL; - RINOK(_stream->Seek((Int64)_cachedPos, STREAM_SEEK_SET, &_phyPos)); + if (begin > phyPos) + begin = phyPos; + end = (UInt64)(Int64)-1; } - size_t pos = (size_t)_cachedPos & kCacheMask; - size_t curSize = MyMin(kCacheSize - pos, _cachedSize); - curSize = MyMin(curSize, size); - RINOK(WriteStream(_seqStream, _cache + pos, curSize)); - _phyPos += curSize; + } + else + { + // (phyPos != _phySize) + if (begin == end || begin > phyPos) + begin = phyPos; + end = (UInt64)(Int64)-1; + } + return _setRestriction->SetRestriction(begin, end); +} + + +/* it writes up to (size) bytes from cache. + (size > _cachedSize) is allowed +*/ +HRESULT CCacheOutStream::FlushFromCache(size_t size) +{ + PRF(printf("\n-- CCacheOutStream::FlushFromCache %u\n", (unsigned)size)); + if (_hres != S_OK) + return _hres; + if (size > _cachedSize) + size = _cachedSize; + // (size <= _cachedSize) + if (size == 0) + return S_OK; + RINOK(SeekPhy(_cachedPos)) + for (;;) + { + // (_phyPos == _cachedPos) + const size_t pos = (size_t)_cachedPos & kCacheMask; + const size_t cur = MyMin(kCacheSize - pos, size); + _hres = SetRestriction_ForWrite(cur); + RINOK(_hres) + PRF(printf("\n-- CCacheOutStream::WriteFromCache _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)cur)); + _hres = WriteStream(_seqStream, _cache + pos, cur); + RINOK(_hres) + _phyPos += cur; if (_phySize < _phyPos) _phySize = _phyPos; - _cachedPos += curSize; - _cachedSize -= curSize; - size -= curSize; + _cachedPos += cur; + _cachedSize -= cur; + size -= cur; + if (size == 0) + return S_OK; + } +} + + +HRESULT CCacheOutStream::FlushNonRestrictedBlocks() +{ + for (;;) + { + const size_t size = kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1)); + if (_cachedSize < size) + break; + UInt64 begin = _restrict_begin; + if (begin == _restrict_end) + begin = _virtPos; + // we don't flush the data to restricted area + if (_cachedPos + size > begin) + break; + RINOK(FlushFromCache(size)) } return S_OK; } + HRESULT CCacheOutStream::FlushCache() { - return MyWrite(_cachedSize); + return FlushFromCache(_cachedSize); } -CCacheOutStream::~CCacheOutStream() +HRESULT CCacheOutStream::FinalFlush() { - FlushCache(); - if (_stream) + _restrict_begin = 0; + _restrict_end = 0; + RINOK(FlushCache()) + if (_stream && _hres == S_OK) { if (_virtSize != _phySize) - _stream->SetSize(_virtSize); - if (_virtPos != _phyPos) - _stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, NULL); + { + // it's unexpected + RINOK(_stream->SetSize(_virtSize)) + _phySize = _virtSize; + } + _hres = SeekPhy(_virtPos); } - ::MidFree(_cache); + return _hres; } -STDMETHODIMP CCacheOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + +Z7_COM7F_IMF(CCacheOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { + PRF(printf("\n==== CCacheOutStream::Write virtPos=0x%x, %u\n", (unsigned)_virtPos, (unsigned)size)); + if (processedSize) *processedSize = 0; if (size == 0) return S_OK; + if (_hres != S_OK) + return _hres; - UInt64 zerosStart = _virtPos; if (_cachedSize != 0) + if (_virtPos < _cachedPos || + _virtPos > _cachedPos + _cachedSize) { - if (_virtPos < _cachedPos) - { - RINOK(FlushCache()); - } - else - { - UInt64 cachedEnd = _cachedPos + _cachedSize; - if (cachedEnd < _virtPos) - { - if (cachedEnd < _phySize) - { - RINOK(FlushCache()); - } - else - zerosStart = cachedEnd; - } - } - } - - if (_cachedSize == 0 && _phySize < _virtPos) - _cachedPos = zerosStart = _phySize; - - if (zerosStart != _virtPos) - { - // write zeros to [cachedEnd ... _virtPos) - - for (;;) - { - UInt64 cachedEnd = _cachedPos + _cachedSize; - size_t endPos = (size_t)cachedEnd & kCacheMask; - size_t curSize = kCacheSize - endPos; - if (curSize > _virtPos - cachedEnd) - curSize = (size_t)(_virtPos - cachedEnd); - if (curSize == 0) - break; - while (curSize > (kCacheSize - _cachedSize)) - { - RINOK(MyWriteBlock()); - } - memset(_cache + endPos, 0, curSize); - _cachedSize += curSize; - } + RINOK(FlushCache()) } if (_cachedSize == 0) _cachedPos = _virtPos; - size_t pos = (size_t)_virtPos & kCacheMask; - size = (UInt32)MyMin((size_t)size, kCacheSize - pos); - UInt64 cachedEnd = _cachedPos + _cachedSize; - if (_virtPos != cachedEnd) // _virtPos < cachedEnd - size = (UInt32)MyMin((size_t)size, (size_t)(cachedEnd - _virtPos)); + const size_t pos = (size_t)_virtPos & kCacheMask; + { + const size_t blockRem = kCacheBlockSize - ((size_t)_virtPos & (kCacheBlockSize - 1)); + if (size > blockRem) + size = (UInt32)blockRem; + } + // _cachedPos <= _virtPos <= _cachedPos + _cachedSize + const UInt64 cachedRem = _cachedPos + _cachedSize - _virtPos; + if (cachedRem) + { + // _virtPos < _cachedPos + _cachedSize + // we rewrite only existing data in cache. So _cachedSize will be not changed + if (size > cachedRem) + size = (UInt32)cachedRem; + } else { - // _virtPos == cachedEnd + // _virtPos == _cachedPos + _cachedSize + // so we need to add new data to the end of cache if (_cachedSize == kCacheSize) { - RINOK(MyWriteBlock()); + // cache is full. So we need to flush some part of cache. + // we flush only one block, but we are allowed to flush any size here + RINOK(FlushFromCache(kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1)))) + } + // _cachedSize != kCacheSize + // so we have some space for new data in cache + if (_cachedSize == 0) + { + /* this code is optional (for optimization): + we write data directly without cache, + if there is no restriction and we have full block. */ + if (_restrict_begin == _restrict_end + && size == kCacheBlockSize) + { + RINOK(SeekPhy(_virtPos)) + if (_setRestriction) + { + _hres = _setRestriction->SetRestriction(_restrict_begin, _restrict_end); + RINOK(_hres) + } + PRF(printf("\n-- CCacheOutStream::WriteDirectly _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)size)); + _hres = WriteStream(_seqStream, data, size); + RINOK(_hres) + if (processedSize) + *processedSize = size; + _virtPos += size; + if (_virtSize < _virtPos) + _virtSize = _virtPos; + _phyPos += size; + if (_phySize < _phyPos) + _phySize = _phyPos; + return S_OK; + } } - size_t startPos = (size_t)_cachedPos & kCacheMask; - if (startPos > pos) - size = (UInt32)MyMin((size_t)size, (size_t)(startPos - pos)); + else // (_cachedSize != 0) + { + const size_t startPos = (size_t)_cachedPos & kCacheMask; + // we don't allow new data to overwrite old start data in cache. + // (startPos == pos) here means that cache is empty. + // (startPos == pos) is not possible here. + if (startPos > pos) + size = (UInt32)MyMin((size_t)size, (size_t)(startPos - pos)); + } + // _virtPos == (_cachedPos + _cachedSize) still _cachedSize += size; } + memcpy(_cache + pos, data, size); if (processedSize) *processedSize = size; _virtPos += size; if (_virtSize < _virtPos) _virtSize = _virtPos; - return S_OK; + return FlushNonRestrictedBlocks(); } -STDMETHODIMP CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + +Z7_COM7F_IMF(CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { + PRF(printf("\n==== CCacheOutStream::Seek seekOrigin=%d Seek =%u\n", seekOrigin, (unsigned)offset)); switch (seekOrigin) { case STREAM_SEEK_SET: break; @@ -1558,27 +1968,90 @@ return S_OK; } -STDMETHODIMP CCacheOutStream::SetSize(UInt64 newSize) + +Z7_COM7F_IMF(CCacheOutStream::SetSize(UInt64 newSize)) { + if (_hres != S_OK) + return _hres; + + if (newSize <= _cachedPos || _cachedSize == 0) + { + _cachedSize = 0; + _cachedPos = newSize; + } + else + { + // _cachedSize != 0 + // newSize > _cachedPos + const UInt64 offset = newSize - _cachedPos; + if (offset <= _cachedSize) + { + // newSize is inside cached block or is touching cached block. + // so we reduce cache + _cachedSize = (size_t)offset; + if (_phySize <= newSize) + { + // _phySize will be restored later after cache flush + _virtSize = newSize; + return S_OK; + } + // (_phySize > newSize) + // so we must reduce phyStream size to (newSize) or to (_cachedPos) + // newPhySize = _cachedPos; // optional reduce to _cachedPos + } + else + { + // newSize > _cachedPos + _cachedSize + /* It's possible that we need to write zeros, + if new size is larger than old size. + We don't optimize for possible cases here. + So we just flush the cache. */ + _hres = FlushCache(); + } + } + _virtSize = newSize; - if (newSize < _phySize) + + if (_hres != S_OK) + return _hres; + + if (newSize != _phySize) { if (!_stream) return E_NOTIMPL; - RINOK(_stream->SetSize(newSize)); + // if (_phyPos > newSize) + RINOK(SeekPhy(newSize)) + if (_setRestriction) + { + UInt64 begin = _restrict_begin; + UInt64 end = _restrict_end; + if (_cachedSize != 0) + { + if (begin > _cachedPos) + begin = _cachedPos; + end = (UInt64)(Int64)-1; + } + _hres = _setRestriction->SetRestriction(begin, end); + RINOK(_hres) + } + _hres = _stream->SetSize(newSize); + RINOK(_hres) _phySize = newSize; } - if (newSize <= _cachedPos) - { - _cachedSize = 0; - _cachedPos = newSize; - } - if (newSize < _cachedPos + _cachedSize) - _cachedSize = (size_t)(newSize - _cachedPos); return S_OK; } +Z7_COM7F_IMF(CCacheOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + PRF(printf("\n============ CCacheOutStream::SetRestriction 0x%x, %u\n", (unsigned)begin, (unsigned)end)); + _restrict_begin = begin; + _restrict_end = end; + return FlushNonRestrictedBlocks(); +} + + + HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS const CObjectVector &inputItems, @@ -1589,21 +2062,36 @@ const CCompressionMethodMode &compressionMethodMode, IArchiveUpdateCallback *updateCallback) { + /* + // it was tested before if (inArchive) { if (!inArchive->CanUpdate()) return E_NOTIMPL; } + */ + CMyComPtr setRestriction; + seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + { + RINOK(setRestriction->SetRestriction(0, 0)) + } CMyComPtr outStream; + CCacheOutStream *cacheStream; bool outSeqMode; + { CMyComPtr outStreamReal; - seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); - if (!outStreamReal) + + if (!compressionMethodMode.Force_SeqOutMode) { - // return E_NOTIMPL; + seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); + /* + if (!outStreamReal) + return E_NOTIMPL; + */ } if (inArchive) @@ -1611,42 +2099,67 @@ if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx) { IInStream *baseStream = inArchive->GetBaseStream(); - RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(baseStream, seqOutStream, (UInt64)inArchive->ArcInfo.Base, NULL)); + RINOK(InStream_SeekToBegin(baseStream)) + RINOK(NCompress::CopyStream_ExactSize(baseStream, seqOutStream, (UInt64)inArchive->ArcInfo.Base, NULL)) } } - CCacheOutStream *cacheStream = new CCacheOutStream(); - outStream = cacheStream; - if (!cacheStream->Allocate()) - return E_OUTOFMEMORY; - RINOK(cacheStream->Init(seqOutStream, outStreamReal)); outSeqMode = (outStreamReal == NULL); + if (outSeqMode) + setRestriction.Release(); + /* CCacheOutStream works as non-restricted by default. + So we use (setRestriction == NULL) for outSeqMode */ + // bool use_cacheStream = true; + // if (use_cacheStream) + { + cacheStream = new CCacheOutStream(); + outStream = cacheStream; + if (!cacheStream->Allocate()) + return E_OUTOFMEMORY; + RINOK(cacheStream->Init(seqOutStream, outStreamReal, setRestriction)) + setRestriction.Release(); + if (!outSeqMode) + setRestriction = cacheStream; + } + /* + else if (!outStreamReal) + { + CSeekOutStream *seekOutStream = new CSeekOutStream(); + outStream = seekOutStream; + seekOutStream->Init(seqOutStream); + } + else + outStream = outStreamReal; + */ } COutArchive outArchive; - RINOK(outArchive.Create(outStream)); + outArchive.SetRestriction = setRestriction; + + RINOK(outArchive.Create(outStream)) if (inArchive) { if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) { IInStream *baseStream = inArchive->GetBaseStream(); - RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(baseStream, (UInt64)inArchive->ArcInfo.Base)) const UInt64 embStubSize = (UInt64)((Int64)inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base); - RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL)); + RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL)) outArchive.MoveCurPos(embStubSize); } } - return Update2( + RINOK (Update2( EXTERNAL_CODECS_LOC_VARS outArchive, inArchive, inputItems, updateItems, updateOptions, compressionMethodMode, outSeqMode, inArchive ? &inArchive->ArcInfo.Comment : NULL, - updateCallback); + updateCallback)) + + return cacheStream->FinalFlush(); } }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.h --- 7zip-22.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.h 2022-05-07 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/Zip/ZipUpdate.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZipUpdate.h -#ifndef __ZIP_UPDATE_H -#define __ZIP_UPDATE_H +#ifndef ZIP7_INC_ZIP_UPDATE_H +#define ZIP7_INC_ZIP_UPDATE_H #include "../../ICoder.h" #include "../IArchive.h" @@ -20,8 +20,8 @@ UInt64 Position; UInt64 Size; - // CUpdateRange() {}; - CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}; + // CUpdateRange() {} + CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {} }; */ @@ -34,6 +34,7 @@ bool Write_UnixTime; // bool Write_UnixTime_ATime; bool IsUtf8; + bool Size_WasSetFromStream; // bool IsAltStream; int IndexInArc; unsigned IndexInClient; @@ -57,6 +58,7 @@ Write_UnixTime = false; IsUtf8 = false; + Size_WasSetFromStream = false; // IsAltStream = false; Time = 0; Size = 0; @@ -74,6 +76,7 @@ Write_NtfsTime(false), Write_UnixTime(false), IsUtf8(false), + Size_WasSetFromStream(false), // IsAltStream(false), Time(0), Size(0) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Archive/ZstdHandler.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZstdHandler.cpp --- 7zip-22.01+dfsg/CPP/7zip/Archive/ZstdHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Archive/ZstdHandler.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -0,0 +1,1147 @@ +// ZstdHandler.cpp + +#include "StdAfx.h" + +// #define Z7_USE_ZSTD_ORIG_DECODER +// #define Z7_USE_ZSTD_COMPRESSION + +#include "../../Common/ComTry.h" + +#include "../Common/MethodProps.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/ZstdDecoder.h" +#ifdef Z7_USE_ZSTD_ORIG_DECODER +#include "../Compress/Zstd2Decoder.h" +#endif + +#ifdef Z7_USE_ZSTD_COMPRESSION +#include "../Compress/ZstdEncoder.h" +#include "../Compress/ZstdEncoderProps.h" +#include "Common/HandlerOut.h" +#endif + +#include "Common/DummyOutStream.h" + +#include "../../../C/CpuArch.h" + +using namespace NWindows; + +namespace NArchive { +namespace NZstd { + +#define DESCRIPTOR_Get_DictionaryId_Flag(d) ((d) & 3) +#define DESCRIPTOR_FLAG_CHECKSUM (1 << 2) +#define DESCRIPTOR_FLAG_RESERVED (1 << 3) +#define DESCRIPTOR_FLAG_UNUSED (1 << 4) +#define DESCRIPTOR_FLAG_SINGLE (1 << 5) +#define DESCRIPTOR_Get_ContentSize_Flag3(d) ((d) >> 5) +#define DESCRIPTOR_Is_ContentSize_Defined(d) (((d) & 0xe0) != 0) + +struct CFrameHeader +{ + Byte Descriptor; + Byte WindowDescriptor; + UInt32 DictionaryId; + UInt64 ContentSize; + + /* by zstd specification: + the decoder must check that (Is_Reserved() == false) + the decoder must ignore Unused_bit */ + bool Is_Reserved() const { return (Descriptor & DESCRIPTOR_FLAG_RESERVED) != 0; } + bool Is_Checksum() const { return (Descriptor & DESCRIPTOR_FLAG_CHECKSUM) != 0; } + bool Is_SingleSegment() const { return (Descriptor & DESCRIPTOR_FLAG_SINGLE) != 0; } + bool Is_ContentSize_Defined() const { return DESCRIPTOR_Is_ContentSize_Defined(Descriptor); } + unsigned Get_DictionaryId_Flag() const { return DESCRIPTOR_Get_DictionaryId_Flag(Descriptor); } + unsigned Get_ContentSize_Flag3() const { return DESCRIPTOR_Get_ContentSize_Flag3(Descriptor); } + + const Byte *Parse(const Byte *p, int size) + { + if ((unsigned)size < 2) + return NULL; + Descriptor = *p++; + size--; + { + Byte w = 0; + if (!Is_SingleSegment()) + { + w = *p++; + size--; + } + WindowDescriptor = w; + } + { + unsigned n = Get_DictionaryId_Flag(); + UInt32 d = 0; + if (n) + { + n = (unsigned)1 << (n - 1); + if ((size -= (int)n) < 0) + return NULL; + d = GetUi32(p) & ((UInt32)(Int32)-1 >> (32 - 8u * n)); + p += n; + } + DictionaryId = d; + } + { + unsigned n = Get_ContentSize_Flag3(); + UInt64 v = 0; + if (n) + { + n >>= 1; + if (n == 1) + v = 256; + n = (unsigned)1 << n; + if ((size -= (int)n) < 0) + return NULL; + v += GetUi64(p) & ((UInt64)(Int64)-1 >> (64 - 8u * n)); + p += n; + } + ContentSize = v; + } + return p; + } +}; + + + +class CHandler Z7_final: + public IInArchive, + public IArchiveOpenSeq, + public ISetProperties, +#ifdef Z7_USE_ZSTD_COMPRESSION + public IOutArchive, +#endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveOpenSeq) + Z7_COM_QI_ENTRY(ISetProperties) +#ifdef Z7_USE_ZSTD_COMPRESSION + Z7_COM_QI_ENTRY(IOutArchive) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveOpenSeq) + Z7_IFACE_COM7_IMP(ISetProperties) +#ifdef Z7_USE_ZSTD_COMPRESSION + Z7_IFACE_COM7_IMP(IOutArchive) +#endif + + bool _isArc; + bool _needSeekToStart; + // bool _dataAfterEnd; + // bool _needMoreInput; + bool _unsupportedBlock; + + bool _wasParsed; + bool _phySize_Decoded_Defined; + bool _unpackSize_Defined; // decoded + bool _decoded_Info_Defined; + + bool _parseMode; + bool _disableHash; + // bool _smallMode; + + UInt64 _phySize; + UInt64 _phySize_Decoded; + UInt64 _unpackSize; + + CZstdDecInfo _parsed_Info; + CZstdDecInfo _decoded_Info; + + CMyComPtr _stream; + CMyComPtr _seqStream; + +#ifdef Z7_USE_ZSTD_COMPRESSION + CSingleMethodProps _props; +#endif + +public: + CHandler(): + _parseMode(false), + _disableHash(false) + // _smallMode(false) + {} +}; + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidNumStreams, + kpidNumBlocks, + kpidMethod, + // kpidChecksum + kpidCRC +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +// static const unsigned kBlockType_Raw = 0; +static const unsigned kBlockType_RLE = 1; +// static const unsigned kBlockType_Compressed = 2; +static const unsigned kBlockType_Reserved = 3; +/* +static const char * const kNames[] = +{ + "RAW" + , "RLE" + , "Compressed" + , "Reserved" +}; +*/ + +static void Add_UInt64(AString &s, const char *name, UInt64 v) +{ + s.Add_OptSpaced(name); + s.Add_Colon(); + s.Add_UInt64(v); +} + + +static void PrintSize(AString &s, UInt64 w) +{ + char c = 0; + if ((w & ((1 << 30) - 1)) == 0) { c = 'G'; w >>= 30; } + else if ((w & ((1 << 20) - 1)) == 0) { c = 'M'; w >>= 20; } + else if ((w & ((1 << 10) - 1)) == 0) { c = 'K'; w >>= 10; } + s.Add_UInt64(w); + if (c) + { + s.Add_Char(c); + s += "iB"; + } +} + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + + CZstdDecInfo *p = NULL; + if (_wasParsed || !_decoded_Info_Defined) + p = &_parsed_Info; + else if (_decoded_Info_Defined) + p = &_decoded_Info; + + switch (propID) + { + case kpidPhySize: + if (_wasParsed) + prop = _phySize; + else if (_phySize_Decoded_Defined) + prop = _phySize_Decoded; + break; + + case kpidUnpackSize: + if (_unpackSize_Defined) + prop = _unpackSize; + break; + + case kpidNumStreams: + if (p) + if (_wasParsed || _decoded_Info_Defined) + prop = p->num_DataFrames; + break; + + case kpidNumBlocks: + if (p) + if (_wasParsed || _decoded_Info_Defined) + prop = p->num_Blocks; + break; + + // case kpidChecksum: + case kpidCRC: + if (p) + if (p->checksum_Defined && p->num_DataFrames == 1) + prop = p->checksum; // it's checksum from last frame + break; + + case kpidMethod: + { + AString s; + s.Add_OptSpaced(p == &_decoded_Info ? + "decoded:" : _wasParsed ? + "parsed:" : + "header-open-only:"); + + if (p->dictionaryId != 0) + { + if (p->are_DictionaryId_Different) + s.Add_OptSpaced("different-dictionary-IDs"); + s.Add_OptSpaced("dictionary-ID:"); + s.Add_UInt32(p->dictionaryId); + } + /* + if (ContentSize_Defined) + { + s.Add_OptSpaced("ContentSize="); + s.Add_UInt64(ContentSize_Total); + } + */ + // if (p->are_Checksums) + if (p->descriptor_OR & DESCRIPTOR_FLAG_CHECKSUM) + s.Add_OptSpaced("XXH64"); + if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_CHECKSUM) + s.Add_OptSpaced("NO-XXH64"); + + if (p->descriptor_OR & DESCRIPTOR_FLAG_UNUSED) + s.Add_OptSpaced("unused_bit"); + + if (p->descriptor_OR & DESCRIPTOR_FLAG_SINGLE) + s.Add_OptSpaced("single-segments"); + + if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE) + { + // Add_UInt64(s, "wnd-descriptors", p->num_WindowDescriptors); + s.Add_OptSpaced("wnd-desc-log-MAX:"); + // WindowDescriptor_MAX = 16 << 3; // for debug + const unsigned e = p->windowDescriptor_MAX >> 3; + s.Add_UInt32(e + 10); + const unsigned m = p->windowDescriptor_MAX & 7; + if (m != 0) + { + s.Add_Dot(); + s.Add_UInt32(m); + } + } + + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR) || + (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE)) + /* + if (p->are_ContentSize_Known || + p->are_WindowDescriptors) + */ + { + s.Add_OptSpaced("wnd-MAX:"); + PrintSize(s, p->windowSize_MAX); + if (p->windowSize_MAX != p->windowSize_Allocate_MAX) + { + s.Add_OptSpaced("wnd-use-MAX:"); + PrintSize(s, p->windowSize_Allocate_MAX); + } + } + + if (p->num_DataFrames != 1) + Add_UInt64(s, "data-frames", p->num_DataFrames); + if (p->num_SkipFrames != 0) + { + Add_UInt64(s, "skip-frames", p->num_SkipFrames); + Add_UInt64(s, "skip-frames-size-total", p->skipFrames_Size); + } + + if (p->are_ContentSize_Unknown) + s.Add_OptSpaced("unknown-content-size"); + + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR)) + { + Add_UInt64(s, "content-size-frame-max", p->contentSize_MAX); + Add_UInt64(s, "content-size-total", p->contentSize_Total); + } + + /* + for (unsigned i = 0; i < 4; i++) + { + const UInt64 n = p->num_Blocks_forType[i]; + if (n) + { + s.Add_OptSpaced(kNames[i]); + s += "-blocks:"; + s.Add_UInt64(n); + + s.Add_OptSpaced(kNames[i]); + s += "-block-bytes:"; + s.Add_UInt64(p->num_BlockBytes_forType[i]); + } + } + */ + prop = s; + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + // if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + if (_unsupportedBlock) v |= kpv_ErrorFlags_UnsupportedMethod; + /* + if (_parsed_Info.numBlocks_forType[kBlockType_Reserved]) + v |= kpv_ErrorFlags_UnsupportedMethod; + */ + prop = v; + break; + } + + default: break; + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPackSize: + if (_wasParsed) + prop = _phySize; + else if (_phySize_Decoded_Defined) + prop = _phySize_Decoded; + break; + + case kpidSize: + if (_wasParsed && !_parsed_Info.are_ContentSize_Unknown) + prop = _parsed_Info.contentSize_Total; + else if (_unpackSize_Defined) + prop = _unpackSize; + break; + + default: break; + } + prop.Detach(value); + return S_OK; +} + +static const unsigned kSignatureSize = 4; +static const Byte k_Signature[kSignatureSize] = { 0x28, 0xb5, 0x2f, 0xfd } ; + +static const UInt32 kDataFrameSignature32 = 0xfd2fb528; +static const UInt32 kSkipFrameSignature = 0x184d2a50; +static const UInt32 kSkipFrameSignature_Mask = 0xfffffff0; + +/* +API_FUNC_static_IsArc IsArc_Zstd(const Byte *p, size_t size) +{ + if (size < kSignatureSize) + return k_IsArc_Res_NEED_MORE; + if (memcmp(p, k_Signature, kSignatureSize) != 0) + { + const UInt32 v = GetUi32(p); + if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; + } + p += 4; + // return k_IsArc_Res_YES; +} +} +*/ + +// kBufSize must be >= (ZSTD_FRAMEHEADERSIZE_MAX = 18) +// we use big buffer for fast parsing of worst case small blocks. +static const unsigned kBufSize = + 1 << 9; + // 1 << 14; // fastest in real file + +struct CStreamBuffer +{ + unsigned pos; + unsigned lim; + IInStream *Stream; + UInt64 StreamOffset; + Byte buf[kBufSize]; + + CStreamBuffer(): + pos(0), + lim(0), + StreamOffset(0) + {} + unsigned Avail() const { return lim - pos; } + const Byte *GetPtr() const { return &buf[pos]; } + UInt64 GetCurOffset() const { return StreamOffset - Avail(); } + void SkipInBuf(UInt32 size) { pos += size; } + HRESULT Skip(UInt32 size); + HRESULT Read(unsigned num); +}; + +HRESULT CStreamBuffer::Skip(UInt32 size) +{ + unsigned rem = lim - pos; + if (rem != 0) + { + if (rem > size) + rem = size; + pos += rem; + size -= rem; + if (pos != lim) + return S_OK; + } + if (size == 0) + return S_OK; + return Stream->Seek(size, STREAM_SEEK_CUR, &StreamOffset); +} + +HRESULT CStreamBuffer::Read(unsigned num) +{ + if (lim - pos >= num) + return S_OK; + if (pos != 0) + { + lim -= pos; + memmove(buf, buf + pos, lim); + pos = 0; + } + size_t processed = kBufSize - ((unsigned)StreamOffset & (kBufSize - 1)); + const unsigned avail = kBufSize - lim; + num -= lim; + if (avail < processed || processed < num) + processed = avail; + const HRESULT res = ReadStream(Stream, buf + lim, &processed); + StreamOffset += processed; + lim += (unsigned)processed; + return res; +} + + +static const unsigned k_ZSTD_FRAMEHEADERSIZE_MAX = 4 + 14; + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + + CZstdDecInfo *p = &_parsed_Info; + // p->are_ContentSize_Unknown = False; + CStreamBuffer sb; + sb.Stream = stream; + + for (;;) + { + RINOK(sb.Read(k_ZSTD_FRAMEHEADERSIZE_MAX)) + if (sb.Avail() < kSignatureSize) + break; + + if (callback && (ZstdDecInfo_GET_NUM_FRAMES(p) & 0xFFF) == 2) + { + const UInt64 numBytes = sb.GetCurOffset(); + RINOK(callback->SetCompleted(NULL, &numBytes)) + } + + const UInt32 v = GetUi32(sb.GetPtr()); + if (v != kDataFrameSignature32) + { + if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature) + break; + _phySize = sb.GetCurOffset() + 8; + p->num_SkipFrames++; + sb.SkipInBuf(4); + if (sb.Avail() < 4) + break; + const UInt32 size = GetUi32(sb.GetPtr()); + p->skipFrames_Size += size; + sb.SkipInBuf(4); + _phySize = sb.GetCurOffset() + size; + RINOK(sb.Skip(size)) + continue; + } + + p->num_DataFrames++; + // _numStreams_Defined = true; + sb.SkipInBuf(4); + CFrameHeader fh; + { + const Byte *data = fh.Parse(sb.GetPtr(), (int)sb.Avail()); + if (!data) + { + // _needMoreInput = true; + // we set size for one byte more to show that stream was truncated + _phySize = sb.StreamOffset + 1; + break; + } + if (fh.Is_Reserved()) + { + // we don't want false detection + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1) + return S_FALSE; + // _phySize = sb.GetCurOffset(); + break; + } + sb.SkipInBuf((unsigned)(data - sb.GetPtr())); + } + + p->descriptor_OR = (Byte)(p->descriptor_OR | fh.Descriptor); + p->descriptor_NOT_OR = (Byte)(p->descriptor_NOT_OR | ~fh.Descriptor); + + // _numBlocks_Defined = true; + // if (fh.Get_DictionaryId_Flag()) + // p->dictionaryId_Cur = fh.DictionaryId; + if (fh.DictionaryId != 0) + { + if (p->dictionaryId == 0) + p->dictionaryId = fh.DictionaryId; + else if (p->dictionaryId != fh.DictionaryId) + p->are_DictionaryId_Different = True; + } + + UInt32 blockSizeAllowedMax = (UInt32)1 << 17; + { + UInt64 winSize = fh.ContentSize; + UInt64 winSize_forAllocate = fh.ContentSize; + if (!fh.Is_SingleSegment()) + { + if (p->windowDescriptor_MAX < fh.WindowDescriptor) + p->windowDescriptor_MAX = fh.WindowDescriptor; + const unsigned e = (fh.WindowDescriptor >> 3); + const unsigned m = (fh.WindowDescriptor & 7); + winSize = (UInt64)(8 + m) << (e + 10 - 3); + if (!fh.Is_ContentSize_Defined() + || fh.DictionaryId != 0 + || winSize_forAllocate > winSize) + winSize_forAllocate = winSize; + // p->are_WindowDescriptors = true; + } + else + { + // p->are_SingleSegments = True; + } + if (blockSizeAllowedMax > winSize) + blockSizeAllowedMax = (UInt32)winSize; + if (p->windowSize_MAX < winSize) + p->windowSize_MAX = winSize; + if (p->windowSize_Allocate_MAX < winSize_forAllocate) + p->windowSize_Allocate_MAX = winSize_forAllocate; + } + + if (fh.Is_ContentSize_Defined()) + { + // p->are_ContentSize_Known = True; + p->contentSize_Total += fh.ContentSize; + if (p->contentSize_MAX < fh.ContentSize) + p->contentSize_MAX = fh.ContentSize; + } + else + { + p->are_ContentSize_Unknown = True; + } + + p->checksum_Defined = false; + + // p->numBlocks_forType[3] += 99; // for debug + + if (!_parseMode) + { + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1) + break; + } + + _wasParsed = true; + + bool blocksWereParsed = false; + + for (;;) + { + if (callback && (p->num_Blocks & 0xFFF) == 2) + { + // Sleep(10); + const UInt64 numBytes = sb.GetCurOffset(); + RINOK(callback->SetCompleted(NULL, &numBytes)) + } + _phySize = sb.GetCurOffset() + 3; + RINOK(sb.Read(3)) + if (sb.Avail() < 3) + { + // _needMoreInput = true; + // return S_FALSE; + break; // change it + } + const unsigned pos = sb.pos; + sb.pos = pos + 3; + UInt32 b = 0; + b += (UInt32)sb.buf[pos]; + b += (UInt32)sb.buf[pos + 1] << (8 * 1); + b += (UInt32)sb.buf[pos + 2] << (8 * 2); + p->num_Blocks++; + const unsigned blockType = (b >> 1) & 3; + UInt32 size = b >> 3; + // p->num_Blocks_forType[blockType]++; + // p->num_BlockBytes_forType[blockType] += size; + if (size > blockSizeAllowedMax + || blockType == kBlockType_Reserved) + { + _unsupportedBlock = true; + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1 && p->num_Blocks == 1) + return S_FALSE; + break; + } + if (blockType == kBlockType_RLE) + size = 1; + _phySize = sb.GetCurOffset() + size; + RINOK(sb.Skip(size)) + if (b & 1) + { + // it's last block + blocksWereParsed = true; + break; + } + } + + if (!blocksWereParsed) + break; + + if (fh.Is_Checksum()) + { + _phySize = sb.GetCurOffset() + 4; + RINOK(sb.Read(4)) + if (sb.Avail() < 4) + break; + p->checksum_Defined = true; + // if (p->num_DataFrames == 1) + p->checksum = GetUi32(sb.GetPtr()); + sb.SkipInBuf(4); + } + } + + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 0) + return S_FALSE; + + _needSeekToStart = true; + // } // _parseMode + _isArc = true; + _stream = stream; + _seqStream = stream; + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _isArc = true; + _seqStream = stream; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _needSeekToStart = false; + // _dataAfterEnd = false; + // _needMoreInput = false; + _unsupportedBlock = false; + + _wasParsed = false; + _phySize_Decoded_Defined = false; + _unpackSize_Defined = false; + _decoded_Info_Defined = false; + + ZstdDecInfo_CLEAR(&_parsed_Info) + ZstdDecInfo_CLEAR(&_decoded_Info) + + _phySize = 0; + _phySize_Decoded = 0; + _unpackSize = 0; + + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + if (_wasParsed) + { + RINOK(extractCallback->SetTotal(_phySize)) + } + + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)) + } + else + _needSeekToStart = true; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + +#ifdef Z7_USE_ZSTD_ORIG_DECODER + CMyComPtr2_Create decoder; +#else + CMyComPtr2_Create decoder; +#endif + + CMyComPtr2_Create outStreamSpec; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + // realOutStream.Release(); + + decoder->FinishMode = true; +#ifndef Z7_USE_ZSTD_ORIG_DECODER + decoder->DisableHash = _disableHash; +#endif + + // _dataAfterEnd = false; + // _needMoreInput = false; + const HRESULT hres = decoder.Interface()->Code(_seqStream, outStreamSpec, NULL, NULL, lps); + /* + { + UInt64 t1 = decoder->GetInputProcessedSize(); + // for debug + const UInt32 kTempSize = 64; + Byte buf[kTempSize]; + UInt32 processedSize = 0; + RINOK(decoder->ReadUnusedFromInBuf(buf, kTempSize, &processedSize)) + processedSize -= processedSize; + UInt64 t2 = decoder->GetInputProcessedSize(); + t2 = t2; + t1 = t1; + } + */ + const UInt64 outSize = outStreamSpec->GetSize(); + // } + + // if (hres == E_ABORT) return hres; + opRes = NExtract::NOperationResult::kDataError; + + if (hres == E_OUTOFMEMORY) + { + return hres; + // opRes = NExtract::NOperationResult::kMemError; + } + else if (hres == S_OK || hres == S_FALSE) + { +#ifndef Z7_USE_ZSTD_ORIG_DECODER + _decoded_Info_Defined = true; + _decoded_Info = decoder->_state.info; + // NumDataFrames_Decoded = decoder->_state.info.num_DataFrames; + // NumSkipFrames_Decoded = decoder->_state.info.num_SkipFrames; + const UInt64 inSize = decoder->_inProcessed; +#else + const UInt64 inSize = decoder->GetInputProcessedSize(); +#endif + _phySize_Decoded = inSize; + _phySize_Decoded_Defined = true; + + _unpackSize_Defined = true; + _unpackSize = outSize; + + // RINOK( + lps.Interface()->SetRatioInfo(&inSize, &outSize); + +#ifdef Z7_USE_ZSTD_ORIG_DECODER + if (hres == S_OK) + opRes = NExtract::NOperationResult::kOK; +#else + if (decoder->ResInfo.decode_SRes == SZ_ERROR_CRC) + { + opRes = NExtract::NOperationResult::kCRCError; + } + else if (decoder->ResInfo.decode_SRes == SZ_ERROR_NO_ARCHIVE) + { + _isArc = false; + opRes = NExtract::NOperationResult::kIsNotArc; + } + else if (decoder->ResInfo.decode_SRes == SZ_ERROR_INPUT_EOF) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else + { + if (hres == S_OK && decoder->ResInfo.decode_SRes == SZ_OK) + opRes = NExtract::NOperationResult::kOK; + if (decoder->ResInfo.extraSize) + { + // if (inSize == 0) _isArc = false; + opRes = NExtract::NOperationResult::kDataAfterEnd; + } + /* + if (decoder->ResInfo.unexpededEnd) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + */ + } +#endif + } + else if (hres == E_NOTIMPL) + { + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else + return hres; + } + + return extractCallback->SetOperationResult(opRes); + + COM_TRY_END +} + + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + // return _props.SetProperties(names, values, numProps); + // _smallMode = false; + _disableHash = false; + _parseMode = false; + // _parseMode = true; // for debug +#ifdef Z7_USE_ZSTD_COMPRESSION + _props.Init(); +#endif + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + const PROPVARIANT &value = values[i]; + + if (name.IsEqualTo("parse")) + { + bool parseMode = true; + RINOK(PROPVARIANT_to_bool(value, parseMode)) + _parseMode = parseMode; + continue; + } + if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 4; + RINOK(ParsePropToUInt32(name, value, crcSize)) + if (crcSize == 0) + _disableHash = true; + else if (crcSize == 4) + _disableHash = false; + else + return E_INVALIDARG; + continue; + } +#ifdef Z7_USE_ZSTD_COMPRESSION + /* + if (name.IsEqualTo("small")) + { + bool smallMode = true; + RINOK(PROPVARIANT_to_bool(value, smallMode)) + _smallMode = smallMode; + continue; + } + */ + RINOK(_props.SetProperty(names[i], value)) +#endif + } + return S_OK; +} + + + + +#ifdef Z7_USE_ZSTD_COMPRESSION + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; + // *timeType = NFileTimeType::kUnix; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + if (numItems != 1) + return E_INVALIDARG; + { + CMyComPtr setRestriction; + outStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt != VT_EMPTY) + if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + + if (!_props.MethodName.IsEmpty() + && !_props.MethodName.IsEqualTo_Ascii_NoCase("zstd")) + return E_INVALIDARG; + + { + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)) + if (!fileInStream) + return S_FALSE; + { + CMyComPtr streamGetSize; + fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize); + if (streamGetSize) + { + UInt64 size2; + if (streamGetSize->GetSize(&size2) == S_OK) + size = size2; + } + } + RINOK(updateCallback->SetTotal(size)) + + CMethodProps props2 = _props; + +#ifndef Z7_ST + /* + CSingleMethodProps (_props) + derives from + CMethodProps (props2) + So we transfer additional variable (num Threads) to CMethodProps list of properties + */ + + UInt32 numThreads = _props._numThreads; + + if (numThreads > Z7_ZSTDMT_NBWORKERS_MAX) + numThreads = Z7_ZSTDMT_NBWORKERS_MAX; + + if (_props.FindProp(NCoderPropID::kNumThreads) < 0) + { + if (!_props._numThreads_WasForced + && numThreads >= 1 + && _props._memUsage_WasSet) + { + NCompress::NZstd::CEncoderProps zstdProps; + RINOK(zstdProps.SetFromMethodProps(_props)) + ZstdEncProps_NormalizeFull(&zstdProps.EncProps); + numThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps.EncProps, _props._memUsage_Compress, numThreads); + } + props2.AddProp_NumThreads(numThreads); + } + +#endif // Z7_ST + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + { + CMyComPtr2_Create encoder; + // size = 1 << 24; // for debug + RINOK(props2.SetCoderProps(encoder.ClsPtr(), size != (UInt64)(Int64)-1 ? &size : NULL)) + // encoderSpec->_props.SmallFileOpt = _smallMode; + // we must set kExpectedDataSize just before Code(). + encoder->SrcSizeHint64 = size; + /* + CMyComPtr optProps; + _compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void**)&optProps); + if (optProps) + { + PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)size; + // RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + RINOK(encoderSpec->SetCoderPropertiesOpt(&propID, &prop, 1)) + } + */ + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + } + } + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + CMyComPtr opCallback; + updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, 0, + NUpdateNotifyOp::kReplicate)) + } + + if (_stream) + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)) + + return NCompress::CopyStream(_stream, outStream, lps); + + COM_TRY_END +} +#endif + + + +#ifndef Z7_USE_ZSTD_COMPRESSION +#undef IMP_CreateArcOut +#define IMP_CreateArcOut +#undef CreateArcOut +#define CreateArcOut NULL +#endif + +#ifdef Z7_USE_ZSTD_COMPRESSION +REGISTER_ARC_IO( + "zstd2", "zst tzst", "* .tar", 0xe + 1, + k_Signature, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) +#else +REGISTER_ARC_IO( + "zstd", "zst tzst", "* .tar", 0xe, + k_Signature, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) +#endif + +}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Asm.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Asm.mak --- 7zip-22.01+dfsg/CPP/7zip/Asm.mak 2016-12-12 09:56:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Asm.mak 2024-02-29 08:00:00.000000000 +0000 @@ -1,8 +1,11 @@ !IFDEF ASM_OBJS -!IF "$(CPU)" == "ARM" -$(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm +!IF "$(PLATFORM)" == "arm64" +$(ASM_OBJS): ../../../../Asm/arm64/$(*B).S + $(COMPL_ASM_CLANG) +!ELSEIF "$(PLATFORM)" == "arm" +$(ASM_OBJS): ../../../../Asm/arm/$(*B).asm $(COMPL_ASM) -!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM64" +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" $(ASM_OBJS): ../../../../Asm/x86/$(*B).asm $(COMPL_ASM) !ENDIF diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/Alone.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/Alone.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/Alone.dsp 2021-09-12 11:31:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/Alone.dsp 2025-07-06 07:00:00.000000000 +0000 @@ -44,7 +44,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,8 +69,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c -# SUBTRACT CPP /WX +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -94,8 +93,8 @@ # PROP Intermediate_Dir "ReleaseU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -121,8 +120,8 @@ # PROP Intermediate_Dir "DebugU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -194,6 +193,7 @@ # Begin Source File SOURCE=..\..\UI\Console\Main.cpp +# ADD CPP /D "Z7_PROG_VARIANT_A" # End Source File # Begin Source File @@ -274,6 +274,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -450,6 +454,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Xxh64Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\XzCrc64Init.cpp # End Source File # Begin Source File @@ -722,6 +730,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OffsetStream.cpp # End Source File # Begin Source File @@ -1132,26 +1148,6 @@ SOURCE=..\..\Compress\PpmdZip.h # End Source File # End Group -# Begin Group "RangeCoder" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\Compress\RangeCoder.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\RangeCoderBit.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\RangeCoderBitTree.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\RangeCoderOpt.h -# End Source File -# End Group # Begin Group "Shrink" # PROP Default_Filter "" @@ -1182,6 +1178,20 @@ # Begin Source File SOURCE=..\..\Compress\LzxDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + # End Source File # Begin Source File @@ -1194,6 +1204,20 @@ # Begin Source File SOURCE=..\..\Compress\QuantumDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + # End Source File # Begin Source File @@ -1292,6 +1316,14 @@ SOURCE=..\..\Compress\XzEncoder.h # End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.h +# End Source File # End Group # Begin Group "Archive" @@ -1478,6 +1510,8 @@ # Begin Source File SOURCE=..\..\Archive\Zip\ZipHandler.cpp +# ADD CPP /D "Z7_ZIP_LZFSE_DISABLE" +# SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File @@ -1684,6 +1718,10 @@ SOURCE=..\..\Archive\XzHandler.cpp # End Source File +# Begin Source File + +SOURCE=..\..\Archive\ZstdHandler.cpp +# End Source File # End Group # Begin Group "UI Common" @@ -2311,6 +2349,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -3065,6 +3107,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\RotateDefs.h # End Source File # Begin Source File @@ -3163,6 +3209,34 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -3189,6 +3263,62 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.h +# End Source File # End Group # End Target # End Project diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/afxres.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/afxres.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/afxres.h 2003-09-23 18:42:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/afxres.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/makefile 2021-09-12 07:29:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile 2025-07-02 07:00:00.000000000 +0000 @@ -1,4 +1,11 @@ PROG = 7za.exe + +CFLAGS = $(CFLAGS) -DZ7_ZIP_LZFSE_DISABLE +# -DZ7_PROG_VARIANT_A +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_A +# ZIP_FLAGS=-DZ7_ZIP_LZFSE_DISABLE + +# USE_C_SORT=1 # USE_C_AES = 1 # USE_C_SHA = 1 # USE_C_LZFINDOPT = 1 @@ -20,10 +27,11 @@ $O\UTFConvert.obj \ $O\MyVector.obj \ $O\Wildcard.obj \ - $O\XzCrc64Init.obj \ - $O\XzCrc64Reg.obj \ $O\Sha1Reg.obj \ $O\Sha256Reg.obj \ + $O\Xxh64Reg.obj \ + $O\XzCrc64Init.obj \ + $O\XzCrc64Reg.obj \ WIN_OBJS = \ $O\DLL.obj \ @@ -56,6 +64,7 @@ $O\MemBlocks.obj \ $O\MethodId.obj \ $O\MethodProps.obj \ + $O\MultiOutStream.obj \ $O\OffsetStream.obj \ $O\OutBuffer.obj \ $O\OutMemStream.obj \ @@ -75,6 +84,7 @@ $O\LzmaHandler.obj \ $O\SplitHandler.obj \ $O\XzHandler.obj \ + $O\ZstdHandler.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ @@ -168,6 +178,10 @@ $O\ShrinkDecoder.obj \ $O\XzDecoder.obj \ $O\XzEncoder.obj \ + $O\ZstdDecoder.obj \ + +# $O\LzfseDecoder.obj \ +# $O\ZstdRegister.obj \ CRYPTO_OBJS = \ $O\7zAes.obj \ @@ -208,12 +222,14 @@ $O\Ppmd8.obj \ $O\Ppmd8Dec.obj \ $O\Ppmd8Enc.obj \ - $O\Sort.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ + $O\Xxh64.obj \ $O\Xz.obj \ $O\XzDec.obj \ $O\XzEnc.obj \ $O\XzIn.obj \ + $O\ZstdDec.obj \ !include "../../UI/Console/Console.mak" @@ -224,5 +240,6 @@ !include "../../LzmaDec.mak" !include "../../Sha1.mak" !include "../../Sha256.mak" +!include "../../Sort.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone/makefile.gcc 2022-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -1,18 +1,13 @@ PROG = 7za +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_A +ZIP_FLAGS=-DZ7_ZIP_LZFSE_DISABLE # IS_X64 = 1 # USE_ASM = 1 # ST_MODE = 1 -include ../../LzmaDec_gcc.mak - - -LOCAL_FLAGS_ST = -MT_OBJS = - - ifdef SystemDrive IS_MINGW = 1 else @@ -22,9 +17,16 @@ endif endif +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST ifdef IS_MINGW MT_OBJS = \ @@ -36,13 +38,14 @@ MT_OBJS = \ $O/LzFindMt.o \ - $O/StreamBinder.o \ - $O/Synchronization.o \ - $O/VirtThread.o \ + $O/LzFindOpt.o \ + $O/Threads.o \ $O/MemBlocks.o \ $O/OutMemStream.o \ $O/ProgressMt.o \ - $O/Threads.o \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ endif @@ -53,9 +56,10 @@ ifdef IS_MINGW LOCAL_FLAGS_SYS = \ - -D_7ZIP_LARGE_PAGES \ - -DWIN_LONG_PATH \ - -DSUPPORT_DEVICE_FILE \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES \ +# -DZ7_LONG_PATH \ SYS_OBJS = \ $O/FileSystem.o \ @@ -77,7 +81,6 @@ $(LOCAL_FLAGS_SYS) \ - CONSOLE_OBJS = \ $O/BenchCon.o \ $O/ConsoleClose.o \ @@ -122,22 +125,22 @@ $O/ListFileUtils.o \ $O/LzFindPrepare.o \ $O/MyString.o \ + $O/MyVector.o \ $O/NewHandler.o \ - $O/StdInStream.o \ - $O/StdOutStream.o \ $O/Sha1Prepare.o \ $O/Sha1Reg.o \ $O/Sha256Prepare.o \ $O/Sha256Reg.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ $O/StringConvert.o \ $O/StringToInt.o \ $O/UTFConvert.o \ - $O/MyVector.o \ $O/Wildcard.o \ + $O/Xxh64Reg.o \ $O/XzCrc64Init.o \ $O/XzCrc64Reg.o \ - WIN_OBJS = \ $O/ErrorMsg.o \ $O/FileDir.o \ @@ -152,7 +155,6 @@ $O/SystemInfo.o \ $O/TimeUtils.o \ - 7ZIP_COMMON_OBJS = \ $O/CreateCoder.o \ $O/CWrappers.o \ @@ -164,6 +166,7 @@ $O/LimitedStreams.o \ $O/MethodId.o \ $O/MethodProps.o \ + $O/MultiOutStream.o \ $O/OffsetStream.o \ $O/OutBuffer.o \ $O/ProgressUtils.o \ @@ -178,6 +181,7 @@ $O/LzmaHandler.o \ $O/SplitHandler.o \ $O/XzHandler.o \ + $O/ZstdHandler.o \ AR_COMMON_OBJS = \ $O/CoderMixer2.o \ @@ -268,6 +272,10 @@ $O/ShrinkDecoder.o \ $O/XzDecoder.o \ $O/XzEncoder.o \ + $O/ZstdDecoder.o \ + +# $O/LzfseDecoder.o \ +# $O/ZstdRegister.o CRYPTO_OBJS = \ $O/7zAes.o \ @@ -282,7 +290,11 @@ $O/ZipStrong.o \ C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ $O/Alloc.o \ $O/Bcj2.o \ $O/Bcj2Enc.o \ @@ -294,7 +306,6 @@ $O/Delta.o \ $O/HuffEnc.o \ $O/LzFind.o \ - $O/LzFindOpt.o \ $O/Lzma2Dec.o \ $O/Lzma2DecMt.o \ $O/Lzma2Enc.o \ @@ -308,24 +319,24 @@ $O/Ppmd8.o \ $O/Ppmd8Dec.o \ $O/Ppmd8Enc.o \ + $O/Sha1.o \ + $O/Sha1Opt.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ $O/Sort.o \ + $O/SwapBytes.o \ + $O/Xxh64.o \ $O/Xz.o \ $O/XzDec.o \ $O/XzEnc.o \ $O/XzIn.o \ $O/XzCrc64.o \ $O/XzCrc64Opt.o \ - $O/7zCrc.o \ - $O/7zCrcOpt.o \ - $O/Aes.o \ - $O/AesOpt.o \ - $O/Sha256.o \ - $O/Sha256Opt.o \ - $O/Sha1.o \ - $O/Sha1Opt.o \ + $O/ZstdDec.o \ + OBJS = \ - $(LZMA_DEC_OPT_OBJS) \ + $(LZMA_DEC_OPT_OBJS) \ $(C_OBJS) \ $(MT_OBJS) \ $(SYS_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/makefile 2022-01-09 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile 2024-01-29 10:00:00.000000000 +0000 @@ -1,7 +1,9 @@ PROG = 7zz.exe # USE_C_AES = 1 # USE_C_SHA = 1 -CFLAGS = $(CFLAGS) -DPROG_VARIANT_Z + +CFLAGS = $(CFLAGS) -DZ7_PROG_VARIANT_Z +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_Z !include "../Format7zF/Arc.mak" !include "../../UI/Console/Console.mak" @@ -24,5 +26,6 @@ 7ZIP_COMMON_OBJS = $(7ZIP_COMMON_OBJS) \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\MultiOutStream.obj \ !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone2/makefile.gcc 2022-07-14 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone2/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -1,11 +1,11 @@ PROG = 7zz +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_Z + # IS_X64 = 1 # USE_ASM = 1 # ST_MODE = 1 -CONSOLE_VARIANT_FLAGS=-DPROG_VARIANT_Z - include ../Format7zF/Arc_gcc.mak ifdef SystemDrive @@ -17,12 +17,15 @@ endif endif +LOCAL_FLAGS_SYS = + ifdef IS_MINGW LOCAL_FLAGS_SYS = \ - -D_7ZIP_LARGE_PAGES \ - -DWIN_LONG_PATH \ - -DSUPPORT_DEVICE_FILE \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LONG_PATH \ +# -DZ7_DEVICE_FILE \ SYS_OBJS = \ $O/FileSystem.o \ @@ -67,7 +70,6 @@ $O/UpdatePair.o \ $O/UpdateProduce.o \ - CONSOLE_OBJS = \ $O/BenchCon.o \ $O/ConsoleClose.o \ @@ -95,6 +97,7 @@ 7ZIP_COMMON_OBJS_2 = \ $O/FilePathAutoRename.o \ $O/FileStreams.o \ + $O/MultiOutStream.o \ OBJS = \ $(ARC_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/Alone.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/Alone.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/Alone.dsp 2021-12-19 20:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/Alone.dsp 2024-01-27 09:00:00.000000000 +0000 @@ -44,7 +44,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,7 +69,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -93,8 +93,8 @@ # PROP Intermediate_Dir "ReleaseU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -120,8 +120,8 @@ # PROP Intermediate_Dir "DebugU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -144,10 +144,6 @@ # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\UI\Console\ArError.h -# End Source File -# Begin Source File - SOURCE=..\..\UI\Console\BenchCon.cpp # End Source File # Begin Source File @@ -270,6 +266,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -318,6 +322,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File @@ -334,6 +346,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -342,6 +358,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyUnknown.h # End Source File # Begin Source File @@ -354,6 +374,10 @@ # End Source File # Begin Source File +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyWindows.cpp # End Source File # Begin Source File @@ -526,6 +550,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -550,7 +578,7 @@ # End Source File # Begin Source File -SOURCE=..\..\..\Windows\Synchronization.cpp +SOURCE=..\..\..\Windows\SecurityUtils.h # End Source File # Begin Source File @@ -678,6 +706,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OffsetStream.cpp # End Source File # Begin Source File @@ -798,10 +834,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Compress\ByteSwap.h -# End Source File -# Begin Source File - SOURCE=..\..\Compress\CopyCoder.cpp # End Source File # Begin Source File @@ -1114,6 +1146,10 @@ # End Source File # Begin Source File +SOURCE=..\..\UI\Common\DirItem.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\EnumDirItems.cpp # End Source File # Begin Source File @@ -1122,6 +1158,10 @@ # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\Extract.cpp # End Source File # Begin Source File @@ -1246,7 +1286,7 @@ # End Source File # Begin Source File -SOURCE=..\..\IMyUnknown.h +SOURCE=..\..\IDecl.h # End Source File # Begin Source File @@ -1473,6 +1513,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1587,7 +1635,26 @@ # Begin Source File SOURCE=..\..\..\..\C\Bra.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + # SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + # End Source File # Begin Source File @@ -1605,6 +1672,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1902,6 +1973,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\RotateDefs.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sha256.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1935,6 +2014,34 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile 2021-10-08 12:33:09.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,8 +1,14 @@ PROG = 7zr.exe # USE_C_AES = 1 +# USE_C_SHA = 1 +# USE_C_CRC64 = 1 +# USE_C_CRC = 1 +# NO_ASM_GNU=1 +# NO_ASM=1 -CFLAGS = $(CFLAGS) -DPROG_VARIANT_R +CFLAGS = $(CFLAGS) -DZ7_PROG_VARIANT_R +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_R COMMON_OBJS = \ $O\CommandLineParser.obj \ @@ -38,7 +44,6 @@ $O\PropVariant.obj \ $O\PropVariantConv.obj \ $O\Registry.obj \ - $O\Synchronization.obj \ $O\System.obj \ $O\SystemInfo.obj \ $O\TimeUtils.obj \ @@ -54,6 +59,7 @@ $O\LimitedStreams.obj \ $O\MethodId.obj \ $O\MethodProps.obj \ + $O\MultiOutStream.obj \ $O\OffsetStream.obj \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ @@ -142,7 +148,7 @@ $O\LzmaEnc.obj \ $O\MtCoder.obj \ $O\MtDec.obj \ - $O\Sort.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ $O\Xz.obj \ $O\XzDec.obj \ @@ -157,5 +163,6 @@ !include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha256.mak" +!include "../../Sort.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile.gcc 2022-07-15 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Alone7z/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -1,6 +1,6 @@ PROG = 7zr -CONSOLE_VARIANT_FLAGS=-DPROG_VARIANT_R +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_R # IS_X64 = 1 # USE_ASM = 1 @@ -24,7 +24,7 @@ ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST ifdef IS_MINGW MT_OBJS = \ @@ -37,10 +37,11 @@ MT_OBJS = \ $O/LzFindMt.o \ $O/LzFindOpt.o \ + $O/Threads.o \ $O/StreamBinder.o \ - $O/Synchronization.o \ $O/VirtThread.o \ - $O/Threads.o \ + + @@ -53,9 +54,10 @@ ifdef IS_MINGW LOCAL_FLAGS_SYS = \ - -D_7ZIP_LARGE_PAGES \ - -DWIN_LONG_PATH \ - -DSUPPORT_DEVICE_FILE \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES \ +# -DZ7_LONG_PATH \ SYS_OBJS = \ $O/FileSystem.o \ @@ -76,13 +78,10 @@ $(LOCAL_FLAGS_ST) \ $(LOCAL_FLAGS_SYS) \ -# -D_LZMA_PROB32 - CONSOLE_OBJS = \ $O/BenchCon.o \ $O/ConsoleClose.o \ - $O/DynLimBuf.o \ $O/ExtractCallbackConsole.o \ $O/HashCon.o \ $O/List.o \ @@ -119,6 +118,7 @@ $O/CommandLineParser.o \ $O/CRC.o \ $O/CrcReg.o \ + $O/DynLimBuf.o \ $O/IntToString.o \ $O/ListFileUtils.o \ $O/LzFindPrepare.o \ @@ -127,10 +127,10 @@ $O/NewHandler.o \ $O/Sha256Prepare.o \ $O/Sha256Reg.o \ - $O/StringConvert.o \ - $O/StringToInt.o \ $O/StdInStream.o \ $O/StdOutStream.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ $O/UTFConvert.o \ $O/Wildcard.o \ $O/XzCrc64Init.o \ @@ -160,6 +160,7 @@ $O/LimitedStreams.o \ $O/MethodId.o \ $O/MethodProps.o \ + $O/MultiOutStream.o \ $O/OffsetStream.o \ $O/OutBuffer.o \ $O/ProgressUtils.o \ @@ -227,7 +228,11 @@ $O/RandGen.o \ C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ $O/Alloc.o \ $O/Bcj2.o \ $O/Bcj2Enc.o \ @@ -246,21 +251,17 @@ $O/MtDec.o \ $O/Sha256.o \ $O/Sha256Opt.o \ - $O/Sort.o \ + $O/SwapBytes.o \ $O/Xz.o \ $O/XzDec.o \ $O/XzEnc.o \ $O/XzIn.o \ $O/XzCrc64.o \ $O/XzCrc64Opt.o \ - $O/7zCrc.o \ - $O/7zCrcOpt.o \ - $O/Aes.o \ - $O/AesOpt.o \ OBJS = \ - $(LZMA_DEC_OPT_OBJS) \ + $(LZMA_DEC_OPT_OBJS) \ $(C_OBJS) \ $(MT_OBJS) \ $(SYS_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/FM.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/FM.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/FM.dsp 2021-10-20 12:26:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/FM.dsp 2024-04-02 12:00:00.000000000 +0000 @@ -45,7 +45,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS_2" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -72,7 +72,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS_2" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -99,7 +99,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS_2" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -127,7 +127,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS_2" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -661,6 +661,18 @@ # End Source File # Begin Source File +SOURCE=..\..\UI\FileManager\BrowseDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog2.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog2Res.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\FileManager\ComboDialog.cpp # End Source File # Begin Source File @@ -705,6 +717,18 @@ # End Source File # Begin Source File +SOURCE=..\..\UI\FileManager\MemDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MemDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MemDialogRes.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\FileManager\MessagesDialog.cpp # End Source File # Begin Source File @@ -849,6 +873,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OutBuffer.cpp # End Source File # Begin Source File @@ -947,10 +979,19 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\7zTypes.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -960,6 +1001,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c !IF "$(CFG)" == "FM - Win32 Release" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/StdAfx.h 2021-01-26 19:26:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -1,16 +1,6 @@ -// stdafx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -// #define _WIN32_WINNT 0x0400 -#define _WIN32_WINNT 0x0500 -#define WINVER _WIN32_WINNT - -#include "../../../Common/Common.h" - -#include -#include -#include +// StdAfx.h +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Fm/makefile 2022-01-09 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Fm/makefile 2024-01-27 13:00:00.000000000 +0000 @@ -1,5 +1,7 @@ PROG = 7zFM.exe +# CFLAGS = $(CFLAGS) -DZ7_LARGE_PAGES + !include "../Format7zF/Arc.mak" !include "../../UI/FileManager/FM.mak" @@ -36,6 +38,7 @@ 7ZIP_COMMON_OBJS = $(7ZIP_COMMON_OBJS) \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\MultiOutStream.obj \ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7z/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7z/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7z/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7z/makefile 2021-07-15 12:40:09.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7z/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,8 +1,8 @@ PROG = 7za.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -DDEFLATE_EXTRACT_ONLY \ - -DBZIP2_EXTRACT_ONLY \ + -DZ7_DEFLATE_EXTRACT_ONLY \ + -DZ7_BZIP2_EXTRACT_ONLY \ COMMON_OBJS = \ $O\CRC.obj \ @@ -25,6 +25,7 @@ $O\PropVariant.obj \ $O\Synchronization.obj \ $O\System.obj \ + $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ @@ -111,6 +112,7 @@ $O\RandGen.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bcj2Enc.obj \ @@ -133,7 +135,7 @@ $O\Ppmd7.obj \ $O\Ppmd7Dec.obj \ $O\Ppmd7Enc.obj \ - $O\Sort.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Aes.mak" @@ -141,5 +143,6 @@ !include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha256.mak" +!include "../../Sort.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtract/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtract/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtract/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtract/makefile 2019-08-26 08:49:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtract/makefile 2023-03-19 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ PROG = 7zxa.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -DEXTRACT_ONLY \ + -DZ7_EXTRACT_ONLY \ COMMON_OBJS = \ $O\CRC.obj \ @@ -91,6 +91,7 @@ $O\MyAesReg.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -104,6 +105,7 @@ $O\MtDec.obj \ $O\Ppmd7.obj \ $O\Ppmd7Dec.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Aes.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/makefile 2018-02-25 09:37:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zExtractR/makefile 2023-03-19 18:00:00.000000000 +0000 @@ -1,8 +1,8 @@ PROG = 7zxr.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -DEXTRACT_ONLY \ - -D_NO_CRYPTO + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_CRYPTO COMMON_OBJS = \ $O\CRC.obj \ @@ -77,6 +77,7 @@ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -88,6 +89,7 @@ $O\Lzma2DecMt.obj \ $O\LzmaDec.obj \ $O\MtDec.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Crc.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc.mak --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc.mak 2022-06-15 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc.mak 2025-07-01 15:00:00.000000000 +0000 @@ -4,6 +4,7 @@ $O\DynLimBuf.obj \ $O\IntToString.obj \ $O\LzFindPrepare.obj \ + $O\Md5Reg.obj \ $O\MyMap.obj \ $O\MyString.obj \ $O\MyVector.obj \ @@ -11,10 +12,14 @@ $O\NewHandler.obj \ $O\Sha1Reg.obj \ $O\Sha256Reg.obj \ + $O\Sha3Reg.obj \ + $O\Sha512Reg.obj \ + $O\Sha512Prepare.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ $O\UTFConvert.obj \ $O\Wildcard.obj \ + $O\Xxh64Reg.obj \ $O\XzCrc64Init.obj \ $O\XzCrc64Reg.obj \ @@ -98,6 +103,7 @@ $O\XarHandler.obj \ $O\XzHandler.obj \ $O\ZHandler.obj \ + $O\ZstdHandler.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ @@ -111,7 +117,6 @@ $O\HandlerOut.obj \ $O\ParseProperties.obj \ - 7Z_OBJS = \ $O\7zCompressionMode.obj \ $O\7zDecode.obj \ @@ -234,7 +239,7 @@ $O\ZlibDecoder.obj \ $O\ZlibEncoder.obj \ $O\ZDecoder.obj \ - + $O\ZstdDecoder.obj \ CRYPTO_OBJS = \ $O\7zAes.obj \ @@ -252,7 +257,6 @@ $O\ZipCrypto.obj \ $O\ZipStrong.obj \ - C_OBJS = \ $O\7zBuf2.obj \ $O\7zStream.obj \ @@ -274,6 +278,7 @@ $O\Lzma2Enc.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ + $O\Md5.obj \ $O\MtCoder.obj \ $O\MtDec.obj \ $O\Ppmd7.obj \ @@ -283,12 +288,17 @@ $O\Ppmd8.obj \ $O\Ppmd8Dec.obj \ $O\Ppmd8Enc.obj \ - $O\Sort.obj \ + $O\Sha3.obj \ + $O\Sha512.obj \ + $O\Sha512Opt.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ + $O\Xxh64.obj \ $O\Xz.obj \ $O\XzDec.obj \ $O\XzEnc.obj \ $O\XzIn.obj \ + $O\ZstdDec.obj \ !include "../../Aes.mak" !include "../../Crc.mak" @@ -297,3 +307,4 @@ !include "../../LzmaDec.mak" !include "../../Sha1.mak" !include "../../Sha256.mak" +!include "../../Sort.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak 2022-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak 2024-11-26 11:00:00.000000000 +0000 @@ -14,7 +14,7 @@ ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST ifdef IS_MINGW MT_OBJS = \ @@ -27,13 +27,13 @@ MT_OBJS = \ $O/LzFindMt.o \ $O/LzFindOpt.o \ - $O/StreamBinder.o \ - $O/Synchronization.o \ - $O/VirtThread.o \ + $O/Threads.o \ $O/MemBlocks.o \ $O/OutMemStream.o \ $O/ProgressMt.o \ - $O/Threads.o \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ endif @@ -45,6 +45,7 @@ $O/DynLimBuf.o \ $O/IntToString.o \ $O/LzFindPrepare.o \ + $O/Md5Reg.o \ $O/MyMap.o \ $O/MyString.o \ $O/MyVector.o \ @@ -54,10 +55,14 @@ $O/Sha1Reg.o \ $O/Sha256Prepare.o \ $O/Sha256Reg.o \ + $O/Sha3Reg.o \ + $O/Sha512Prepare.o \ + $O/Sha512Reg.o \ $O/StringConvert.o \ $O/StringToInt.o \ $O/UTFConvert.o \ $O/Wildcard.o \ + $O/Xxh64Reg.o \ $O/XzCrc64Init.o \ $O/XzCrc64Reg.o \ @@ -135,6 +140,10 @@ $O/XarHandler.o \ $O/XzHandler.o \ $O/ZHandler.o \ + $O/ZstdHandler.o \ + +# $O/AvbHandler.o +# $O/LvmHandler.o AR_COMMON_OBJS = \ $O/CoderMixer2.o \ @@ -269,6 +278,7 @@ $O/ZlibDecoder.o \ $O/ZlibEncoder.o \ $O/ZDecoder.o \ + $O/ZstdDecoder.o \ ifdef DISABLE_RAR DISABLE_RAR_COMPRESS=1 @@ -309,7 +319,11 @@ C_OBJS = \ $O/7zBuf2.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ $O/Alloc.o \ $O/Bcj2.o \ $O/Bcj2Enc.o \ @@ -327,6 +341,7 @@ $O/Lzma2Enc.o \ $O/LzmaDec.o \ $O/LzmaEnc.o \ + $O/Md5.o \ $O/MtCoder.o \ $O/MtDec.o \ $O/Ppmd7.o \ @@ -336,21 +351,23 @@ $O/Ppmd8.o \ $O/Ppmd8Dec.o \ $O/Ppmd8Enc.o \ + $O/Sha1.o \ + $O/Sha1Opt.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/Sha3.o \ + $O/Sha512.o \ + $O/Sha512Opt.o \ $O/Sort.o \ + $O/SwapBytes.o \ + $O/Xxh64.o \ $O/Xz.o \ $O/XzDec.o \ $O/XzEnc.o \ $O/XzIn.o \ $O/XzCrc64.o \ $O/XzCrc64Opt.o \ - $O/7zCrc.o \ - $O/7zCrcOpt.o \ - $O/Aes.o \ - $O/AesOpt.o \ - $O/Sha256.o \ - $O/Sha256Opt.o \ - $O/Sha1.o \ - $O/Sha1Opt.o \ + $O/ZstdDec.o \ ARC_OBJS = \ $(LZMA_DEC_OPT_OBJS) \ @@ -358,6 +375,7 @@ $(MT_OBJS) \ $(COMMON_OBJS) \ $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ $(AR_OBJS) \ $(AR_COMMON_OBJS) \ $(7Z_OBJS) \ @@ -373,5 +391,5 @@ $(ZIP_OBJS) \ $(COMPRESS_OBJS) \ $(CRYPTO_OBJS) \ - $(7ZIP_COMMON_OBJS) \ +# we need empty line after last line above diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Format7z.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Format7z.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/Format7z.dsp 2022-07-08 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/Format7z.dsp 2024-11-26 08:00:00.000000000 +0000 @@ -43,7 +43,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "NO_REGISTRY" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "_7ZIP_ST_9" /FAcs /Yu"StdAfx.h" /FD /GF /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_ST_9" /FAcs /Yu"StdAfx.h" /FD /GF /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "NO_REGISTRY" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "_7ZIP_ST_9" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_ST_9" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -195,6 +195,10 @@ SOURCE=..\..\Archive\Icons\zip.ico # End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\zst.ico +# End Source File # End Group # Begin Source File @@ -231,10 +235,22 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Common.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -271,6 +287,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Md5Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyBuffer.h # End Source File # Begin Source File @@ -367,6 +387,18 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Sha3Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File @@ -399,6 +431,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Xxh64Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\XzCrc64Init.cpp # End Source File # Begin Source File @@ -1065,6 +1101,14 @@ SOURCE=..\..\Compress\ZDecoder.h # End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.h +# End Source File # End Group # Begin Group "Crypto" @@ -1634,6 +1678,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c !IF "$(CFG)" == "7z - Win32 Release" @@ -1993,6 +2045,26 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Md5.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Md5.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\MtCoder.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -2194,6 +2266,62 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Sha3.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha3.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512Opt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sort.c !IF "$(CFG)" == "7z - Win32 Release" @@ -2214,7 +2342,23 @@ # End Source File # Begin Source File -SOURCE=..\..\..\..\C\StdAfx.h +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h # End Source File # Begin Source File @@ -2225,6 +2369,46 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.h +# End Source File # End Group # Begin Group "Archive" @@ -2967,6 +3151,10 @@ SOURCE=..\..\Archive\ZHandler.cpp # End Source File +# Begin Source File + +SOURCE=..\..\Archive\ZstdHandler.cpp +# End Source File # End Group # Begin Group "7zip" @@ -2993,6 +3181,10 @@ # End Source File # Begin Source File +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + SOURCE=..\..\PropID.h # End Source File # End Group @@ -3037,6 +3229,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile 2013-11-23 17:57:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile 2024-01-27 16:00:00.000000000 +0000 @@ -1,10 +1,11 @@ PROG = 7z.dll +# USE_C_LZFINDOPT = 1 DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -DEXTERNAL_CODECS \ + -DZ7_EXTERNAL_CODECS \ !IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -D_7ZIP_LARGE_PAGES +# CFLAGS = $(CFLAGS) -DZ7_LARGE_PAGES !ENDIF !include "Arc.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile.gcc 2022-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -16,13 +16,15 @@ endif endif +LOCAL_FLAGS_SYS = ifdef IS_MINGW -LOCAL_FLAGS_WIN = \ - -D_7ZIP_LARGE_PAGES \ +LOCAL_FLAGS_SYS = \ $(LOCAL_FLAGS_ST) \ +# -DZ7_LARGE_PAGES \ + SYS_OBJS = \ $O/resource.o \ @@ -34,8 +36,8 @@ endif LOCAL_FLAGS = \ - -DEXTERNAL_CODECS \ - $(LOCAL_FLAGS_WIN) \ + -DZ7_EXTERNAL_CODECS \ + $(LOCAL_FLAGS_SYS) \ $(LOCAL_FLAGS_ST) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/resource.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/resource.rc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zF/resource.rc 2022-01-05 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zF/resource.rc 2024-01-31 07:00:00.000000000 +0000 @@ -29,10 +29,11 @@ 23 ICON "../../Archive/Icons/xz.ico" 24 ICON "../../Archive/Icons/squashfs.ico" 25 ICON "../../Archive/Icons/apfs.ico" +26 ICON "../../Archive/Icons/zst.ico" STRINGTABLE BEGIN - 100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 vhdx:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 apfs:25" + 100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 zst:26 tzst:26 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 vhdx:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 apfs:25" END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zR/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zR/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zR/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/Format7zR/makefile 2021-07-15 12:38:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/Format7zR/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ PROG = 7zra.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -D_NO_CRYPTO + -DZ7_NO_CRYPTO COMMON_OBJS = \ $O\CRC.obj \ @@ -23,6 +23,7 @@ $O\PropVariant.obj \ $O\Synchronization.obj \ $O\System.obj \ + $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ @@ -92,6 +93,7 @@ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bcj2Enc.obj \ @@ -109,6 +111,7 @@ $O\LzmaEnc.obj \ $O\MtCoder.obj \ $O\MtDec.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Crc.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp 2022-06-09 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp 2024-11-29 10:00:00.000000000 +0000 @@ -1,11 +1,9 @@ -// LzmaAlone.cpp + // LzmaAlone.cpp #include "StdAfx.h" // #include -#include "../../../../C/CpuArch.h" - #if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE) #include #include @@ -14,16 +12,17 @@ #define MY_SET_BINARY_MODE(file) #endif -#include "../../../Common/MyWindows.h" -#include "../../../Common/MyInitGuid.h" - +#include "../../../../C/CpuArch.h" #include "../../../../C/7zVersion.h" #include "../../../../C/Alloc.h" #include "../../../../C/Lzma86.h" +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + #include "../../../Windows/NtCheck.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/System.h" #endif @@ -41,6 +40,8 @@ #include "../../UI/Console/BenchCon.h" #include "../../UI/Console/ConsoleClose.h" +extern +bool g_LargePagesMode; bool g_LargePagesMode = false; using namespace NCommandLineParser; @@ -58,13 +59,13 @@ " b : Benchmark\n" "\n" " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" - " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n" + " -d{N} : set dictionary size : [12, 31] : default = 24 (16 MiB)\n" " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" " -mc{N} : set number of cycles for match finder\n" " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" - " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n" + " -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n" " -mt{N} : set number of CPU threads\n" " -eos : write end of stream marker\n" " -si : read data from stdin\n" @@ -219,20 +220,17 @@ Print(kHelpString); } -class CProgressPrint: - public ICompressProgressInfo, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CProgressPrint, + ICompressProgressInfo +) UInt64 _size1; UInt64 _size2; public: CProgressPrint(): _size1(0), _size2(0) {} void ClosePrint(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #define BACK_STR \ @@ -248,7 +246,7 @@ Print(kBackSpaces); } -STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { if (NConsoleClose::TestBreakSignal()) return E_ABORT; @@ -272,7 +270,7 @@ } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void IncorrectCommand() { throw "Incorrect command"; @@ -316,7 +314,7 @@ else { char temp[32]; - ConvertUInt32ToHex(res, temp); + ConvertUInt32ToHex((UInt32)res, temp); PrintErr("Error code = 0x"); PrintErr_LF(temp); } @@ -357,7 +355,7 @@ CParser parser; try { - if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings)) + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) { PrintError2(parser.ErrorMessage, parser.ErrorLine); return 1; @@ -374,8 +372,8 @@ return 0; } - bool stdInMode = parser[NKey::kStdIn].ThereIs; - bool stdOutMode = parser[NKey::kStdOut].ThereIs; + const bool stdInMode = parser[NKey::kStdIn].ThereIs; + const bool stdOutMode = parser[NKey::kStdOut].ThereIs; if (!stdOutMode) PrintTitle(); @@ -396,7 +394,16 @@ UInt32 dictLog; const UString &s = parser[NKey::kDict].PostStrings[0]; dictLog = GetNumber(s); - dict = 1 << dictLog; + if (dictLog >= 32) + throw "unsupported dictionary size"; + // we only want to use dictionary sizes that are powers of 2, + // because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0 +#if 0 + if (dictLog == 32) + dict = (UInt32)3840 << 20; + else +#endif + dict = (UInt32)1 << dictLog; dictDefined = true; AddProp(props2, "d", s); } @@ -414,7 +421,7 @@ UInt32 numThreads = (UInt32)(Int32)-1; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (parser[NKey::kMultiThread].ThereIs) { @@ -503,7 +510,7 @@ const UString &outputName = params[paramIndex++]; outStreamSpec = new COutFileStream; outStream = outStreamSpec; - if (!outStreamSpec->Create(us2fs(outputName), true)) + if (!outStreamSpec->Create_ALWAYS(us2fs(outputName))) { PrintError2("Cannot open output file", outputName); return 1; @@ -524,7 +531,7 @@ if (encodeMode && !dictDefined) { - dict = 1 << kDictSizeLog; + dict = (UInt32)1 << kDictSizeLog; if (fileSizeDefined) { unsigned i; @@ -676,7 +683,7 @@ NCoderPropID::kMatchFinderCycles, }; - const unsigned kNumPropsMax = ARRAY_SIZE(propIDs); + const unsigned kNumPropsMax = Z7_ARRAY_SIZE(propIDs); PROPVARIANT props[kNumPropsMax]; for (int p = 0; p < 6; p++) @@ -757,7 +764,7 @@ throw "SetDecoderProperties error"; UInt64 unpackSize = 0; - for (int i = 0; i < 8; i++) + for (unsigned i = 0; i < 8; i++) unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i); bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1); @@ -792,7 +799,7 @@ return 0; } -int MY_CDECL main(int numArgs, const char *args[]) +int Z7_CDECL main(int numArgs, const char *args[]) { NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp 2021-07-15 13:50:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp 2024-01-27 10:00:00.000000000 +0000 @@ -42,7 +42,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_NO_LONG_PATH" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -66,7 +66,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_NO_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -132,6 +132,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -148,14 +152,6 @@ # End Source File # Begin Source File -SOURCE=..\..\..\Windows\Synchronization.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\Synchronization.h -# End Source File -# Begin Source File - SOURCE=..\..\..\Windows\System.cpp # End Source File # Begin Source File @@ -188,6 +184,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -216,10 +216,26 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -228,6 +244,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyUnknown.h # End Source File # Begin Source File @@ -274,6 +294,14 @@ SOURCE=..\..\..\Common\Types.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File # End Group # Begin Group "7zip Common" @@ -346,14 +374,6 @@ SOURCE=..\..\UI\Common\Bench.h # End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\LoadCodecs.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\LoadCodecs.h -# End Source File # End Group # Begin Group "Console" @@ -398,21 +418,16 @@ # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Alloc.c -# SUBTRACT CPP /YX /Yc /Yu -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\C\Alloc.h +SOURCE=..\..\..\..\C\7zWindows.h # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Bra.c +SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Bra.h +SOURCE=..\..\..\..\C\Alloc.h # End Source File # Begin Source File @@ -421,8 +436,7 @@ # End Source File # Begin Source File -SOURCE=..\..\..\..\C\BraIA64.c -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\..\..\C\Compiler.h # End Source File # Begin Source File @@ -502,6 +516,22 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group # Begin Source File SOURCE=.\LzmaAlone.cpp diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/StdAfx.h 2013-01-25 07:40:27.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile 2021-07-15 13:44:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile 2024-01-27 10:00:00.000000000 +0000 @@ -1,6 +1,10 @@ PROG = lzma.exe MY_CONSOLE = 1 +CFLAGS = $(CFLAGS) -DZ7_NO_LONG_PATH +# CFLAGS = $(CFLAGS) -DZ7_ST + + CURRENT_OBJS = \ $O\LzmaAlone.obj \ @@ -20,6 +24,7 @@ $O\NewHandler.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ + $O\Wildcard.obj \ WIN_OBJS = \ $O\FileIO.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile.gcc 2022-07-15 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/LzmaCon/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -4,12 +4,6 @@ # USE_ASM = 1 # ST_MODE = 1 -include ../../LzmaDec_gcc.mak - -LOCAL_FLAGS_ST = -MT_OBJS = - - ifdef SystemDrive IS_MINGW = 1 else @@ -19,17 +13,24 @@ endif endif +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST else MT_OBJS = \ $O/LzFindMt.o \ $O/LzFindOpt.o \ - $O/Synchronization.o \ $O/Threads.o \ + $O/Synchronization.o \ @@ -45,6 +46,9 @@ $O/Registry.o \ $O/resource.o \ +LOCAL_FLAGS_SYS = \ + -DZ7_NO_LONG_PATH \ + else SYS_OBJS = \ @@ -58,6 +62,7 @@ LOCAL_FLAGS = \ $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ COMMON_OBJS = \ @@ -72,6 +77,7 @@ $O/StringConvert.o \ $O/StringToInt.o \ $O/UTFConvert.o \ + $O/Wildcard.o \ WIN_OBJS = \ $O/FileIO.o \ @@ -110,7 +116,7 @@ $O/Lzma86Enc.o \ OBJS = \ - $(LZMA_DEC_OPT_OBJS) \ + $(LZMA_DEC_OPT_OBJS) \ $(C_OBJS) \ $(MT_OBJS) \ $(SYS_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/SFXCon.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SFXCon.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/SFXCon.dsp 2019-08-28 17:17:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SFXCon.dsp 2024-02-09 08:00:00.000000000 +0000 @@ -42,7 +42,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -257,6 +257,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -265,6 +269,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -285,6 +293,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -309,6 +321,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\LzmaRegister.cpp # End Source File # Begin Source File @@ -317,6 +333,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\PpmdRegister.cpp # End Source File # End Group @@ -427,6 +447,14 @@ SOURCE=..\..\..\Windows\System.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File # End Group # Begin Group "Common" @@ -441,6 +469,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -457,6 +489,18 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -759,6 +803,19 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -810,11 +867,19 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Delta.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -825,7 +890,18 @@ # Begin Source File SOURCE=..\..\..\..\C\DllSecur.c + +!IF "$(CFG)" == "SFXCon - Win32 Release" + +# ADD CPP /O2 # SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + # End Source File # Begin Source File @@ -905,13 +981,33 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\7z.ico +SOURCE=..\..\Archive\IArchive.h # End Source File # Begin Source File -SOURCE=..\..\Archive\IArchive.h +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/SfxCon.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SfxCon.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/SfxCon.cpp 2021-12-25 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/SfxCon.cpp 2024-06-18 08:00:00.000000000 +0000 @@ -3,9 +3,9 @@ #include "StdAfx.h" #include "../../../../C/CpuArch.h" +#include "../../../../C/DllSecur.h" #include "../../../Common/MyWindows.h" - #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -28,7 +28,6 @@ #include "../../MyVersion.h" -#include "../../../../C/DllSecur.h" using namespace NWindows; using namespace NFile; @@ -36,8 +35,12 @@ using namespace NCommandLineParser; #ifdef _WIN32 -HINSTANCE g_hInstance = 0; +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; #endif +extern +int g_CodePage; int g_CodePage = -1; extern CStdOutStream *g_StdStream; @@ -184,14 +187,14 @@ g_StdOut << kHelpString; } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code) { g_StdOut << message << endl; throw code; } -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void PrintHelpAndExit() // yyy { PrintHelp(); @@ -370,12 +373,12 @@ } } - bool yesToAll = parser[NKey::kYes].ThereIs; + const bool yesToAll = parser[NKey::kYes].ThereIs; // NExtractMode::EEnum extractMode; // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); - bool passwordEnabled = parser[NKey::kPassword].ThereIs; + const bool passwordEnabled = parser[NKey::kPassword].ThereIs; UString password; if (passwordEnabled) @@ -403,7 +406,7 @@ CCodecs *codecs = new CCodecs; CMyComPtr< - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS ICompressCodecsInfo #else IUnknown @@ -419,9 +422,9 @@ { CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr extractCallback = ecs; - ecs->Init(g_StdStream, &g_StdErr, g_StdStream); + ecs->Init(g_StdStream, &g_StdErr, g_StdStream, false); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = passwordEnabled; ecs->Password = password; #endif @@ -430,7 +433,7 @@ COpenCallbackConsole openCallback; openCallback.Init(g_StdStream, g_StdStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; #endif @@ -452,22 +455,33 @@ codecs, CObjectVector(), CIntVector(), v1, v2, wildcardCensorHead, - eo, ecs, ecs, + eo, + ecs, ecs, ecs, // NULL, // hash errorMessage, stat); + + ecs->ClosePercents(); + if (!errorMessage.IsEmpty()) { - (*g_StdStream) << endl << "Error: " << errorMessage;; + (*g_StdStream) << endl << "Error: " << errorMessage; if (result == S_OK) result = E_FAIL; } - if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) + if ( 0 != ecs->NumCantOpenArcs + || 0 != ecs->NumArcsWithError + || 0 != ecs->NumFileErrors + || 0 != ecs->NumOpenArcErrors) { + if (ecs->NumCantOpenArcs != 0) + (*g_StdStream) << endl << "Can't open as archive" << endl; if (ecs->NumArcsWithError != 0) (*g_StdStream) << endl << "Archive Errors" << endl; if (ecs->NumFileErrors != 0) (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; + if (ecs->NumOpenArcErrors != 0) + (*g_StdStream) << endl << "Open Errors: " << ecs->NumOpenArcErrors << endl; return NExitCode::kFatalError; } if (result != S_OK) @@ -489,7 +503,7 @@ wildcardCensorHead, true, // enableHeaders false, // techMode - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO passwordEnabled, password, #endif numErrors, numWarnings); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile 2021-03-06 13:39:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile 2024-03-20 06:00:00.000000000 +0000 @@ -3,9 +3,11 @@ MY_FIXED = 1 CFLAGS = $(CFLAGS) \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ CURRENT_OBJS = \ $O\SfxCon.obj \ @@ -43,6 +45,7 @@ $O\PropVariantConv.obj \ $O\Synchronization.obj \ $O\System.obj \ + $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ @@ -109,6 +112,7 @@ $O\MyAes.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile.gcc 2022-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -22,7 +22,7 @@ ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST ifdef IS_MINGW MT_OBJS = \ @@ -47,6 +47,8 @@ ifdef IS_MINGW LOCAL_FLAGS_SYS = \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ SYS_OBJS = \ $O/DLL.o \ @@ -61,11 +63,11 @@ endif LOCAL_FLAGS = \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ $(LOCAL_FLAGS_ST) \ $(LOCAL_FLAGS_SYS) \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ CURRENT_OBJS = \ @@ -172,6 +174,7 @@ $O/MyAes.o \ C_OBJS = \ + $O/7zStream.o \ $O/Alloc.o \ $O/Bcj2.o \ $O/Bra.o \ @@ -179,7 +182,6 @@ $O/BraIA64.o \ $O/CpuArch.o \ $O/Delta.o \ - \ $O/Lzma2Dec.o \ $O/Lzma2DecMt.o \ $O/LzmaDec.o \ @@ -194,7 +196,7 @@ $O/AesOpt.o \ OBJS = \ - $(LZMA_DEC_OPT_OBJS) \ + $(LZMA_DEC_OPT_OBJS) \ $(C_OBJS) \ $(MT_OBJS) \ $(SYS_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/resource.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/resource.rc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXCon/resource.rc 2005-07-28 16:18:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXCon/resource.rc 2022-12-28 17:00:00.000000000 +0000 @@ -2,4 +2,8 @@ MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx") -101 ICON "7z.ico" \ No newline at end of file +101 ICON "7z.ico" + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp 2020-06-11 12:15:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp 2023-12-03 16:00:00.000000000 +0000 @@ -63,7 +63,7 @@ return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) { #ifndef _NO_PROGRESS ProgressDialog.Sync.SetProgress(size, 0); @@ -71,10 +71,10 @@ return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) { #ifndef _NO_PROGRESS - RINOK(ProgressDialog.Sync.ProcessStopAndPause()); + RINOK(ProgressDialog.Sync.ProcessStopAndPause()) if (completeValue != NULL) ProgressDialog.Sync.SetPos(*completeValue); #endif @@ -92,8 +92,8 @@ } } -STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, - ISequentialOutStream **outStream, Int32 askExtractMode) +Z7_COM7F_IMF(CExtractCallbackImp::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) { #ifndef _NO_PROGRESS if (ProgressDialog.Sync.GetStopped()) @@ -104,7 +104,7 @@ UString fullPath; { NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) if (prop.vt == VT_EMPTY) fullPath = _itemDefaultName; else @@ -119,7 +119,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract) { NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) _processedFileInfo.Attributes = _defaultAttributes; else @@ -129,18 +129,18 @@ _processedFileInfo.Attributes = prop.ulVal; } - RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)) _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal); bool isAnti = false; { NCOM::CPropVariant propTemp; - RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)); + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)) if (propTemp.vt == VT_BOOL) isAnti = VARIANT_BOOLToBool(propTemp.boolVal); } - RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) switch (prop.vt) { case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; @@ -190,7 +190,7 @@ { _outFileStreamSpec = new COutFileStream; CMyComPtr outStreamLoc(_outFileStreamSpec); - if (!_outFileStreamSpec->Create(fullProcessedPath, true)) + if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath)) { _message = kCantOpenFile; return E_FAIL; @@ -207,13 +207,13 @@ return S_OK; } -STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)) { _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult) +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)) { switch (resultEOperationResult) { @@ -237,7 +237,7 @@ if (_outFileStream != NULL) { _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); - RINOK(_outFileStreamSpec->Close()); + RINOK(_outFileStreamSpec->Close()) } _outFileStream.Release(); if (_extractMode) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h 2013-01-25 07:53:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h 2023-04-03 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractCallbackSfx.h -#ifndef __EXTRACT_CALLBACK_SFX_H -#define __EXTRACT_CALLBACK_SFX_H +#ifndef ZIP7_INC_EXTRACT_CALLBACK_SFX_H +#define ZIP7_INC_EXTRACT_CALLBACK_SFX_H #include "resource.h" @@ -19,19 +19,16 @@ #endif #include "../../UI/Common/ArchiveOpenCallback.h" -class CExtractCallbackImp: +class CExtractCallbackImp Z7_final: public IArchiveExtractCallback, public IOpenCallbackUI, public CMyUnknownImp { -public: - - MY_UNKNOWN_IMP - - INTERFACE_IArchiveExtractCallback(;) - INTERFACE_IOpenCallbackUI(;) + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_IMP(IOpenCallbackUI) -private: CMyComPtr _archiveHandler; FString _directoryPath; UString _filePath; @@ -70,7 +67,7 @@ #ifndef _NO_PROGRESS HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread) { - ProgressDialog.Create(title, thread, 0); + ProgressDialog.Create(title, thread, NULL); { ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING)); } @@ -78,7 +75,7 @@ ProgressDialog.Show(SW_SHOWNORMAL); return S_OK; } - virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); } + ~CExtractCallbackImp() { ProgressDialog.Destroy(); } #endif }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp 2020-06-11 12:15:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp 2023-03-20 18:00:00.000000000 +0000 @@ -64,18 +64,14 @@ if (!CreateComplexDir(dirPath)) { - ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, - #ifdef LANG - 0x02000603, - #endif - fs2us(dirPath)); + ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, fs2us(dirPath)); Result = E_FAIL; return; } ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0); - Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback); + Result = ArchiveLink.GetArchive()->Extract(NULL, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback); } void Process() @@ -116,7 +112,9 @@ { t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON; NWindows::CThread thread; - RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t)); + const WRes wres = thread.Create(CThreadExtracting::MyThreadFunction, &t); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); UString title; LangString(IDS_PROGRESS_EXTRACTING, title); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h 2011-03-01 05:54:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h 2023-01-10 19:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractEngine.h -#ifndef __EXTRACT_ENGINE_H -#define __EXTRACT_ENGINE_H +#ifndef ZIP7_INC_EXTRACT_ENGINE_H +#define ZIP7_INC_EXTRACT_ENGINE_H #include "../../UI/Common/LoadCodecs.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp 2018-02-25 09:26:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp 2024-03-10 09:00:00.000000000 +0000 @@ -44,7 +44,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -71,7 +71,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -97,8 +97,8 @@ # PROP Intermediate_Dir "ReleaseD" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -221,6 +221,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -229,6 +233,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -249,6 +257,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -289,6 +301,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -305,6 +321,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -457,6 +477,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -464,7 +492,7 @@ SOURCE=..\..\..\Windows\Window.h # End Source File # End Group -# Begin Group "7z Common" +# Begin Group "7zip Common" # PROP Default_Filter "" # Begin Source File @@ -667,6 +695,19 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -704,6 +745,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -775,6 +820,30 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group # Begin Source File SOURCE=.\ExtractCallbackSfx.cpp diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp 2021-03-06 15:56:47.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -2,8 +2,9 @@ #include "StdAfx.h" -#include "../../../Common/MyWindows.h" +#include "../../../../C/DllSecur.h" +#include "../../../Common/MyWindows.h" #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -23,19 +24,22 @@ #include "ExtractEngine.h" -#include "../../../../C/DllSecur.h" - #include "resource.h" using namespace NWindows; using namespace NFile; using namespace NDir; +extern +HINSTANCE g_hInstance; HINSTANCE g_hInstance; +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; static CFSTR const kTempDirPrefix = FTEXT("7zS"); -#define _SHELL_EXECUTE +#define MY_SHELL_EXECUTE static bool ReadDataString(CFSTR fileName, LPCSTR startID, LPCSTR endID, AString &stringResult) @@ -73,10 +77,10 @@ break; if (memcmp(buffer + pos, endID, signatureEndSize) == 0) return true; - char b = buffer[pos]; + const Byte b = buffer[pos]; if (b == 0) return false; - stringResult += b; + stringResult += (char)b; pos++; } else @@ -101,13 +105,13 @@ static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 }; static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 }; -struct CInstallIDInit +static struct CInstallIDInit { CInstallIDInit() { kStartID[0] = ';'; kEndID[0] = ';'; - }; + } } g_CInstallIDInit; @@ -118,11 +122,11 @@ static void ShowErrorMessageSpec(const UString &name) { UString message = NError::MyFormatMessage(::GetLastError()); - int pos = message.Find(L"%1"); + const int pos = message.Find(L"%1"); if (pos >= 0) { - message.Delete(pos, 2); - message.Insert(pos, name); + message.Delete((unsigned)pos, 2); + message.Insert((unsigned)pos, name); } ShowErrorMessage(NULL, message); } @@ -146,7 +150,7 @@ // InitCommonControls(); UString archiveName, switches; - #ifdef _SHELL_EXECUTE + #ifdef MY_SHELL_EXECUTE UString executeFile, executeParameters; #endif NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); @@ -183,23 +187,23 @@ ShowErrorMessage(L"Config failed"); return 1; } - UString friendlyName = GetTextConfigValue(pairs, "Title"); - UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt"); - UString progress = GetTextConfigValue(pairs, "Progress"); + const UString friendlyName = GetTextConfigValue(pairs, "Title"); + const UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt"); + const UString progress = GetTextConfigValue(pairs, "Progress"); if (progress.IsEqualTo_Ascii_NoCase("no")) showProgress = false; - int index = FindTextConfigItem(pairs, "Directory"); + const int index = FindTextConfigItem(pairs, "Directory"); if (index >= 0) dirPrefix = pairs[index].String; if (!installPrompt.IsEmpty() && !assumeYes) { - if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | + if (MessageBoxW(NULL, installPrompt, friendlyName, MB_YESNO | MB_ICONQUESTION) != IDYES) return 0; } appLaunched = GetTextConfigValue(pairs, "RunProgram"); - #ifdef _SHELL_EXECUTE + #ifdef MY_SHELL_EXECUTE executeFile = GetTextConfigValue(pairs, "ExecuteFile"); executeParameters = GetTextConfigValue(pairs, "ExecuteParameters"); #endif @@ -216,7 +220,7 @@ CCodecs *codecs = new CCodecs; CMyComPtr compressCodecsInfo = codecs; { - HRESULT result = codecs->Load(); + const HRESULT result = codecs->Load(); if (result != S_OK) { ShowErrorMessage(L"Cannot load codecs"); @@ -225,7 +229,7 @@ } const FString tempDirPath = tempDir.GetPath(); - // tempDirPath = L"M:\\1\\"; // to test low disk space + // tempDirPath = "M:\\1\\"; // to test low disk space { bool isCorrupt = false; UString errorMessage; @@ -245,7 +249,7 @@ { if (errorMessage.IsEmpty()) errorMessage = NError::MyFormatMessage(result); - ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); + ::MessageBoxW(NULL, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } } return 1; @@ -258,8 +262,8 @@ return 1; #endif - HANDLE hProcess = 0; -#ifdef _SHELL_EXECUTE + HANDLE hProcess = NULL; +#ifdef MY_SHELL_EXECUTE if (!executeFile.IsEmpty()) { CSysString filePath (GetSystemString(executeFile)); @@ -280,7 +284,7 @@ executeParameters += switches; } - CSysString parametersSys (GetSystemString(executeParameters)); + const CSysString parametersSys (GetSystemString(executeParameters)); if (parametersSys.IsEmpty()) execInfo.lpParameters = NULL; else @@ -288,7 +292,7 @@ execInfo.lpDirectory = NULL; execInfo.nShow = SW_SHOWNORMAL; - execInfo.hProcess = 0; + execInfo.hProcess = NULL; /* BOOL success = */ ::ShellExecuteEx(&execInfo); UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; if (result <= 32) @@ -304,7 +308,7 @@ { if (appLaunched.IsEmpty()) { - appLaunched = L"setup.exe"; + appLaunched = "setup.exe"; if (!NFind::DoesFileExist_FollowLink(us2fs(appLaunched))) { if (!assumeYes) @@ -319,7 +323,7 @@ appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2)); } - UString appNameForError = appLaunched; // actually we need to rtemove parameters also + const UString appNameForError = appLaunched; // actually we need to rtemove parameters also appLaunched.Replace(L"%%T", fs2us(tempDirPath)); @@ -330,20 +334,21 @@ } STARTUPINFO startupInfo; startupInfo.cb = sizeof(startupInfo); - startupInfo.lpReserved = 0; - startupInfo.lpDesktop = 0; - startupInfo.lpTitle = 0; + startupInfo.lpReserved = NULL; + startupInfo.lpDesktop = NULL; + startupInfo.lpTitle = NULL; startupInfo.dwFlags = 0; startupInfo.cbReserved2 = 0; - startupInfo.lpReserved2 = 0; + startupInfo.lpReserved2 = NULL; PROCESS_INFORMATION processInformation; - CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched)); + const CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched)); - BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, - NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, - &startupInfo, &processInformation); + const BOOL createResult = CreateProcess(NULL, + appLaunchedSys.Ptr_non_const(), + NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, + &startupInfo, &processInformation); if (createResult == 0) { if (!assumeYes) @@ -357,7 +362,7 @@ ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } - if (hProcess != 0) + if (hProcess) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/StdAfx.h 2013-11-27 09:50:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -1,13 +1,6 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/Common.h" - -#include - -// #define printf(x) NO_PRINTF_(x) -// #define sprintf(x) NO_SPRINTF_(x) - +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXSetup/makefile 2018-04-23 09:04:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXSetup/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -2,11 +2,13 @@ MY_FIXED = 1 CFLAGS = $(CFLAGS) \ - -DNO_REGISTRY \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ - -D_NO_CRYPTO \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_CRYPTO \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ CURRENT_OBJS = \ $O\SfxSetup.obj \ @@ -36,6 +38,7 @@ $O\ResourceString.obj \ $O\Synchronization.obj \ $O\System.obj \ + $O\TimeUtils.obj \ $O\Window.obj \ WIN_CTRL_OBJS = \ @@ -97,6 +100,7 @@ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/SFXWin.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SFXWin.dsp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/SFXWin.dsp 2021-08-30 09:40:27.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SFXWin.dsp 2024-03-10 09:00:00.000000000 +0000 @@ -44,7 +44,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -71,7 +71,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -97,8 +97,8 @@ # PROP Intermediate_Dir "SFXWin___Win32_ReleaseD" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -221,6 +221,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -229,6 +233,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -249,6 +257,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -277,6 +289,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\PpmdRegister.cpp # End Source File # End Group @@ -657,6 +673,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -677,6 +701,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -851,6 +879,15 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -902,6 +939,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -993,13 +1034,33 @@ SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\7z.ico +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h # End Source File +# End Group # Begin Source File -SOURCE=.\7z1.ico +SOURCE=.\7z.ico # End Source File # Begin Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/SfxWin.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SfxWin.cpp --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/SfxWin.cpp 2021-12-22 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/SfxWin.cpp 2024-03-14 11:00:00.000000000 +0000 @@ -4,7 +4,13 @@ #include "../../../Common/MyWindows.h" +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else #include +#endif + +#include "../../../../C/DllSecur.h" #include "../../../Common/MyInitGuid.h" @@ -28,33 +34,43 @@ #include "../../UI/GUI/ExtractGUI.h" #include "../../UI/GUI/ExtractRes.h" -#include "../../../../C/DllSecur.h" - using namespace NWindows; using namespace NFile; using namespace NDir; +extern +HINSTANCE g_hInstance; HINSTANCE g_hInstance; +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; #ifndef UNDER_CE -DWORD g_ComCtl32Version; +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000 +#define Z7_USE_DYN_ComCtl32Version +#endif + +#ifdef Z7_USE_DYN_ComCtl32Version +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION static DWORD GetDllVersion(LPCTSTR dllName) { DWORD dwVersion = 0; - HINSTANCE hinstDll = LoadLibrary(dllName); + const HINSTANCE hinstDll = LoadLibrary(dllName); if (hinstDll) { - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion"); - if (pDllGetVersion) + const + DLLGETVERSIONPROC func_DllGetVersion = Z7_GET_PROC_ADDRESS( + DLLGETVERSIONPROC, hinstDll, "DllGetVersion"); + if (func_DllGetVersion) { DLLVERSIONINFO dvi; ZeroMemory(&dvi, sizeof(dvi)); dvi.cbSize = sizeof(dvi); - HRESULT hr = (*pDllGetVersion)(&dvi); + const HRESULT hr = func_DllGetVersion(&dvi); if (SUCCEEDED(hr)) - dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); } FreeLibrary(hinstDll); } @@ -62,7 +78,10 @@ } #endif +#endif +extern +bool g_LVN_ITEMACTIVATE_Support; bool g_LVN_ITEMACTIVATE_Support = true; static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!"; @@ -75,14 +94,18 @@ static int APIENTRY WinMain2() { // OleInitialize is required for ProgressBar in TaskBar. - #ifndef UNDER_CE +#ifndef UNDER_CE OleInitialize(NULL); - #endif +#endif - #ifndef UNDER_CE - g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); - g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); - #endif +#ifndef UNDER_CE +#ifdef Z7_USE_DYN_ComCtl32Version + { + const DWORD g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); + } +#endif +#endif UString password; bool assumeYes = false; @@ -101,7 +124,7 @@ const UString &s = commandStrings[i]; if (s.Len() > 1 && s[0] == '-') { - wchar_t c = MyCharLower_Ascii(s[1]); + const wchar_t c = MyCharLower_Ascii(s[1]); if (c == 'y') { assumeYes = true; @@ -124,6 +147,8 @@ } } + g_DisableUserQuestions = assumeYes; + FString path; NDLL::MyGetModuleFileName(path); @@ -152,7 +177,7 @@ CMyComPtr extractCallback = ecs; ecs->Init(); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = !password.IsEmpty(); ecs->Password = password; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/StdAfx.h 2013-10-29 09:02:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -1,14 +1,6 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/Common.h" - -#include -#include - -// #define printf(x) NO_PRINTF_(x) -// #define sprintf(x) NO_SPRINTF_(x) - +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/makefile --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/makefile 2021-08-30 07:28:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/makefile 2024-03-14 11:00:00.000000000 +0000 @@ -2,10 +2,12 @@ MY_FIXED = 1 CFLAGS = $(CFLAGS) \ - -DNO_REGISTRY \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ !IFDEF UNDER_CE LIBS = $(LIBS) ceshell.lib Commctrl.lib @@ -46,6 +48,7 @@ $O\Shell.obj \ $O\Synchronization.obj \ $O\System.obj \ + $O\TimeUtils.obj \ $O\Window.obj \ WIN_CTRL_OBJS = \ @@ -131,6 +134,7 @@ $O\MyAes.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/resource.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/resource.rc --- 7zip-22.01+dfsg/CPP/7zip/Bundles/SFXWin/resource.rc 2011-09-15 07:04:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Bundles/SFXWin/resource.rc 2022-12-28 17:00:00.000000000 +0000 @@ -48,3 +48,8 @@ BEGIN IDS_PROP_MTIME "Modified" END + + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/GUI/7zG.exe.manifest" +#endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/CWrappers.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/CWrappers.cpp 2021-02-09 19:12:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -18,6 +18,7 @@ case E_ABORT: return SZ_ERROR_PROGRESS; case S_FALSE: return SZ_ERROR_DATA; case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; + default: break; } return defaultRes; } @@ -32,6 +33,8 @@ case SZ_ERROR_DATA: case SZ_ERROR_CRC: case SZ_ERROR_INPUT_EOF: + case SZ_ERROR_ARCHIVE: + case SZ_ERROR_NO_ARCHIVE: return S_FALSE; case SZ_ERROR_MEM: return E_OUTOFMEMORY; @@ -45,6 +48,7 @@ // case SZ_ERROR_ARCHIVE: // case SZ_ERROR_NO_ARCHIVE: // return E_FAIL; + default: break; } if (res < 0) return res; @@ -57,9 +61,9 @@ #define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) -static SRes CompressProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) throw() +static SRes CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) throw() { - CCompressProgressWrap *p = CONTAINER_FROM_VTBL(pp, CCompressProgressWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CCompressProgressWrap) p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize)); return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); } @@ -73,9 +77,9 @@ static const UInt32 kStreamStepSize = (UInt32)1 << 31; -static SRes MyRead(const ISeqInStream *pp, void *data, size_t *size) throw() +static SRes MyRead(ISeqInStreamPtr pp, void *data, size_t *size) throw() { - CSeqInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqInStreamWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = (p->Stream->Read(data, curSize, &curSize)); *size = curSize; @@ -85,9 +89,9 @@ return HRESULT_To_SRes(p->Res, SZ_ERROR_READ); } -static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size) throw() +static size_t MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size) throw() { - CSeqOutStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqOutStreamWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqOutStreamWrap) if (p->Stream) { p->Res = WriteStream(p->Stream, data, size); @@ -118,20 +122,23 @@ } -static SRes InStreamWrap_Read(const ISeekInStream *pp, void *data, size_t *size) throw() +static SRes InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size) throw() { - CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = p->Stream->Read(data, curSize, &curSize); *size = curSize; return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; } -static SRes InStreamWrap_Seek(const ISeekInStream *pp, Int64 *offset, ESzSeek origin) throw() +static SRes InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin) throw() { - CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 moveMethod; - switch (origin) + /* we need (int)origin to eliminate the clang warning: + default label in switch which covers all enumeration values + [-Wcovered-switch-default */ + switch ((int)origin) { case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; @@ -188,15 +195,18 @@ return 0; } -static Byte Wrap_ReadByte(const IByteIn *pp) throw() +// #pragma GCC diagnostic ignored "-Winvalid-offsetof" + +static Byte Wrap_ReadByte(IByteInPtr pp) throw() { - CByteInBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt); + CByteInBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInBufWrap) if (p->Cur != p->Lim) return *p->Cur++; return p->ReadByteFromNewBlock(); } -CByteInBufWrap::CByteInBufWrap(): Buf(NULL) +CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL) { vt.Read = Wrap_ReadByte; } @@ -227,7 +237,7 @@ /* EXTERN_C_BEGIN -void CLookToSequentialWrap_Look(ILookInSeqStream *pp) +void CLookToSequentialWrap_Look(ILookInSeqStreamPtr pp) { CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj; @@ -281,9 +291,10 @@ return Res; } -static void Wrap_WriteByte(const IByteOut *pp, Byte b) throw() +static void Wrap_WriteByte(IByteOutPtr pp, Byte b) throw() { - CByteOutBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt); + CByteOutBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteOutBufWrap) Byte *dest = p->Cur; *dest = b; p->Cur = ++dest; @@ -317,16 +328,16 @@ return (Buf != NULL); } -static size_t LookOutWrap_GetOutBuf(const ILookOutStream *pp, void **buf) throw() +static size_t LookOutWrap_GetOutBuf(ILookOutStreamPtr pp, void **buf) throw() { - CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); *buf = p->Buf; return p->Size; } -static size_t LookOutWrap_Write(const ILookOutStream *pp, size_t size) throw() +static size_t LookOutWrap_Write(ILookOutStreamPtr pp, size_t size) throw() { - CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); if (p->Res == S_OK && size != 0) { p->Res = WriteStream(p->Stream, p->Buf, size); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/CWrappers.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.h --- 7zip-22.01+dfsg/CPP/7zip/Common/CWrappers.h 2021-01-24 15:35:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CWrappers.h 2023-05-04 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // CWrappers.h -#ifndef __C_WRAPPERS_H -#define __C_WRAPPERS_H +#ifndef ZIP7_INC_C_WRAPPERS_H +#define ZIP7_INC_C_WRAPPERS_H #include "../ICoder.h" #include "../../Common/MyCom.h" @@ -63,7 +63,7 @@ bool Extra; HRESULT Res; - CByteInBufWrap(); + CByteInBufWrap() throw(); ~CByteInBufWrap() { Free(); } void Free() throw(); bool Alloc(UInt32 size) throw(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/CreateCoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/CreateCoder.cpp 2021-08-05 08:12:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.cpp 2024-10-27 08:00:00.000000000 +0000 @@ -19,11 +19,11 @@ const CCodecInfo *g_Codecs[kNumCodecsMax]; // We use g_ExternalCodecs in other stages. -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS /* extern CExternalCodecs g_ExternalCodecs; #define CHECK_GLOBAL_CODECS \ - if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs; + if (!_externalCodecs || !_externalCodecs->IsSet()) _externalCodecs = &g_ExternalCodecs; */ #define CHECK_GLOBAL_CODECS #endif @@ -35,7 +35,7 @@ g_Codecs[g_NumCodecs++] = codecInfo; } -static const unsigned kNumHashersMax = 16; +static const unsigned kNumHashersMax = 32; extern unsigned g_NumHashers; unsigned g_NumHashers = 0; @@ -50,12 +50,12 @@ } -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = 1; else if (prop.vt == VT_UI4) @@ -68,7 +68,7 @@ static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = true; else if (prop.vt == VT_BOOL) @@ -89,13 +89,13 @@ UString s; UInt32 num; - RINOK(GetCodecs->GetNumMethods(&num)); + RINOK(GetCodecs->GetNumMethods(&num)) for (UInt32 i = 0; i < num; i++) { NWindows::NCOM::CPropVariant prop; - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; // old Interface info.Id = prop.uhVal.QuadPart; @@ -103,22 +103,22 @@ prop.Clear(); info.Name.Empty(); - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) continue; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)) { UInt32 numUnpackStreams = 1; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)) if (numUnpackStreams != 1) continue; } - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter)); + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter)) Codecs.Add(info); } @@ -133,7 +133,7 @@ { NWindows::NCOM::CPropVariant prop; - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; info.Id = prop.uhVal.QuadPart; @@ -141,7 +141,7 @@ prop.Clear(); info.Name.Empty(); - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -162,7 +162,8 @@ const AString &name, bool encode, CMethodId &methodId, - UInt32 &numStreams) + UInt32 &numStreams, + bool &isFilter) { unsigned i; for (i = 0; i < g_NumCodecs; i++) @@ -173,23 +174,25 @@ { methodId = codec.Id; numStreams = codec.NumStreams; + isFilter = codec.IsFilter; return (int)i; } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned) && StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; numStreams = codec.NumStreams; + isFilter = codec.IsFilter; return (int)(g_NumCodecs + i); } } @@ -212,14 +215,14 @@ return (int)i; } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)) return (int)(g_NumCodecs + i); } @@ -248,14 +251,14 @@ } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; if (methodId == codec.Id) { name = codec.Name; @@ -284,14 +287,14 @@ } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; @@ -313,13 +316,13 @@ for (i = 0; i < g_NumHashers; i++) methods[i] = (*g_Hashers[i]).Id; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - methods.Add(__externalCodecs->Hashers[i].Id); + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + methods.Add(_externalCodecs->Hashers[i].Id); #endif } @@ -364,17 +367,17 @@ } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) + if (_externalCodecs) { i -= g_NumCodecs; cod.IsExternal = true; - if (i < __externalCodecs->Codecs.Size()) + if (i < _externalCodecs->Codecs.Size()) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; // if (codec.Id == methodId) { if (encode) @@ -383,15 +386,15 @@ { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } else @@ -399,15 +402,15 @@ { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } } @@ -424,7 +427,7 @@ CCreatedCoder &cod) { CMyComPtr filter; - HRESULT res = CreateCoder_Index( + const HRESULT res = CreateCoder_Index( EXTERNAL_CODECS_LOC_VARS index, encode, filter, cod); @@ -447,7 +450,7 @@ CMyComPtr &filter, CCreatedCoder &cod) { - int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode); + const int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode); if (index < 0) return S_OK; return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)index, encode, filter, cod); @@ -460,7 +463,7 @@ CCreatedCoder &cod) { CMyComPtr filter; - HRESULT res = CreateCoder_Id( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, filter, cod); @@ -483,7 +486,7 @@ CMyComPtr &coder) { CCreatedCoder cod; - HRESULT res = CreateCoder_Id( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, cod); @@ -524,18 +527,18 @@ } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (!hasher && __externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (!hasher && _externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (codec.Id == methodId) { name = codec.Name; - return __externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); + return _externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/CreateCoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.h --- 7zip-22.01+dfsg/CPP/7zip/Common/CreateCoder.h 2021-08-05 09:09:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/CreateCoder.h 2023-03-18 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // CreateCoder.h -#ifndef __CREATE_CODER_H -#define __CREATE_CODER_H +#ifndef ZIP7_INC_CREATE_CODER_H +#define ZIP7_INC_CREATE_CODER_H #include "../../Common/MyCom.h" #include "../../Common/MyString.h" @@ -11,10 +11,10 @@ #include "MethodId.h" /* - if EXTERNAL_CODECS is not defined, the code supports only codecs that + if Z7_EXTERNAL_CODECS is not defined, the code supports only codecs that are statically linked at compile-time and link-time. - if EXTERNAL_CODECS is defined, the code supports also codecs from another + if Z7_EXTERNAL_CODECS is defined, the code supports also codecs from another executable modules, that can be linked dynamically at run-time: - EXE module can use codecs from external DLL files. - DLL module can use codecs from external EXE and DLL files. @@ -26,7 +26,7 @@ 2) External codecs */ -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CCodecInfoEx { @@ -46,13 +46,17 @@ AString Name; }; -#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo, -#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo) -#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo); -#define IMPL_ISetCompressCodecsInfo2(x) \ -STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \ - COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.Load(); COM_TRY_END } -#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC \ + public ISetCompressCodecsInfo, +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC \ + Z7_COM_QI_ENTRY(ISetCompressCodecsInfo) +#define DECL_ISetCompressCodecsInfo \ + Z7_COM7F_IMP(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +#define IMPL_ISetCompressCodecsInfo2(cls) \ + Z7_COM7F_IMF(cls::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) \ + { COM_TRY_BEGIN _externalCodecs.GetCodecs = compressCodecsInfo; \ + return _externalCodecs.Load(); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) struct CExternalCodecs { @@ -83,26 +87,27 @@ extern CExternalCodecs g_ExternalCodecs; -#define EXTERNAL_CODECS_VARS2 (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs) -#define EXTERNAL_CODECS_VARS2_L (&__externalCodecs) +#define EXTERNAL_CODECS_VARS2 (_externalCodecs.IsSet() ? &_externalCodecs : &g_ExternalCodecs) +#define EXTERNAL_CODECS_VARS2_L (&_externalCodecs) #define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs) -#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs; +#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs _externalCodecs; #define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, #define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L, #define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G, -#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs -#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *_externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL DECL_EXTERNAL_CODECS_LOC_VARS2; -#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, -#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, +#define EXTERNAL_CODECS_LOC_VARS2 _externalCodecs +#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, #else -#define PUBLIC_ISetCompressCodecsInfo -#define QUERY_ENTRY_ISetCompressCodecsInfo +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC #define DECL_ISetCompressCodecsInfo #define IMPL_ISetCompressCodecsInfo #define EXTERNAL_CODECS_VARS2 @@ -111,8 +116,9 @@ #define EXTERNAL_CODECS_VARS_L #define EXTERNAL_CODECS_VARS_G #define DECL_EXTERNAL_CODECS_LOC_VARS2 -#define EXTERNAL_CODECS_LOC_VARS2 #define DECL_EXTERNAL_CODECS_LOC_VARS +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL +#define EXTERNAL_CODECS_LOC_VARS2 #define EXTERNAL_CODECS_LOC_VARS #endif @@ -122,7 +128,8 @@ const AString &name, bool encode, CMethodId &methodId, - UInt32 &numStreams); + UInt32 &numStreams, + bool &isFilter); bool FindMethod( DECL_EXTERNAL_CODECS_LOC_VARS diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FilePathAutoRename.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/FilePathAutoRename.cpp 2021-01-24 14:03:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.cpp 2024-01-23 15:00:00.000000000 +0000 @@ -19,8 +19,8 @@ bool AutoRenamePath(FString &path) { - int dotPos = path.ReverseFind_Dot(); - int slashPos = path.ReverseFind_PathSepar(); + const int dotPos = path.ReverseFind_Dot(); + const int slashPos = path.ReverseFind_PathSepar(); FString name = path; FString extension; @@ -29,14 +29,14 @@ name.DeleteFrom((unsigned)dotPos); extension = path.Ptr((unsigned)dotPos); } - name += '_'; + name.Add_Char('_'); FString temp; - UInt32 left = 1, right = ((UInt32)1 << 30); + UInt32 left = 1, right = (UInt32)1 << 30; while (left != right) { - UInt32 mid = (left + right) / 2; + const UInt32 mid = (left + right) / 2; if (MakeAutoName(name, extension, mid, temp)) left = mid + 1; else diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FilePathAutoRename.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.h --- 7zip-22.01+dfsg/CPP/7zip/Common/FilePathAutoRename.h 2013-01-17 09:56:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilePathAutoRename.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // FilePathAutoRename.h -#ifndef __FILE_PATH_AUTO_RENAME_H -#define __FILE_PATH_AUTO_RENAME_H +#ifndef ZIP7_INC_FILE_PATH_AUTO_RENAME_H +#define ZIP7_INC_FILE_PATH_AUTO_RENAME_H #include "../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FileStreams.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/FileStreams.cpp 2022-07-12 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -11,18 +11,32 @@ #include #include +/* +inclusion of by is deprecated since glibc 2.25. +Since glibc 2.3.3, macros have been aliases for three GNU-specific +functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor() + +Warning in GCC: +In the GNU C Library, "major" is defined by . +For historical compatibility, it is currently defined by + as well, but we plan to remove this soon. +To use "major", include directly. +If you did not intend to use a system-defined macro "major", +you should undefine it after including +*/ // for major()/minor(): -#if defined(__FreeBSD__) || defined(BSD) +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else #include #endif -#endif +#endif // _WIN32 #include "../../Windows/FileFind.h" -#ifdef SUPPORT_DEVICE_FILE +#ifdef Z7_DEVICE_FILE #include "../../../C/Alloc.h" #include "../../Common/Defs.h" #endif @@ -47,15 +61,15 @@ } -#ifdef SUPPORT_DEVICE_FILE +#ifdef Z7_DEVICE_FILE static const UInt32 kClusterSize = 1 << 18; #endif CInFileStream::CInFileStream(): - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos(0), PhyPos(0), - Buf(0), + Buf(NULL), BufSize(0), #endif #ifndef _WIN32 @@ -73,7 +87,7 @@ CInFileStream::~CInFileStream() { - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE MidFree(Buf); #endif @@ -81,11 +95,13 @@ Callback->InFileStream_On_Destroy(this, CallbackRef); } -STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + // printf("\nCInFileStream::Read size=%d, VirtPos=%8d\n", (unsigned)size, (int)VirtPos); + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (processedSize) *processedSize = 0; if (size == 0) @@ -96,7 +112,7 @@ { if (VirtPos >= File.Size) return VirtPos == File.Size ? S_OK : E_FAIL; - UInt64 rem = File.Size - VirtPos; + const UInt64 rem = File.Size - VirtPos; if (size > rem) size = (UInt32)rem; } @@ -104,13 +120,13 @@ { const UInt32 mask = kClusterSize - 1; const UInt64 mask2 = ~(UInt64)mask; - UInt64 alignedPos = VirtPos & mask2; + const UInt64 alignedPos = VirtPos & mask2; if (BufSize > 0 && BufStartPos == alignedPos) { - UInt32 pos = (UInt32)VirtPos & mask; + const UInt32 pos = (UInt32)VirtPos & mask; if (pos >= BufSize) return S_OK; - UInt32 rem = MyMin(BufSize - pos, size); + const UInt32 rem = MyMin(BufSize - pos, size); memcpy(data, Buf + pos, rem); VirtPos += rem; if (processedSize) @@ -119,7 +135,7 @@ } bool useBuf = false; - if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 ) + if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 ) useBuf = true; else { @@ -138,7 +154,7 @@ if (alignedPos != PhyPos) { UInt64 realNewPosition; - bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); + const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); if (!result) return ConvertBoolToHRESULT(result); PhyPos = realNewPosition; @@ -155,7 +171,7 @@ if (!Buf) return E_OUTOFMEMORY; } - bool result = File.Read1(Buf, readSize, BufSize); + const bool result = File.Read1(Buf, readSize, BufSize); if (!result) return ConvertBoolToHRESULT(result); @@ -180,7 +196,7 @@ if (processedSize) *processedSize = realProcessedSize; - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos += realProcessedSize; PhyPos += realProcessedSize; #endif @@ -188,7 +204,7 @@ if (result) return S_OK; - #else // USE_WIN_FILE + #else // Z7_FILE_STREAMS_USE_WIN_FILE if (processedSize) *processedSize = 0; @@ -199,10 +215,14 @@ *processedSize = (UInt32)res; return S_OK; } - #endif // USE_WIN_FILE + #endif // Z7_FILE_STREAMS_USE_WIN_FILE { const DWORD error = ::GetLastError(); +#if 0 + if (File.IsStdStream && error == ERROR_BROKEN_PIPE) + return S_OK; // end of stream +#endif if (Callback) return Callback->InFileStream_On_Error(CallbackRef, error); if (error == 0) @@ -212,7 +232,7 @@ } #ifdef UNDER_CE -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fread(data, 1, size, stdin); int error = ferror(stdin); @@ -223,15 +243,37 @@ return E_FAIL; } #else -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { + // printf("\nCStdInFileStream::Read size = %d\n", (unsigned)size); #ifdef _WIN32 DWORD realProcessedSize; UInt32 sizeTemp = (1 << 20); if (sizeTemp > size) sizeTemp = size; + /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL, + and it doesn't set LastError. */ + /* + SetLastError(0); + const HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (!h || h == INVALID_HANDLE_VALUE) + { + if (processedSize) + *processedSize = 0; + if (GetLastError() == 0) + SetLastError(ERROR_INVALID_HANDLE); + return GetLastError_noZero_HRESULT(); + } + */ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL); + + /* + printf("\nCInFileStream::Read: size=%d, processed=%8d res=%d 4rror=%3d\n", + (unsigned)size, (int)realProcessedSize, + (int)res, GetLastError()); + */ + if (processedSize) *processedSize = realProcessedSize; if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) @@ -259,14 +301,68 @@ #endif -STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + +/* +bool CreateStdInStream(CMyComPtr &str) +{ +#if 0 + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec);; + if (!inStreamSpec->OpenStdIn()) + return false; + if (!inStreamSpec->File.IsStdPipeStream) + str = inStreamLoc.Detach(); + else +#endif + str = new CStdInFileStream; + return true; +} +*/ + +#if 0 +bool CInFileStream::OpenStdIn() +{ + _info_WasLoaded = false; + // Sleep(100); + bool res = File.AttachStdIn(); + if (!res) + return false; +#if 1 + CStreamFileProps props; + if (GetProps2(&props) != S_OK) + { + // we can ignore that error + return false; + } + // we can't use Size, because Size can be set for pipe streams for some value. + // Seek() sees only current chunk in pipe buffer. + // So Seek() can move across only current unread chunk. + // But after reading that chunk. it can't move position back. + // We need safe check that shows that we can use seek (non-pipe mode) + // Is it safe check that shows that pipe mode was used? + File.IsStdPipeStream = (props.VolID == 0); + // && FILETIME_IsZero(props.CTime) + // && FILETIME_IsZero(props.ATime) + // && FILETIME_IsZero(props.MTime); +#endif + // printf("\n######## pipe=%d", (unsigned)File.IsStdPipeStream); + return true; +} +#endif + + +Z7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { + /* + printf("\nCInFileStream::Seek seekOrigin=%d, offset=%8d, VirtPos=%8d\n", + (unsigned)seekOrigin, (int)offset, (int)VirtPos); + */ if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) { switch (seekOrigin) @@ -293,7 +389,7 @@ in case of error. So we don't need additional code below */ // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); } - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE PhyPos = VirtPos = realNewPosition; #endif @@ -319,17 +415,19 @@ #endif } -STDMETHODIMP CInFileStream::GetSize(UInt64 *size) +Z7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size)) { return ConvertBoolToHRESULT(File.GetLength(*size)); } -#ifdef USE_WIN_FILE +#ifdef Z7_FILE_STREAMS_USE_WIN_FILE -STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) { if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } const BY_HANDLE_FILE_INFORMATION &info = _info; /* BY_HANDLE_FILE_INFORMATION info; @@ -346,10 +444,12 @@ } } -STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) { if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } const BY_HANDLE_FILE_INFORMATION &info = _info; /* BY_HANDLE_FILE_INFORMATION info; @@ -370,17 +470,19 @@ } } -STDMETHODIMP CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) { if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } if (!_info_WasLoaded) return S_OK; NWindows::NCOM::CPropVariant prop; - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (File.IsDeviceFile) { switch (propID) @@ -436,9 +538,9 @@ } -STDMETHODIMP CInFileStream::ReloadProps() +Z7_COM7F_IMF(CInFileStream::ReloadProps()) { - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (File.IsDeviceFile) { memset(&_info, 0, sizeof(_info)); @@ -455,16 +557,44 @@ _info_WasLoaded = File.GetFileInformation(&_info); if (!_info_WasLoaded) return GetLastError_HRESULT(); +#ifdef _WIN32 +#if 0 + printf( + "\ndwFileAttributes = %8x" + "\nftCreationTime = %8x" + "\nftLastAccessTime = %8x" + "\nftLastWriteTime = %8x" + "\ndwVolumeSerialNumber = %8x" + "\nnFileSizeHigh = %8x" + "\nnFileSizeLow = %8x" + "\nnNumberOfLinks = %8x" + "\nnFileIndexHigh = %8x" + "\nnFileIndexLow = %8x \n", + (unsigned)_info.dwFileAttributes, + (unsigned)_info.ftCreationTime.dwHighDateTime, + (unsigned)_info.ftLastAccessTime.dwHighDateTime, + (unsigned)_info.ftLastWriteTime.dwHighDateTime, + (unsigned)_info.dwVolumeSerialNumber, + (unsigned)_info.nFileSizeHigh, + (unsigned)_info.nFileSizeLow, + (unsigned)_info.nNumberOfLinks, + (unsigned)_info.nFileIndexHigh, + (unsigned)_info.nFileIndexLow); +#endif +#endif return S_OK; } #elif !defined(_WIN32) -STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) { + // printf("\nCInFileStream::GetProps VirtPos = %8d\n", (int)VirtPos); if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } const struct stat &st = _info; /* struct stat st; @@ -483,10 +613,13 @@ // #include -STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) { + // printf("\nCInFileStream::GetProps2 VirtPos = %8d\n", (int)VirtPos); if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } const struct stat &st = _info; /* struct stat st; @@ -521,10 +654,13 @@ return S_OK; } -STDMETHODIMP CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) { + // printf("\nCInFileStream::GetProperty VirtPos = %8d propID = %3d\n", (int)VirtPos, propID); if (!_info_WasLoaded) - RINOK(ReloadProps()); + { + RINOK(ReloadProps()) + } if (!_info_WasLoaded) return S_OK; @@ -544,6 +680,11 @@ case kpidMTime: PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break; case kpidPosixAttrib: prop = (UInt32)st.st_mode; break; + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + case kpidDeviceMajor: { // printf("\nst.st_rdev = %d\n", st.st_rdev); @@ -563,6 +704,10 @@ // prop = (UInt32)123456789; // for debug break; + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + /* case kpidDevice: if (S_ISCHR(st.st_mode) || @@ -625,6 +770,7 @@ } break; } + default: break; } } prop.Detach(value); @@ -632,7 +778,7 @@ } -STDMETHODIMP CInFileStream::ReloadProps() +Z7_COM7F_IMF(CInFileStream::ReloadProps()) { _info_WasLoaded = (File.my_fstat(&_info) == 0); if (!_info_WasLoaded) @@ -653,9 +799,9 @@ return ConvertBoolToHRESULT(File.Close()); } -STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE UInt32 realProcessedSize; const bool result = File.Write(data, size, realProcessedSize); @@ -680,12 +826,12 @@ #endif } -STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE UInt64 realNewPosition = 0; const bool result = File.Seek(offset, seekOrigin, realNewPosition); @@ -705,7 +851,7 @@ #endif } -STDMETHODIMP COutFileStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize)) { return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize)); } @@ -717,7 +863,7 @@ #ifdef UNDER_CE -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fwrite(data, 1, size, stdout); if (processedSize) @@ -727,7 +873,7 @@ #else -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FileStreams.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.h --- 7zip-22.01+dfsg/CPP/7zip/Common/FileStreams.h 2022-06-09 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FileStreams.h 2024-03-28 13:00:00.000000000 +0000 @@ -1,10 +1,10 @@ // FileStreams.h -#ifndef __FILE_STREAMS_H -#define __FILE_STREAMS_H +#ifndef ZIP7_INC_FILE_STREAMS_H +#define ZIP7_INC_FILE_STREAMS_H #ifdef _WIN32 -#define USE_WIN_FILE +#define Z7_FILE_STREAMS_USE_WIN_FILE #endif #include "../../Common/MyCom.h" @@ -18,13 +18,27 @@ class CInFileStream; -struct IInFileStream_Callback + +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IInFileStream_Callback) { virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0; virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) = 0; }; +Z7_PURE_INTERFACES_END + -class CInFileStream: +/* +Z7_CLASS_IMP_COM_5( + CInFileStream + , IInStream + , IStreamGetSize + , IStreamGetProps + , IStreamGetProps2 + , IStreamGetProp +) +*/ +Z7_class_final(CInFileStream) : public IInStream, public IStreamGetSize, public IStreamGetProps, @@ -32,12 +46,31 @@ public IStreamGetProp, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_6( + IInStream, + ISequentialInStream, + IStreamGetSize, + IStreamGetProps, + IStreamGetProps2, + IStreamGetProp) + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(IInStream) +public: + Z7_IFACE_COM7_IMP(IStreamGetSize) +private: + Z7_IFACE_COM7_IMP(IStreamGetProps) +public: + Z7_IFACE_COM7_IMP(IStreamGetProps2) + Z7_IFACE_COM7_IMP(IStreamGetProp) + +private: NWindows::NFile::NIO::CInFile File; public: - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE UInt64 VirtPos; UInt64 PhyPos; UInt64 BufStartPos; @@ -64,9 +97,8 @@ IInFileStream_Callback *Callback; UINT_PTR CallbackRef; - virtual ~CInFileStream(); - CInFileStream(); + ~CInFileStream(); void Set_PreserveATime(bool v) { @@ -77,6 +109,10 @@ { return File.GetLength(length); } + +#if 0 + bool OpenStdIn(); +#endif bool Open(CFSTR fileName) { @@ -89,53 +125,48 @@ _info_WasLoaded = false; return File.OpenShared(fileName, shareForWrite); } - - MY_QUERYINTERFACE_BEGIN2(IInStream) - MY_QUERYINTERFACE_ENTRY(IStreamGetSize) - MY_QUERYINTERFACE_ENTRY(IStreamGetProps) - MY_QUERYINTERFACE_ENTRY(IStreamGetProps2) - MY_QUERYINTERFACE_ENTRY(IStreamGetProp) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - STDMETHOD(GetSize)(UInt64 *size); - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib); - STDMETHOD(GetProps2)(CStreamFileProps *props); - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(ReloadProps)(); }; -class CStdInFileStream: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP +// bool CreateStdInStream(CMyComPtr &str); - virtual ~CStdInFileStream() {} - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +Z7_CLASS_IMP_NOQIB_1( + CStdInFileStream + , ISequentialInStream +) }; -class COutFileStream: - public IOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + COutFileStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) public: + NWindows::NFile::NIO::COutFile File; - virtual ~COutFileStream() {} - bool Create(CFSTR fileName, bool createAlways) + bool Create_NEW(CFSTR fileName) + { + ProcessedSize = 0; + return File.Create_NEW(fileName); + } + + bool Create_ALWAYS(CFSTR fileName) + { + ProcessedSize = 0; + return File.Create_ALWAYS(fileName); + } + + bool Open_EXISTING(CFSTR fileName) { ProcessedSize = 0; - return File.Create(fileName, createAlways); + return File.Open_EXISTING(fileName); } - bool Open(CFSTR fileName, DWORD creationDisposition) + + bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways) { ProcessedSize = 0; - return File.Open(fileName, creationDisposition); + return File.Create_ALWAYS_or_Open_ALWAYS(fileName, createAlways); } HRESULT Close(); @@ -148,15 +179,9 @@ } bool SetMTime(const CFiTime *mTime) { return File.SetMTime(mTime); } - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); - bool SeekToBegin_bool() { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE return File.SeekToBegin(); #else return File.seekToBegin() == 0; @@ -166,18 +191,15 @@ HRESULT GetSize(UInt64 *size); }; -class CStdOutFileStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CStdOutFileStream + , ISequentialOutStream +) UInt64 _size; public: - MY_UNKNOWN_IMP - UInt64 GetSize() const { return _size; } CStdOutFileStream(): _size(0) {} - virtual ~CStdOutFileStream() {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FilterCoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/FilterCoder.cpp 2019-09-10 13:47:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.cpp 2023-03-18 13:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include + #include "../../Common/Defs.h" #include "FilterCoder.h" @@ -33,13 +35,17 @@ Some filters (BCJ and others) don't process data at the end of stream in some cases. So the encoder and decoder write such last bytes without change. + + Most filters process all data, if we send aligned size to filter. + But BCJ filter can process up 4 bytes less than sent size. + And ARMT filter can process 2 bytes less than sent size. */ -static const UInt32 kBufSize = 1 << 20; +static const UInt32 kBufSize = 1 << 21; -STDMETHODIMP CFilterCoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CFilterCoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetOutBufSize(UInt32 , UInt32 size)) { _outBufSize = size; return S_OK; } HRESULT CFilterCoder::Alloc() { @@ -51,6 +57,7 @@ size &= ~(UInt32)(kMinSize - 1); if (size < kMinSize) size = kMinSize; + // size = (1 << 12); // + 117; // for debug if (!_buf || _bufSize != size) { AllocAligned(size); @@ -63,7 +70,7 @@ HRESULT CFilterCoder::Init_and_Alloc() { - RINOK(Filter->Init()); + RINOK(Filter->Init()) return Alloc(); } @@ -72,78 +79,197 @@ _inBufSize(kBufSize), _outBufSize(kBufSize), _encodeMode(encodeMode), - _outSizeIsDefined(false), + _outSize_Defined(false), _outSize(0), _nowPos64(0) {} -CFilterCoder::~CFilterCoder() -{ -} -STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { - RINOK(Init_and_Alloc()); - + RINOK(Init_and_Alloc()) + + /* + It's expected that BCJ/ARMT filter can process up to 4 bytes less + than sent data size. For such BCJ/ARMT cases with non-filtered data we: + - write some filtered data to output stream + - move non-written data (filtered and non-filtered data) to start of buffer + - read more new data from input stream to position after end of non-filtered data + - call Filter() for concatenated data in buffer. + + For all cases, even for cases with partial filtering (BCJ/ARMT), + we try to keep real/virtual alignment for all operations + (memmove, Read(), Filter(), Write()). + We use (kAlignSize=64) alignmnent that is larger than (16-bytes) + required for AES filter alignment. + + AES-CBC uses 16-bytes blocks, that is simple case for processing here, + if we call Filter() for aligned size for all calls except of last call (last block). + And now there are no filters that use blocks with non-power2 size, + but we try to support such non-power2 filters too here at Code(). + */ + UInt64 prev = 0; UInt64 nowPos64 = 0; bool inputFinished = false; - UInt32 pos = 0; + UInt32 readPos = 0; + UInt32 filterPos = 0; while (!outSize || nowPos64 < *outSize) { + HRESULT hres = S_OK; if (!inputFinished) { - size_t processedSize = _bufSize - pos; - RINOK(ReadStream(inStream, _buf + pos, &processedSize)); - pos += (UInt32)processedSize; - inputFinished = (pos != _bufSize); + size_t processedSize = _bufSize - readPos; + /* for AES filters we need at least max(16, kAlignSize) bytes in buffer. + But we try to read full buffer to reduce the number of Filter() and Write() calls. + */ + hres = ReadStream(inStream, _buf + readPos, &processedSize); + readPos += (UInt32)processedSize; + inputFinished = (readPos != _bufSize); + if (hres != S_OK) + { + // do we need to stop encoding after reading error? + // if (_encodeMode) return hres; + inputFinished = true; + } } - if (pos == 0) - return S_OK; + if (readPos == 0) + return hres; - UInt32 filtered = Filter->Filter(_buf, pos); - - if (filtered > pos) + /* we set (needMoreInput = true), if it's block-filter (like AES-CBC) + that needs more data for current block filtering: + We read full input buffer with Read(), and _bufSize is aligned, + So the possible cases when we set (needMoreInput = true) are: + 1) decode : filter needs more data after the end of input stream. + another cases are possible for non-power2-block-filter, + because buffer size is not aligned for filter_non_power2_block_size: + 2) decode/encode : filter needs more data from non-finished input stream + 3) encode : filter needs more space for zeros after the end of input stream + */ + bool needMoreInput = false; + + while (readPos != filterPos) + { + /* Filter() is allowed to process part of data. + Here we use the loop to filter as max as possible. + when we call Filter(data, size): + if (size < 16), AES-CTR filter uses internal 16-byte buffer. + new (since v23.00) AES-CTR filter allows (size < 16) for non-last block, + but it will work less efficiently than calls with aligned (size). + We still support old (before v23.00) AES-CTR filters here. + We have aligned (size) for AES-CTR, if it's not last block. + We have aligned (readPos) for any filter, if (!inputFinished). + We also meet the requirements for (data) pointer in Filter() call: + { + (virtual_stream_offset % aligment_size) == (data_ptr % aligment_size) + (aligment_size == 2^N) + (aligment_size >= 16) + } + */ + const UInt32 cur = Filter->Filter(_buf + filterPos, readPos - filterPos); + if (cur == 0) + break; + const UInt32 f = filterPos + cur; + if (cur > readPos - filterPos) + { + // AES-CBC + if (hres != S_OK) + break; + + if (!_encodeMode + || cur > _bufSize - filterPos + || !inputFinished) + { + /* (cur > _bufSize - filterPos) is unexpected for AES filter, if _bufSize is multiply of 16. + But we support this case, if some future filter will use block with non-power2-size. + */ + needMoreInput = true; + break; + } + + /* (_encodeMode && inputFinished). + We add zero bytes as pad in current block after the end of read data. */ + Byte *buf = _buf; + do + buf[readPos] = 0; + while (++readPos != f); + // (readPos) now is (size_of_real_input_data + size_of_zero_pad) + if (cur != Filter->Filter(buf + filterPos, cur)) + return E_FAIL; + } + filterPos = f; + } + + UInt32 size = filterPos; + if (hres == S_OK) { - // AES - if (!inputFinished || filtered > _bufSize) - return E_FAIL; + /* If we need more Read() or Filter() calls, then we need to Write() + some data and move unwritten data to get additional space in buffer. + We try to keep alignment for data moves, Read(), Filter() and Write() calls. + */ + const UInt32 kAlignSize = 1 << 6; + const UInt32 alignedFiltered = filterPos & ~(kAlignSize - 1); + if (inputFinished) + { + if (!needMoreInput) + size = readPos; // for risc/bcj filters in last block we write data after filterPos. + else if (_encodeMode) + size = alignedFiltered; // for non-power2-block-encode-filter + } + else + size = alignedFiltered; + } + + { + UInt32 writeSize = size; + if (outSize) + { + const UInt64 rem = *outSize - nowPos64; + if (writeSize > rem) + writeSize = (UInt32)rem; + } + RINOK(WriteStream(outStream, _buf, writeSize)) + nowPos64 += writeSize; + } + + if (hres != S_OK) + return hres; + + if (inputFinished) + { + if (readPos == size) + return hres; if (!_encodeMode) + { + // block-decode-filter (AES-CBS) has non-full last block + // we don't want unaligned data move for more iterations with this error case. return S_FALSE; - - Byte *buf = _buf; - do - buf[pos] = 0; - while (++pos != filtered); - - if (filtered != Filter->Filter(buf, filtered)) - return E_FAIL; + } } - UInt32 size = (filtered != 0 ? filtered : pos); - if (outSize) + if (size == 0) { - const UInt64 remSize = *outSize - nowPos64; - if (size > remSize) - size = (UInt32)remSize; + // it's unexpected that we have no any move in this iteration. + return E_FAIL; } - - RINOK(WriteStream(outStream, _buf, size)); - nowPos64 += size; - - if (filtered == 0) - return S_OK; - pos -= filtered; - for (UInt32 i = 0; i < pos; i++) - _buf[i] = _buf[filtered++]; + // if (size != 0) + { + if (filterPos < size) + return E_FAIL; // filterPos = 0; else + filterPos -= size; + readPos -= size; + if (readPos != 0) + memmove(_buf, _buf + size, readPos); + } + // printf("\nnowPos64=%x, readPos=%x, filterPos=%x\n", (unsigned)nowPos64, (unsigned)readPos, (unsigned)filterPos); if (progress && (nowPos64 - prev) >= (1 << 22)) { prev = nowPos64; - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); + RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)) } } @@ -154,13 +280,13 @@ // ---------- Write to Filter ---------- -STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CFilterCoder::SetOutStream(ISequentialOutStream *outStream)) { _outStream = outStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseOutStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseOutStream()) { _outStream.Release(); return S_OK; @@ -171,9 +297,9 @@ while (_convSize != 0) { UInt32 num = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (num > rem) num = (UInt32)rem; if (num == 0) @@ -181,21 +307,23 @@ } UInt32 processed = 0; - HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); + const HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); if (processed == 0) return res != S_OK ? res : E_FAIL; _convPos += processed; _convSize -= processed; _nowPos64 += processed; - RINOK(res); + RINOK(res) } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } @@ -203,14 +331,14 @@ return S_OK; } -STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; while (size != 0) { - RINOK(Flush2()); + RINOK(Flush2()) // _convSize is 0 // _convPos is 0 @@ -245,20 +373,22 @@ return S_OK; } -STDMETHODIMP CFilterCoder::OutStreamFinish() +Z7_COM7F_IMF(CFilterCoder::OutStreamFinish()) { for (;;) { - RINOK(Flush2()); + RINOK(Flush2()) if (_bufPos == 0) break; - _convSize = Filter->Filter(_buf, _bufPos); - if (_convSize == 0) - _convSize = _bufPos; - else if (_convSize > _bufPos) + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; + UInt32 bufPos = _bufPos; + if (convSize == 0) + _convSize = bufPos; + else if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) { _convSize = 0; return E_FAIL; @@ -268,9 +398,11 @@ _convSize = 0; return S_FALSE; } - for (; _bufPos < _convSize; _bufPos++) - _buf[_bufPos] = 0; - _convSize = Filter->Filter(_buf, _bufPos); + Byte *buf = _buf; + for (; bufPos < convSize; bufPos++) + buf[bufPos] = 0; + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, bufPos); if (_convSize != _bufPos) return E_FAIL; } @@ -285,7 +417,7 @@ // ---------- Init functions ---------- -STDMETHODIMP CFilterCoder::InitEncoder() +Z7_COM7F_IMF(CFilterCoder::InitEncoder()) { InitSpecVars(); return Init_and_Alloc(); @@ -297,33 +429,33 @@ return Alloc(); } -STDMETHODIMP CFilterCoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CFilterCoder::SetOutStreamSize(const UInt64 *outSize)) { InitSpecVars(); if (outSize) { _outSize = *outSize; - _outSizeIsDefined = true; + _outSize_Defined = true; } return Init_and_Alloc(); } // ---------- Read from Filter ---------- -STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CFilterCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseInStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -334,9 +466,9 @@ { if (size > _convSize) size = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (size > rem) size = (UInt32)rem; } @@ -349,46 +481,51 @@ break; } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } { size_t readSize = _bufSize - _bufPos; - HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); + const HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); _bufPos += (UInt32)readSize; - RINOK(res); + RINOK(res) } - _convSize = Filter->Filter(_buf, _bufPos); + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; - if (_convSize == 0) + UInt32 bufPos = _bufPos; + + if (convSize == 0) { - if (_bufPos == 0) + if (bufPos == 0) break; // BCJ - _convSize = _bufPos; + _convSize = bufPos; continue; } - if (_convSize > _bufPos) + if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) return E_FAIL; if (!_encodeMode) return S_FALSE; - + Byte *buf = _buf; do - _buf[_bufPos] = 0; - while (++_bufPos != _convSize); - - _convSize = Filter->Filter(_buf, _convSize); + buf[bufPos] = 0; + while (++bufPos != convSize); + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, convSize); if (_convSize != _bufPos) return E_FAIL; } @@ -398,39 +535,43 @@ } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO -STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) - { return _SetPassword->CryptoSetPassword(data, size); } +Z7_COM7F_IMF(CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)) + { return _setPassword->CryptoSetPassword(data, size); } -STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size) - { return _CryptoProperties->SetKey(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetKey(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetKey(data, size); } -STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size) - { return _CryptoProperties->SetInitVector(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetInitVector(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetInitVector(data, size); } #endif -#ifndef EXTRACT_ONLY - -STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties) - { return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } +#ifndef Z7_EXTRACT_ONLY -STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) - { return _WriteCoderProperties->WriteCoderProperties(outStream); } +Z7_COM7F_IMF(CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } + +Z7_COM7F_IMF(CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)) + { return _writeCoderProperties->WriteCoderProperties(outStream); } + +Z7_COM7F_IMF(CFilterCoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderPropertiesOpt->SetCoderPropertiesOpt(propIDs, properties, numProperties); } /* -STDMETHODIMP CFilterCoder::ResetSalt() - { return _CryptoResetSalt->ResetSalt(); } +Z7_COM7F_IMF(CFilterCoder::ResetSalt() + { return _cryptoResetSalt->ResetSalt(); } */ -STDMETHODIMP CFilterCoder::ResetInitVector() - { return _CryptoResetInitVector->ResetInitVector(); } +Z7_COM7F_IMF(CFilterCoder::ResetInitVector()) + { return _cryptoResetInitVector->ResetInitVector(); } #endif -STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { return _SetDecoderProperties2->SetDecoderProperties2(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) + { return _setDecoderProperties2->SetDecoderProperties2(data, size); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/FilterCoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.h --- 7zip-22.01+dfsg/CPP/7zip/Common/FilterCoder.h 2018-12-30 17:40:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/FilterCoder.h 2023-03-18 13:00:00.000000000 +0000 @@ -1,18 +1,18 @@ // FilterCoder.h -#ifndef __FILTER_CODER_H -#define __FILTER_CODER_H +#ifndef ZIP7_INC_FILTER_CODER_H +#define ZIP7_INC_FILTER_CODER_H #include "../../../C/Alloc.h" #include "../../Common/MyCom.h" #include "../ICoder.h" -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO #include "../IPassword.h" #endif -#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ +#define Z7_COM_QI_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ *outObject = (void *)(i *)this; } @@ -26,7 +26,8 @@ void AllocAligned(size_t size); }; -class CFilterCoder: + +class CFilterCoder Z7_final : public ICompressCoder, public ICompressSetOutStreamSize, @@ -41,14 +42,15 @@ public ICompressSetBufSize, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoSetPassword, public ICryptoProperties, #endif - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public ICompressSetCoderProperties, public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, // public ICryptoResetSalt, public ICryptoResetInitVector, #endif @@ -62,7 +64,7 @@ UInt32 _outBufSize; bool _encodeMode; - bool _outSizeIsDefined; + bool _outSize_Defined; UInt64 _outSize; UInt64 _nowPos64; @@ -78,7 +80,7 @@ _convPos = 0; _convSize = 0; - _outSizeIsDefined = false; + _outSize_Defined = false; _outSize = 0; _nowPos64 = 0; } @@ -87,117 +89,111 @@ HRESULT Init_and_Alloc(); HRESULT Flush2(); - #ifndef _NO_CRYPTO - CMyComPtr _SetPassword; - CMyComPtr _CryptoProperties; + #ifndef Z7_NO_CRYPTO + CMyComPtr _setPassword; + CMyComPtr _cryptoProperties; #endif - #ifndef EXTRACT_ONLY - CMyComPtr _SetCoderProperties; - CMyComPtr _WriteCoderProperties; - // CMyComPtr _CryptoResetSalt; - CMyComPtr _CryptoResetInitVector; + #ifndef Z7_EXTRACT_ONLY + CMyComPtr _setCoderProperties; + CMyComPtr _writeCoderProperties; + CMyComPtr _setCoderPropertiesOpt; + // CMyComPtr _cryptoResetSalt; + CMyComPtr _cryptoResetInitVector; #endif - CMyComPtr _SetDecoderProperties2; + CMyComPtr _setDecoderProperties2; public: CMyComPtr Filter; CFilterCoder(bool encodeMode); - ~CFilterCoder(); - class C_InStream_Releaser + struct C_InStream_Releaser { - public: CFilterCoder *FilterCoder; C_InStream_Releaser(): FilterCoder(NULL) {} ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } }; - class C_OutStream_Releaser + struct C_OutStream_Releaser { - public: CFilterCoder *FilterCoder; C_OutStream_Releaser(): FilterCoder(NULL) {} ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } }; - class C_Filter_Releaser + struct C_Filter_Releaser { - public: CFilterCoder *FilterCoder; C_Filter_Releaser(): FilterCoder(NULL) {} ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); } }; +private: + Z7_COM_QI_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ICompressInitEncoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ISequentialInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) - MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) - MY_QUERYINTERFACE_ENTRY(IOutStreamFinish) + Z7_COM_QI_ENTRY(ICompressSetOutStream) + Z7_COM_QI_ENTRY(ISequentialOutStream) + Z7_COM_QI_ENTRY(IOutStreamFinish) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + Z7_COM_QI_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties) #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) - MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties) - // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY_AG(ICompressSetCoderProperties, Filter, _setCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressSetCoderPropertiesOpt, Filter, _setCoderPropertiesOpt) + // Z7_COM_QI_ENTRY_AG(ICryptoResetSalt, Filter, _cryptoResetSalt) + Z7_COM_QI_ENTRY_AG(ICryptoResetInitVector, Filter, _cryptoResetInitVector) #endif - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + Z7_COM_QI_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties2) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(InitEncoder)(); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); - STDMETHOD(ReleaseOutStream)(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); +public: + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressInitEncoder) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) +public: + Z7_IFACE_COM7_IMP(ICompressSetOutStream) +private: + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + Z7_IFACE_COM7_IMP(IOutStreamFinish) +private: - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + Z7_IFACE_COM7_IMP(ICompressSetBufSize) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoSetPassword) + Z7_IFACE_COM7_IMP(ICryptoProperties) + #endif + + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) #endif - #ifndef EXTRACT_ONLY - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); - #endif - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) HRESULT Init_NoSubFilterInit(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/InBuffer.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/InBuffer.cpp 2022-02-09 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.cpp 2023-12-24 13:00:00.000000000 +0000 @@ -7,10 +7,10 @@ #include "InBuffer.h" CInBufferBase::CInBufferBase() throw(): - _buf(0), - _bufLim(0), - _bufBase(0), - _stream(0), + _buf(NULL), + _bufLim(NULL), + _bufBase(NULL), + _stream(NULL), _processedSize(0), _bufSize(0), _wasFinished(false), @@ -22,18 +22,18 @@ const unsigned kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_bufBase != 0 && _bufSize == bufSize) + if (_bufBase != NULL && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _bufBase = (Byte *)::MidAlloc(bufSize); - return (_bufBase != 0); + return (_bufBase != NULL); } void CInBuffer::Free() throw() { ::MidFree(_bufBase); - _bufBase = 0; + _bufBase = NULL; } void CInBufferBase::Init() throw() @@ -42,7 +42,7 @@ _buf = _bufBase; _bufLim = _buf; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; @@ -50,7 +50,7 @@ bool CInBufferBase::ReadBlock() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return false; #endif @@ -61,8 +61,8 @@ _bufLim = _bufBase; UInt32 processed; // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) - HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); - #ifdef _NO_EXCEPTIONS + const HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) @@ -96,6 +96,24 @@ return *_buf++; } +size_t CInBufferBase::ReadBytesPart(Byte *buf, size_t size) +{ + if (size == 0) + return 0; + size_t rem = (size_t)(_bufLim - _buf); + if (rem == 0) + { + if (!ReadBlock()) + return 0; + rem = (size_t)(_bufLim - _buf); + } + if (size > rem) + size = rem; + memcpy(buf, _buf, size); + _buf += size; + return size; +} + size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) { size_t num = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/InBuffer.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.h --- 7zip-22.01+dfsg/CPP/7zip/Common/InBuffer.h 2021-01-24 15:38:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InBuffer.h 2025-02-20 08:00:00.000000000 +0000 @@ -1,12 +1,12 @@ // InBuffer.h -#ifndef __IN_BUFFER_H -#define __IN_BUFFER_H +#ifndef ZIP7_INC_IN_BUFFER_H +#define ZIP7_INC_IN_BUFFER_H #include "../../Common/MyException.h" #include "../IStream.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct CInBufferException: public CSystemException { CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -31,7 +31,7 @@ Byte ReadByte_FromNewBlock(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif UInt32 NumExtraBytes; @@ -51,6 +51,7 @@ bool WasFinished() const { return _wasFinished; } void SetStream(ISequentialInStream *stream) { _stream = stream; } + void ClearStreamPtr() { _stream = NULL; } void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos) { @@ -60,7 +61,7 @@ _buf = buf + pos; _bufLim = buf + end; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; @@ -68,7 +69,7 @@ void Init() throw(); - MY_FORCE_INLINE + Z7_FORCE_INLINE bool ReadByte(Byte &b) { if (_buf >= _bufLim) @@ -77,7 +78,7 @@ return true; } - MY_FORCE_INLINE + Z7_FORCE_INLINE bool ReadByte_FromBuf(Byte &b) { if (_buf >= _bufLim) @@ -86,7 +87,7 @@ return true; } - MY_FORCE_INLINE + Z7_FORCE_INLINE Byte ReadByte() { if (_buf >= _bufLim) @@ -94,7 +95,18 @@ return *_buf++; } + size_t ReadBytesPart(Byte *buf, size_t size); size_t ReadBytes(Byte *buf, size_t size); + const Byte *Lookahead(size_t &rem) + { + rem = (size_t)(_bufLim - _buf); + if (!rem) + { + ReadBlock(); + rem = (size_t)(_bufLim - _buf); + } + return _buf; + } size_t Skip(size_t size); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/InOutTempBuffer.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/InOutTempBuffer.cpp 2019-08-27 18:33:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.cpp 2022-12-19 22:00:00.000000000 +0000 @@ -2,170 +2,236 @@ #include "StdAfx.h" +#include "../../../C/Alloc.h" + #include "InOutTempBuffer.h" + #include "StreamUtils.h" #ifdef USE_InOutTempBuffer_FILE #include "../../../C/7zCrc.h" -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static const size_t kTempBufSize = (1 << 20); - #define kTempFilePrefixString FTEXT("7zt") -CInOutTempBuffer::~CInOutTempBuffer() -{ - delete []_buf; -} +/* + Total buffer size limit, if we use temp file scheme: + 32-bit: 16 MiB = 1 MiB * 16 buffers + 64-bit: 4 GiB = 1 MiB * 4096 buffers +*/ +static const size_t kNumBufsMax = (size_t)1 << (sizeof(size_t) * 2 - 4); + #endif -CInOutTempBuffer::CInOutTempBuffer() - #ifdef USE_InOutTempBuffer_FILE - : _buf(NULL) - #endif -{ } +static const size_t kBufSize = (size_t)1 << 20; -void CInOutTempBuffer::Create() -{ - #ifdef USE_InOutTempBuffer_FILE - if (!_buf) - _buf = new Byte[kTempBufSize]; - #endif -} -void CInOutTempBuffer::InitWriting() -{ - #ifdef USE_InOutTempBuffer_FILE - _bufPos = 0; +CInOutTempBuffer::CInOutTempBuffer(): + _size(0), + _bufs(NULL), + _numBufs(0), + _numFilled(0) +{ + #ifdef USE_InOutTempBuffer_FILE + _tempFile_Created = false; + _useMemOnly = false; _crc = CRC_INIT_VAL; - _tempFileCreated = false; - #endif - _size = 0; + #endif } +CInOutTempBuffer::~CInOutTempBuffer() +{ + for (size_t i = 0; i < _numBufs; i++) + MyFree(_bufs[i]); + MyFree(_bufs); +} -#ifdef USE_InOutTempBuffer_FILE -static inline HRESULT Get_HRESULT_LastError() +void *CInOutTempBuffer::GetBuf(size_t index) { - #ifdef _WIN32 - DWORD lastError = ::GetLastError(); - if (lastError != 0) - return HRESULT_FROM_WIN32(lastError); - #endif - return E_FAIL; + if (index >= _numBufs) + { + const size_t num = (_numBufs == 0 ? 16 : _numBufs * 2); + void **p = (void **)MyRealloc(_bufs, num * sizeof(void *)); + if (!p) + return NULL; + _bufs = p; + memset(p + _numBufs, 0, (num - _numBufs) * sizeof(void *)); + _numBufs = num; + } + + void *buf = _bufs[index]; + if (!buf) + { + buf = MyAlloc(kBufSize); + if (buf) + _bufs[index] = buf; + } + return buf; } -#endif - HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size) { - #ifdef USE_InOutTempBuffer_FILE - if (size == 0) return S_OK; - size_t cur = kTempBufSize - _bufPos; - if (cur != 0) + + #ifdef USE_InOutTempBuffer_FILE + if (!_tempFile_Created) + #endif + for (;;) // loop for additional attemp to allocate memory after file creation error { - if (cur > size) - cur = size; - memcpy(_buf + _bufPos, data, cur); - _crc = CrcUpdate(_crc, data, cur); - _bufPos += cur; - _size += cur; - size -= (UInt32)cur; - data = ((const Byte *)data) + cur; - } - - if (size == 0) - return S_OK; + #ifdef USE_InOutTempBuffer_FILE + bool allocError = false; + #endif + + for (;;) // loop for writing to buffers + { + const size_t index = (size_t)(_size / kBufSize); + + #ifdef USE_InOutTempBuffer_FILE + if (index >= kNumBufsMax && !_useMemOnly) + break; + #endif + + void *buf = GetBuf(index); + if (!buf) + { + #ifdef USE_InOutTempBuffer_FILE + if (!_useMemOnly) + { + allocError = true; + break; + } + #endif + return E_OUTOFMEMORY; + } + + const size_t offset = (size_t)(_size) & (kBufSize - 1); + size_t cur = kBufSize - offset; + if (cur > size) + cur = size; + memcpy((Byte *)buf + offset, data, cur); + _size += cur; + if (index >= _numFilled) + _numFilled = index + 1; + data = (const void *)((const Byte *)data + cur); + size -= (UInt32)cur; + if (size == 0) + return S_OK; + } - if (!_tempFileCreated) - { - if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) - return Get_HRESULT_LastError(); - _tempFileCreated = true; + #ifdef USE_InOutTempBuffer_FILE + #ifndef _WIN32 + _outFile.mode_for_Create = 0600; // only owner will have the rights to access this file + #endif + if (_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) + { + _tempFile_Created = true; + break; + } + _useMemOnly = true; + if (allocError) + return GetLastError_noZero_HRESULT(); + #endif } - UInt32 processed; - if (!_outFile.Write(data, size, processed)) - return Get_HRESULT_LastError(); - _crc = CrcUpdate(_crc, data, processed); - _size += processed; - return (processed == size) ? S_OK : E_FAIL; - - #else - - const size_t newSize = _size + size; - if (newSize < _size) - return E_OUTOFMEMORY; - if (!_dynBuffer.EnsureCapacity(newSize)) - return E_OUTOFMEMORY; - memcpy(((Byte *)_dynBuffer) + _size, data, size); - _size = newSize; - return S_OK; - #endif + #ifdef USE_InOutTempBuffer_FILE + if (!_outFile.WriteFull(data, size)) + return GetLastError_noZero_HRESULT(); + _crc = CrcUpdate(_crc, data, size); + _size += size; + return S_OK; + #endif } HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { - #ifdef USE_InOutTempBuffer_FILE - - if (!_outFile.Close()) - return E_FAIL; + UInt64 rem = _size; + // if (rem == 0) return S_OK; - UInt64 size = 0; - UInt32 crc = CRC_INIT_VAL; + const size_t numFilled = _numFilled; + _numFilled = 0; - if (_bufPos != 0) - { - RINOK(WriteStream(stream, _buf, _bufPos)); - crc = CrcUpdate(crc, _buf, _bufPos); - size += _bufPos; - } - - if (_tempFileCreated) + for (size_t i = 0; i < numFilled; i++) { - NIO::CInFile inFile; - if (!inFile.Open(_tempFile.GetPath())) + if (rem == 0) return E_FAIL; - while (size < _size) + size_t cur = kBufSize; + if (cur > rem) + cur = (size_t)rem; + RINOK(WriteStream(stream, _bufs[i], cur)) + rem -= cur; + #ifdef USE_InOutTempBuffer_FILE + // we will use _bufs[0] later for writing from temp file + if (i != 0 || !_tempFile_Created) + #endif { - UInt32 processed; - if (!inFile.ReadPart(_buf, kTempBufSize, processed)) - return E_FAIL; - if (processed == 0) - break; - RINOK(WriteStream(stream, _buf, processed)); - crc = CrcUpdate(crc, _buf, processed); - size += processed; + MyFree(_bufs[i]); + _bufs[i] = NULL; } } - return (_crc == crc && size == _size) ? S_OK : E_FAIL; - #else - return WriteStream(stream, (const Byte *)_dynBuffer, _size); + #ifdef USE_InOutTempBuffer_FILE - #endif -} + if (rem == 0) + return _tempFile_Created ? E_FAIL : S_OK; -/* -STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) -{ - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; + if (!_tempFile_Created) return E_FAIL; + + if (!_outFile.Close()) + return GetLastError_noZero_HRESULT(); + + HRESULT hres; + void *buf = GetBuf(0); // index + if (!buf) + hres = E_OUTOFMEMORY; + else + { + NWindows::NFile::NIO::CInFile inFile; + if (!inFile.Open(_tempFile.GetPath())) + hres = GetLastError_noZero_HRESULT(); + else + { + UInt32 crc = CRC_INIT_VAL; + for (;;) + { + size_t processed; + if (!inFile.ReadFull(buf, kBufSize, processed)) + { + hres = GetLastError_noZero_HRESULT(); + break; + } + if (processed == 0) + { + // we compare crc without CRC_GET_DIGEST + hres = (_crc == crc ? S_OK : E_FAIL); + break; + } + size_t n = processed; + if (n > rem) + n = (size_t)rem; + hres = WriteStream(stream, buf, n); + if (hres != S_OK) + break; + crc = CrcUpdate(crc, buf, n); + rem -= n; + if (n != processed) + { + hres = E_FAIL; + break; + } + } + } } - if (processed) - *processed = size; - return S_OK; + + // _tempFile.DisableDeleting(); // for debug + _tempFile.Remove(); + RINOK(hres) + + #endif + + return rem == 0 ? S_OK : E_FAIL; } -*/ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/InOutTempBuffer.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.h --- 7zip-22.01+dfsg/CPP/7zip/Common/InOutTempBuffer.h 2019-08-27 18:32:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/InOutTempBuffer.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,66 +1,45 @@ // InOutTempBuffer.h -#ifndef __IN_OUT_TEMP_BUFFER_H -#define __IN_OUT_TEMP_BUFFER_H +#ifndef ZIP7_INC_IN_OUT_TEMP_BUFFER_H +#define ZIP7_INC_IN_OUT_TEMP_BUFFER_H -#ifdef _WIN32 -// #define USE_InOutTempBuffer_FILE -#endif +// #ifdef _WIN32 +#define USE_InOutTempBuffer_FILE +// #endif #ifdef USE_InOutTempBuffer_FILE #include "../../Windows/FileDir.h" -#else -#include "StreamObjects.h" #endif #include "../IStream.h" class CInOutTempBuffer { - #ifdef USE_InOutTempBuffer_FILE + UInt64 _size; + void **_bufs; + size_t _numBufs; + size_t _numFilled; + + #ifdef USE_InOutTempBuffer_FILE + bool _tempFile_Created; + bool _useMemOnly; + UInt32 _crc; + // COutFile object must be declared after CTempFile object for correct destructor order NWindows::NFile::NDir::CTempFile _tempFile; NWindows::NFile::NIO::COutFile _outFile; - bool _tempFileCreated; - Byte *_buf; - size_t _bufPos; - UInt64 _size; - UInt32 _crc; - #else - - CByteDynBuffer _dynBuffer; - size_t _size; - - #endif + #endif - CLASS_NO_COPY(CInOutTempBuffer); + void *GetBuf(size_t index); + + Z7_CLASS_NO_COPY(CInOutTempBuffer) public: CInOutTempBuffer(); - void Create(); - - #ifdef USE_InOutTempBuffer_FILE ~CInOutTempBuffer(); - #endif - - void InitWriting(); HRESULT Write_HRESULT(const void *data, UInt32 size); HRESULT WriteToStream(ISequentialOutStream *stream); UInt64 GetDataSize() const { return _size; } }; -/* -class CSequentialOutTempBufferImp: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; -public: - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; -*/ - #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/LimitedStreams.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/LimitedStreams.cpp 2022-02-01 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -6,7 +6,7 @@ #include "LimitedStreams.h" -STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; { @@ -27,7 +27,7 @@ return result; } -STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -46,7 +46,7 @@ if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } HRESULT res = _stream->Read(data, size, &size); if (processedSize) @@ -56,7 +56,7 @@ return res; } -STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -75,17 +75,17 @@ HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream) { - *resStream = 0; + *resStream = NULL; CLimitedInStream *streamSpec = new CLimitedInStream; CMyComPtr streamTemp = streamSpec; streamSpec->SetStream(inStream); - RINOK(streamSpec->InitAndSeek(pos, size)); + RINOK(streamSpec->InitAndSeek(pos, size)) streamSpec->SeekToStart(); *resStream = streamTemp.Detach(); return S_OK; } -STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -110,7 +110,7 @@ if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } _curRem = blockSize - offsetInBlock; @@ -130,7 +130,7 @@ return res; } -STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -150,7 +150,7 @@ } -STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -201,7 +201,7 @@ if (_phyPos != phy) { _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error - RINOK(Stream->Seek((Int64)phy, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(Stream, phy)) _phyPos = phy; } } @@ -218,7 +218,7 @@ } -STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -236,7 +236,7 @@ } -STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (processedSize) @@ -263,7 +263,7 @@ } -STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Read(data, size, &cur); @@ -273,7 +273,7 @@ return res; } -STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -282,7 +282,7 @@ case STREAM_SEEK_END: { UInt64 pos = 0; - RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)); + RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)) if (pos < Offset) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; _virtPos = pos - Offset; @@ -297,10 +297,10 @@ _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; - return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, Offset + _virtPos); } -STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -329,7 +329,7 @@ if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } res = _stream->Read(data, size, &size); _physPos += size; @@ -340,7 +340,7 @@ return res; } -STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -357,7 +357,7 @@ return S_OK; } -STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Write(data, size, &cur); @@ -369,7 +369,7 @@ return res; } -STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -386,7 +386,7 @@ return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL); } -STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(CTailOutStream::SetSize(UInt64 newSize)) { _virtSize = newSize; return Stream->SetSize(Offset + newSize); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/LimitedStreams.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.h --- 7zip-22.01+dfsg/CPP/7zip/Common/LimitedStreams.h 2022-02-01 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LimitedStreams.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,17 +1,19 @@ // LimitedStreams.h -#ifndef __LIMITED_STREAMS_H -#define __LIMITED_STREAMS_H +#ifndef ZIP7_INC_LIMITED_STREAMS_H +#define ZIP7_INC_LIMITED_STREAMS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" #include "../../Common/MyVector.h" #include "../IStream.h" -class CLimitedSequentialInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +#include "StreamUtils.h" + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialInStream + , ISequentialInStream +) CMyComPtr _stream; UInt64 _size; UInt64 _pos; @@ -25,26 +27,22 @@ _pos = 0; _wasFinished = false; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _pos; } UInt64 GetRem() const { return _size - _pos; } bool WasFinished() const { return _wasFinished; } }; -class CLimitedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedInStream +) CMyComPtr _stream; UInt64 _virtPos; UInt64 _physPos; UInt64 _size; UInt64 _startOffset; - HRESULT SeekToPhys() { return _stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: void SetStream(IInStream *stream) { _stream = stream; } HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) @@ -55,21 +53,15 @@ _size = size; return SeekToPhys(); } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); -class CClusterInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CClusterInStream +) UInt64 _virtPos; UInt64 _physPos; UInt32 _curRem; @@ -80,7 +72,7 @@ CRecordVector Vector; UInt64 StartOffset; - HRESULT SeekToPhys() { return Stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } HRESULT InitAndSeek() { @@ -94,11 +86,6 @@ } return S_OK; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; @@ -114,23 +101,18 @@ bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; } }; -class CExtentsStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CExtentsStream +) UInt64 _virtPos; UInt64 _phyPos; unsigned _prevExtentIndex; - public: CMyComPtr Stream; CRecordVector Extents; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); void ReleaseStream() { Stream.Release(); } - void Init() { _virtPos = 0; @@ -141,17 +123,15 @@ -class CLimitedSequentialOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLimitedSequentialOutStream + , ISequentialOutStream +) CMyComPtr _stream; UInt64 _size; bool _overflow; bool _overflowIsAllowed; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(UInt64 size, bool overflowIsAllowed = false) @@ -165,10 +145,9 @@ }; -class CTailInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CTailInStream +) UInt64 _virtPos; public: CMyComPtr Stream; @@ -178,19 +157,13 @@ { _virtPos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Stream->Seek((Int64)Offset, STREAM_SEEK_SET, NULL); } + HRESULT SeekToStart() { return InStream_SeekSet(Stream, Offset); } }; -class CLimitedCachedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedCachedInStream +) CMyComPtr _stream; UInt64 _virtPos; UInt64 _physPos; @@ -201,8 +174,7 @@ size_t _cacheSize; size_t _cachePhyPos; - - HRESULT SeekToPhys() { return _stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: CByteBuffer Buffer; @@ -223,37 +195,27 @@ return SeekToPhys(); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; -class CTailOutStream: + +class CTailOutStream Z7_final : public IOutStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialOutStream, IOutStream) + UInt64 _virtPos; UInt64 _virtSize; public: CMyComPtr Stream; UInt64 Offset; - virtual ~CTailOutStream() {} - - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) - void Init() { _virtPos = 0; _virtSize = 0; } - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/LockedStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LockedStream.h --- 7zip-22.01+dfsg/CPP/7zip/Common/LockedStream.h 2014-12-27 17:19:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/LockedStream.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ // LockedStream.h -#ifndef __LOCKED_STREAM_H -#define __LOCKED_STREAM_H +#ifndef ZIP7_INC_LOCKED_STREAM_H +#define ZIP7_INC_LOCKED_STREAM_H #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MemBlocks.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/MemBlocks.cpp 2021-06-05 11:26:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.cpp 2023-09-07 16:00:00.000000000 +0000 @@ -34,8 +34,8 @@ void CMemBlockManager::FreeSpace() { ::MidFree(_data); - _data = 0; - _headFree= 0; + _data = NULL; + _headFree= NULL; } void *CMemBlockManager::AllocateBlock() @@ -57,7 +57,7 @@ // #include -HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) +HRESULT CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) { if (numNoLockBlocks > numBlocks) return E_INVALIDARG; @@ -87,7 +87,7 @@ } -HRes CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks) +HRESULT CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks) { // desiredNumberOfBlocks = 0; // for debug if (numNoLockBlocks > desiredNumberOfBlocks) @@ -95,7 +95,7 @@ for (;;) { // if (desiredNumberOfBlocks == 0) return E_OUTOFMEMORY; - HRes hres = AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks); + const HRESULT hres = AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks); if (hres != E_OUTOFMEMORY) return hres; if (desiredNumberOfBlocks == numNoLockBlocks) @@ -157,7 +157,7 @@ curSize = (size_t)totalSize; if (blockIndex >= Blocks.Size()) return E_FAIL; - RINOK(WriteStream(outStream, Blocks[blockIndex], curSize)); + RINOK(WriteStream(outStream, Blocks[blockIndex], curSize)) totalSize -= curSize; } return S_OK; @@ -207,7 +207,7 @@ blocks.Blocks.Add(Blocks[i]); else FreeBlock(i, memManager); - Blocks[i] = 0; + Blocks[i] = NULL; totalSize += blockSize; } blocks.TotalSize = TotalSize; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MemBlocks.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.h --- 7zip-22.01+dfsg/CPP/7zip/Common/MemBlocks.h 2021-01-24 15:52:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MemBlocks.h 2023-09-06 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // MemBlocks.h -#ifndef __MEM_BLOCKS_H -#define __MEM_BLOCKS_H +#ifndef ZIP7_INC_MEM_BLOCKS_H +#define ZIP7_INC_MEM_BLOCKS_H #include "../../Common/MyVector.h" @@ -30,14 +30,14 @@ { NWindows::NSynchronization::CCriticalSection _criticalSection; public: - SYNC_OBJ_DECL(Synchro); + SYNC_OBJ_DECL(Synchro) NWindows::NSynchronization::CSemaphore_WFMO Semaphore; CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {} ~CMemBlockManagerMt() { FreeSpace(); } - HRes AllocateSpace(size_t numBlocks, size_t numNoLockBlocks); - HRes AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); + HRESULT AllocateSpace(size_t numBlocks, size_t numNoLockBlocks); + HRESULT AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); void FreeSpace(); void *AllocateBlock(); void FreeBlock(void *p, bool lockMode = true); @@ -62,10 +62,10 @@ { bool LockMode; - CMemLockBlocks(): LockMode(true) {}; + CMemLockBlocks(): LockMode(true) {} void Free(CMemBlockManagerMt *memManager); void FreeBlock(unsigned index, CMemBlockManagerMt *memManager); - // HRes SwitchToNoLockMode(CMemBlockManagerMt *memManager); + // HRESULT SwitchToNoLockMode(CMemBlockManagerMt *memManager); void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MethodId.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodId.h --- 7zip-22.01+dfsg/CPP/7zip/Common/MethodId.h 2013-01-17 07:40:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodId.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // MethodId.h -#ifndef __7Z_METHOD_ID_H -#define __7Z_METHOD_ID_H +#ifndef ZIP7_INC_7Z_METHOD_ID_H +#define ZIP7_INC_7Z_METHOD_ID_H #include "../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MethodProps.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/MethodProps.cpp 2021-11-17 19:21:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.cpp 2025-06-28 09:00:00.000000000 +0000 @@ -60,6 +60,7 @@ case VT_EMPTY: dest = true; return S_OK; case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK; case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG; + default: break; } return E_INVALIDARG; } @@ -323,15 +324,22 @@ HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const { - return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL); + return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL, NULL, NULL); } HRESULT CProps::SetCoderProps_DSReduce_Aff( ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, - const UInt64 *affinity) const -{ - CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0) + (affinity ? 1 : 0) ); + const UInt64 *affinity, + const UInt32 *affinityGroup, + const UInt64 *affinityInGroup) const +{ + CCoderProps coderProps(Props.Size() + + (dataSizeReduce ? 1 : 0) + + (affinity ? 1 : 0) + + (affinityGroup ? 1 : 0) + + (affinityInGroup ? 1 : 0) + ); FOR_VECTOR (i, Props) coderProps.AddProp(Props[i]); if (dataSizeReduce) @@ -348,6 +356,20 @@ prop.Value = *affinity; coderProps.AddProp(prop); } + if (affinityGroup) + { + CProp prop; + prop.Id = NCoderPropID::kThreadGroup; + prop.Value = *affinityGroup; + coderProps.AddProp(prop); + } + if (affinityInGroup) + { + CProp prop; + prop.Id = NCoderPropID::kAffinityInGroup; + prop.Value = *affinityInGroup; + coderProps.AddProp(prop); + } return coderProps.SetProps(scp); } @@ -379,14 +401,14 @@ // the following are related to NCoderPropID::EEnum values - +// NCoderPropID::k_NUM_DEFINED static const CNameToPropID g_NameToPropID[] = { { VT_UI4, "" }, { VT_UI4, "d" }, { VT_UI4, "mem" }, { VT_UI4, "o" }, - { VT_UI4, "c" }, + { VT_UI8, "c" }, { VT_UI4, "pb" }, { VT_UI4, "lc" }, { VT_UI4, "lp" }, @@ -400,15 +422,62 @@ { VT_UI4, "x" }, { VT_UI8, "reduce" }, { VT_UI8, "expect" }, - { VT_UI4, "b" }, + { VT_UI8, "cc" }, // "cc" in v23, "b" in v22.01 { VT_UI4, "check" }, { VT_BSTR, "filter" }, - { VT_UI8, "memuse" } + { VT_UI8, "memuse" }, + { VT_UI8, "aff" }, + { VT_UI4, "offset" }, + { VT_UI4, "zhb" } + /* + , { VT_UI4, "tgn" }, // kNumThreadGroups + , { VT_UI4, "tgi" }, // kThreadGroup + , { VT_UI8, "tga" }, // kAffinityInGroup + */ + /* + , + // { VT_UI4, "zhc" }, + // { VT_UI4, "zhd" }, + // { VT_UI4, "zcb" }, + { VT_UI4, "dc" }, + { VT_UI4, "zx" }, + { VT_UI4, "zf" }, + { VT_UI4, "zmml" }, + { VT_UI4, "zov" }, + { VT_BOOL, "zmfr" }, + { VT_BOOL, "zle" }, // long enable + // { VT_UI4, "zldb" }, + { VT_UI4, "zld" }, + { VT_UI4, "zlhb" }, + { VT_UI4, "zlmml" }, + { VT_UI4, "zlbb" }, + { VT_UI4, "zlhrb" }, + { VT_BOOL, "zwus" }, + { VT_BOOL, "zshp" }, + { VT_BOOL, "zshs" }, + { VT_BOOL, "zshe" }, + { VT_BOOL, "zshg" }, + { VT_UI4, "zpsm" } + */ + // { VT_UI4, "mcb" }, // mc log version + // { VT_UI4, "ztlen" }, // fb ? }; +/* +#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 200410L) || (defined(_MSC_VER) && _MSC_VER >= 1600) + +#if (defined(__cplusplus) && __cplusplus < 201103L) \ + && defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wc11-extensions" +#endif + static_assert(Z7_ARRAY_SIZE(g_NameToPropID) == NCoderPropID::k_NUM_DEFINED, + "g_NameToPropID doesn't match NCoderPropID enum"); +#endif +*/ + static int FindPropIdExact(const UString &name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NameToPropID); i++) if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name)) return (int)i; return -1; @@ -493,8 +562,13 @@ case NCoderPropID::kUsedMemorySize: case NCoderPropID::kBlockSize: case NCoderPropID::kBlockSize2: + /* + case NCoderPropID::kChainSize: + case NCoderPropID::kLdmWindowSize: + */ // case NCoderPropID::kReduceSize: return true; + default: break; } return false; } @@ -503,14 +577,19 @@ { int index = FindPropIdExact(name); if (index < 0) - return E_INVALIDARG; + { + // 'b' was used as NCoderPropID::kBlockSize2 before v23 + if (!name.IsEqualTo_Ascii_NoCase("b") || value.Find(L':') >= 0) + return E_INVALIDARG; + index = NCoderPropID::kBlockSize2; + } const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; CProp prop; prop.Id = (unsigned)index; if (IsLogSizeProp(prop.Id)) { - RINOK(StringToDictSize(value, prop.Value)); + RINOK(StringToDictSize(value, prop.Value)) } else { @@ -561,7 +640,7 @@ const UString ¶m = params[i]; UString name, value; SplitParam(param, name, value); - RINOK(SetParam(name, value)); + RINOK(SetParam(name, value)) } return S_OK; } @@ -582,7 +661,7 @@ } // {realName}=value - int index = FindPropIdExact(realName); + const int index = FindPropIdExact(realName); if (index < 0) return E_INVALIDARG; const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; @@ -591,7 +670,7 @@ if (IsLogSizeProp(prop.Id)) { - RINOK(PROPVARIANT_to_DictSize(value, prop.Value)); + RINOK(PROPVARIANT_to_DictSize(value, prop.Value)) } else { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MethodProps.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.h --- 7zip-22.01+dfsg/CPP/7zip/Common/MethodProps.h 2021-11-19 07:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MethodProps.h 2025-06-28 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // MethodProps.h -#ifndef __7Z_METHOD_PROPS_H -#define __7Z_METHOD_PROPS_H +#ifndef ZIP7_INC_7Z_METHOD_PROPS_H +#define ZIP7_INC_7Z_METHOD_PROPS_H #include "../../Common/MyString.h" #include "../../Common/Defs.h" @@ -80,7 +80,11 @@ } HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const; - HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, const UInt64 *affinity) const; + HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, + const UInt64 *dataSizeReduce, + const UInt64 *affinity, + const UInt32 *affinityGroup, + const UInt64 *affinityInGroup) const; }; class CMethodProps: public CProps @@ -125,7 +129,7 @@ UInt32 Get_Lzma_Algo() const { - int i = FindProp(NCoderPropID::kAlgorithm); + const int i = FindProp(NCoderPropID::kAlgorithm); if (i >= 0) { const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; @@ -141,11 +145,11 @@ if (Get_DicSize(v)) return v; const unsigned level = GetLevel(); - const UInt32 dictSize = - ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : - ( level <= 6 ? ((UInt32)1 << (level + 19)) : - ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) - ))); + const UInt32 dictSize = level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); return dictSize; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MultiOutStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/MultiOutStream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.cpp 2023-09-05 07:00:00.000000000 +0000 @@ -0,0 +1,855 @@ +// MultiOutStream.cpp + +#include "StdAfx.h" + +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include + #define PRF(x) x; +#else + #define PRF(x) +#endif + +#include "../../Common/ComTry.h" + +#include "../../Windows/FileDir.h" +#include "../../Windows/FileFind.h" +#include "../../Windows/System.h" + +#include "MultiOutStream.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const unsigned k_NumVols_MAX = k_VectorSizeMax - 1; + // 2; // for debug + +/* +#define UPDATE_HRES(hres, x) \ + { const HRESULT res2 = (x); if (hres == SZ_OK) hres = res2; } +*/ + +HRESULT CMultiOutStream::Destruct() +{ + COM_TRY_BEGIN + HRESULT hres = S_OK; + HRESULT hres3 = S_OK; + + while (!Streams.IsEmpty()) + { + try + { + HRESULT hres2; + if (NeedDelete) + { + /* we could call OptReOpen_and_SetSize() to test that we try to delete correct file, + but we cannot guarantee that (RealSize) will be correct after Write() or another failures. + And we still want to delete files even for such cases. + So we don't check for OptReOpen_and_SetSize() here: */ + // if (OptReOpen_and_SetSize(Streams.Size() - 1, 0) == S_OK) + hres2 = CloseStream_and_DeleteFile(Streams.Size() - 1); + } + else + { + hres2 = CloseStream(Streams.Size() - 1); + } + if (hres == S_OK) + hres = hres2; + } + catch(...) + { + hres3 = E_OUTOFMEMORY; + } + + { + /* Stream was released in CloseStream_*() above already, and it was removed from linked list + it's some unexpected case, if Stream is still attached here. + So the following code is optional: */ + CVolStream &s = Streams.Back(); + if (s.Stream) + { + if (hres3 == S_OK) + hres3 = E_FAIL; + s.Stream.Detach(); + /* it will be not failure, even if we call RemoveFromLinkedList() + twice for same CVolStream in this Destruct() function */ + RemoveFromLinkedList(Streams.Size() - 1); + } + } + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + + if (hres == S_OK) + hres = hres3; + if (hres == S_OK && NumListItems != 0) + hres = E_FAIL; + return hres; + COM_TRY_END +} + + +CMultiOutStream::~CMultiOutStream() +{ + // we try to avoid exception in destructors + Destruct(); +} + + +void CMultiOutStream::Init(const CRecordVector &sizes) +{ + Streams.Clear(); + InitLinkedList(); + Sizes = sizes; + NeedDelete = true; + MTime_Defined = false; + FinalVol_WasReopen = false; + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + _absLimit = (UInt64)(Int64)-1; + + _restrict_Begin = 0; + _restrict_End = (UInt64)(Int64)-1; + _restrict_Global = 0; + + UInt64 sum = 0; + unsigned i = 0; + for (i = 0; i < Sizes.Size(); i++) + { + if (i >= k_NumVols_MAX) + { + _absLimit = sum; + break; + } + const UInt64 size = Sizes[i]; + const UInt64 next = sum + size; + if (next < sum) + break; + sum = next; + } + + // if (Sizes.IsEmpty()) throw "no volume sizes"; + const UInt64 size = Sizes.Back(); + if (size == 0) + throw "zero size last volume"; + + if (i == Sizes.Size()) + if ((_absLimit - sum) / size >= (k_NumVols_MAX - i)) + _absLimit = sum + (k_NumVols_MAX - i) * size; +} + + +/* IsRestricted(): + we must call only if volume is full (s.RealSize==VolSize) or finished. + the function doesn't use VolSize and it uses s.RealSize instead. + it returns true : if stream is restricted, and we can't close that stream + it returns false : if there is no restriction, and we can close that stream + Note: (RealSize == 0) (empty volume) on restriction bounds are supposed as non-restricted +*/ +bool CMultiOutStream::IsRestricted(const CVolStream &s) const +{ + if (s.Start < _restrict_Global) + return true; + if (_restrict_Begin == _restrict_End) + return false; + if (_restrict_Begin <= s.Start) + return _restrict_End > s.Start; + return _restrict_Begin < s.Start + s.RealSize; +} + +/* +// this function check also _length and volSize +bool CMultiOutStream::IsRestricted_for_Close(unsigned index) const +{ + const CVolStream &s = Streams[index]; + if (_length <= s.Start) // we don't close streams after the end, because we still can write them later + return true; + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + return IsRestricted_Empty(s); + if (_length - s.Start < volSize) + return true; + return IsRestricted(s); +} +*/ + +FString CMultiOutStream::GetFilePath(unsigned index) +{ + FString name; + name.Add_UInt32((UInt32)(index + 1)); + while (name.Len() < 3) + name.InsertAtFront(FTEXT('0')); + name.Insert(0, Prefix); + return name; +} + + +// we close stream, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream(unsigned index) +{ + CVolStream &s = Streams[index]; + if (s.Stream) + { + RINOK(s.StreamSpec->Close()) + // the following two commands must be called together: + s.Stream.Release(); + RemoveFromLinkedList(index); + } + return S_OK; +} + + +// we close stream and delete file, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream_and_DeleteFile(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_AndDelete \n", index)) + RINOK(CloseStream(index)) + FString path = GetFilePath(index); + path += Streams[index].Postfix; + // we can checki that file exist + // if (NFind::DoesFileExist_Raw(path)) + if (!DeleteFileAlways(path)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + + +HRESULT CMultiOutStream::CloseStream_and_FinalRename(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_and_FinalRename \n", index)) + CVolStream &s = Streams[index]; + // HRESULT res = S_OK; + bool mtime_WasSet = false; + if (MTime_Defined && s.Stream) + { + if (s.StreamSpec->SetMTime(&MTime)) + mtime_WasSet = true; + // else res = GetLastError_noZero_HRESULT(); + } + + RINOK(CloseStream(index)) + if (s.Postfix.IsEmpty()) // if Postfix is empty, the path is already final + return S_OK; + const FString path = GetFilePath(index); + FString tempPath = path; + tempPath += s.Postfix; + + if (MTime_Defined && !mtime_WasSet) + { + if (!SetDirTime(tempPath, NULL, NULL, &MTime)) + { + // res = GetLastError_noZero_HRESULT(); + } + } + if (!MyMoveFile(tempPath, path)) + return GetLastError_noZero_HRESULT(); + /* we clear CVolStream::Postfix. So we will not use Temp path + anymore for this stream, and we will work only with final path */ + s.Postfix.Empty(); + // we can ignore set_mtime error or we can return it + return S_OK; + // return res; +} + + +HRESULT CMultiOutStream::PrepareToOpenNew() +{ + PRF(printf("PrepareToOpenNew NumListItems =%u, NumOpenFiles_AllowedMax = %u \n", NumListItems, NumOpenFiles_AllowedMax)) + + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + /* when we create zip archive: in most cases we need only starting + data of restricted region for rewriting zip's local header. + So here we close latest created volume (from Head), and we try to + keep oldest volumes that will be used for header rewriting later. */ + const int index = Head; + if (index == -1) + return E_FAIL; + PRF(printf("\n== %u, PrepareToOpenNew::CloseStream, NumListItems =%u \n", index, NumListItems)) + /* we don't expect non-restricted stream here in normal cases (if _restrict_Global was not changed). + if there was non-restricted stream, it should be closed before */ + // if (!IsRestricted_for_Close(index)) return CloseStream_and_FinalRename(index); + return CloseStream((unsigned)index); +} + + +HRESULT CMultiOutStream::CreateNewStream(UInt64 newSize) +{ + PRF(printf("\n== %u, CreateNewStream, size =%u \n", Streams.Size(), (unsigned)newSize)) + + if (Streams.Size() >= k_NumVols_MAX) + return E_INVALIDARG; // E_OUTOFMEMORY + + RINOK(PrepareToOpenNew()) + CVolStream s; + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + const FString path = GetFilePath(Streams.Size()); + + if (NFind::DoesFileExist_Raw(path)) + return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + if (!CreateTempFile2(path, false, s.Postfix, &s.StreamSpec->File)) + return GetLastError_noZero_HRESULT(); + + s.Start = GetGlobalOffset_for_NewStream(); + s.Pos = 0; + s.RealSize = 0; + + const unsigned index = Streams.Add(s); + InsertToLinkedList(index); + + if (newSize != 0) + return s.SetSize2(newSize); + return S_OK; +} + + +HRESULT CMultiOutStream::CreateStreams_If_Required(unsigned streamIndex) +{ + // UInt64 lastStreamSize = 0; + for (;;) + { + const unsigned numStreamsBefore = Streams.Size(); + if (streamIndex < numStreamsBefore) + return S_OK; + UInt64 newSize; + if (streamIndex == numStreamsBefore) + { + // it's final volume that will be used for real writing. + /* SetSize(_offsetPos) is not required, + because the file Size will be set later by calling Seek() with Write() */ + newSize = 0; // lastStreamSize; + } + else + { + // it's intermediate volume. So we need full volume size + newSize = GetVolSize_for_Stream(numStreamsBefore); + } + + RINOK(CreateNewStream(newSize)) + + // optional check + if (numStreamsBefore + 1 != Streams.Size()) return E_FAIL; + + if (streamIndex != numStreamsBefore) + { + // it's intermediate volume. So we can close it, if it's non-restricted + bool isRestricted; + { + const CVolStream &s = Streams[numStreamsBefore]; + if (newSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + } + if (!isRestricted) + { + RINOK(CloseStream_and_FinalRename(numStreamsBefore)) + } + } + } +} + + +HRESULT CMultiOutStream::ReOpenStream(unsigned streamIndex) +{ + PRF(printf("\n====== %u, ReOpenStream \n", streamIndex)) + RINOK(PrepareToOpenNew()) + CVolStream &s = Streams[streamIndex]; + + FString path = GetFilePath(streamIndex); + path += s.Postfix; + + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + s.Pos = 0; + + HRESULT hres; + if (s.StreamSpec->Open_EXISTING(path)) + { + if (s.Postfix.IsEmpty()) + { + /* it's unexpected case that we open finished volume. + It can mean that the code for restriction is incorrect */ + FinalVol_WasReopen = true; + } + UInt64 realSize = 0; + hres = s.StreamSpec->GetSize(&realSize); + if (hres == S_OK) + { + if (realSize == s.RealSize) + { + PRF(printf("\n ReOpenStream OK realSize = %u\n", (unsigned)realSize)) + InsertToLinkedList(streamIndex); + return S_OK; + } + // file size was changed between Close() and ReOpen() + // we must release Stream to be consistent with linked list + hres = E_FAIL; + } + } + else + hres = GetLastError_noZero_HRESULT(); + s.Stream.Release(); + s.StreamSpec = NULL; + return hres; +} + + +/* Sets size of stream, if new size is not equal to old size (RealSize). + If stream was closed and size change is required, it reopens the stream. */ + +HRESULT CMultiOutStream::OptReOpen_and_SetSize(unsigned index, UInt64 size) +{ + CVolStream &s = Streams[index]; + if (size == s.RealSize) + return S_OK; + if (!s.Stream) + { + RINOK(ReOpenStream(index)) + } + PRF(printf("\n== %u, OptReOpen_and_SetSize, size =%u RealSize = %u\n", index, (unsigned)size, (unsigned)s.RealSize)) + // comment it to debug tail after data + return s.SetSize2(size); +} + + +/* +call Normalize_finalMode(false), if _length was changed. + for all streams starting after _length: + - it sets zero size + - it still keeps file open + Note: after _length reducing with CMultiOutStream::SetSize() we can + have very big number of empty streams at the end of Streams[] list. + And Normalize_finalMode() will runs all these empty streams of Streams[] vector. + So it can be ineffective, if we call Normalize_finalMode() many + times after big reducing of (_length). + +call Normalize_finalMode(true) to set final presentations of all streams + for all streams starting after _length: + - it sets zero size + - it removes file + - it removes CVolStream object from Streams[] vector + +Note: we don't remove zero sized first volume, if (_length == 0) +*/ + +HRESULT CMultiOutStream::Normalize_finalMode(bool finalMode) +{ + PRF(printf("\n== Normalize_finalMode: _length =%d \n", (unsigned)_length)) + + unsigned i = Streams.Size(); + + UInt64 offset = 0; + + /* At first we normalize (reduce or increase) the sizes of all existing + streams in Streams[] that can be affected by changed _length. + And we remove tailing zero-size streams, if (finalMode == true) */ + while (i != 0) + { + offset = Streams[--i].Start; // it's last item in Streams[] + // we don't want to remove first volume + if (offset < _length || i == 0) + { + const UInt64 volSize = GetVolSize_for_Stream(i); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(OptReOpen_and_SetSize(i, size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize + offset += volSize; + // _length > offset + break; + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, size)); + } + + /* we Set Size of stream to zero even for (finalMode==true), although + that stream will be deleted in next commands */ + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, 0)); + RINOK(OptReOpen_and_SetSize(i, 0)) + if (finalMode) + { + RINOK(CloseStream_and_DeleteFile(i)) + /* CVolStream::Stream was released above already, and it was + removed from linked list. So we don't need to update linked list + structure, when we delete last item in Streams[] */ + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + } + + /* now we create new zero-filled streams to cover all data up to _length */ + + if (_length == 0) + return S_OK; + + // (offset) is start offset of next stream after existing Streams[] + + for (;;) + { + // _length > offset + const UInt64 volSize = GetVolSize_for_Stream(Streams.Size()); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(CreateNewStream(size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize) + offset += volSize; + // _length > offset + } +} + + +HRESULT CMultiOutStream::FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes) +{ + // at first we remove unused zero-sized streams after _length + HRESULT res = Normalize_finalMode(true); + numTotalVolumesRes = Streams.Size(); + FOR_VECTOR (i, Streams) + { + const HRESULT res2 = CloseStream_and_FinalRename(i); + if (res == S_OK) + res = res2; + } + if (NumListItems != 0 && res == S_OK) + res = E_FAIL; + return res; +} + + +bool CMultiOutStream::SetMTime_Final(const CFiTime &mTime) +{ + // we will set mtime only if new value differs from previous + if (!FinalVol_WasReopen && MTime_Defined && Compare_FiTime(&MTime, &mTime) == 0) + return true; + bool res = true; + FOR_VECTOR (i, Streams) + { + CVolStream &s = Streams[i]; + if (s.Stream) + { + if (!s.StreamSpec->SetMTime(&mTime)) + res = false; + } + else + { + if (!SetDirTime(GetFilePath(i), NULL, NULL, &mTime)) + res = false; + } + } + return res; +} + + +Z7_COM7F_IMF(CMultiOutStream::SetSize(UInt64 newSize)) +{ + COM_TRY_BEGIN + if ((Int64)newSize < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (newSize > _absLimit) + { + /* big seek value was sent to SetSize() or to Seek()+Write(). + It can mean one of two situations: + 1) some incorrect code called it with big seek value. + 2) volume size was small, and we have too big number of volumes + */ + /* in Windows SetEndOfFile() can return: + ERROR_NEGATIVE_SEEK: for >= (1 << 63) + ERROR_INVALID_PARAMETER: for > (16 TiB - 64 KiB) + ERROR_DISK_FULL: for <= (16 TiB - 64 KiB) + */ + // return E_FAIL; + // return E_OUTOFMEMORY; + return E_INVALIDARG; + } + + if (newSize > _length) + { + // we don't expect such case. So we just define global restriction */ + _restrict_Global = newSize; + } + else if (newSize < _restrict_Global) + _restrict_Global = newSize; + + PRF(printf("\n== CMultiOutStream::SetSize, size =%u \n", (unsigned)newSize)) + + _length = newSize; + return Normalize_finalMode(false); + + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + PRF(printf("\n -- CMultiOutStream::Write() : _absPos = %6u, size =%6u \n", + (unsigned)_absPos, (unsigned)size)) + + if (_absPos > _length) + { + // it create data only up to _absPos. + // but we still can need additional new streams, if _absPos at range of volume + RINOK(SetSize(_absPos)) + } + + while (size != 0) + { + UInt64 volSize; + { + if (_streamIndex < Sizes.Size() - 1) + { + volSize = Sizes[_streamIndex]; + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + } + else + { + volSize = Sizes[Sizes.Size() - 1]; + if (_offsetPos >= volSize) + { + const UInt64 v = _offsetPos / volSize; + if (v >= ((UInt32)(Int32)-1) - _streamIndex) + return E_INVALIDARG; + // throw 202208; + _streamIndex += (unsigned)v; + _offsetPos -= (unsigned)v * volSize; + } + if (_streamIndex >= k_NumVols_MAX) + return E_INVALIDARG; + } + } + + // (_offsetPos < volSize) here + + /* we can need to create one or more streams here, + vol_size for some streams is allowed to be 0. + Also we close some new created streams, if they are non-restricted */ + // file Size will be set later by calling Seek() with Write() + + /* the case (_absPos > _length) was processed above with SetSize(_absPos), + so here it's expected. that we can create optional zero-size streams and then _streamIndex */ + RINOK(CreateStreams_If_Required(_streamIndex)) + + CVolStream &s = Streams[_streamIndex]; + + PRF(printf("\n%d, == Write : Pos = %u, RealSize = %u size =%u \n", + _streamIndex, (unsigned)s.Pos, (unsigned)s.RealSize, size)) + + if (!s.Stream) + { + RINOK(ReOpenStream(_streamIndex)) + } + if (_offsetPos != s.Pos) + { + RINOK(s.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) + s.Pos = _offsetPos; + } + + UInt32 curSize = size; + { + const UInt64 rem = volSize - _offsetPos; + if (curSize > rem) + curSize = (UInt32)rem; + } + // curSize != 0 + UInt32 realProcessed = 0; + + HRESULT hres = s.Stream->Write(data, curSize, &realProcessed); + + data = (const void *)((const Byte *)data + realProcessed); + size -= realProcessed; + s.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_length < _absPos) + _length = _absPos; + if (s.RealSize < _offsetPos) + s.RealSize = _offsetPos; + if (processedSize) + *processedSize += realProcessed; + + if (s.Pos == volSize) + { + bool isRestricted; + if (volSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + if (!isRestricted) + { + const HRESULT res2 = CloseStream_and_FinalRename(_streamIndex); + if (hres == S_OK) + hres = res2; + } + _streamIndex++; + _offsetPos = 0; + } + + RINOK(hres) + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + // break; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + PRF(printf("\n-- CMultiOutStream::Seek seekOrigin=%u Seek =%u\n", seekOrigin, (unsigned)offset)) + + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _absPos; break; + case STREAM_SEEK_END: offset += _length; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if ((UInt64)offset != _absPos) + { + _absPos = (UInt64)offset; + _offsetPos = (UInt64)offset; + _streamIndex = 0; + } + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +// result value will be saturated to (UInt32)(Int32)-1 + +unsigned CMultiOutStream::GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const +{ + const unsigned last = Sizes.Size() - 1; + for (unsigned i = 0; i < last; i++) + { + const UInt64 size = Sizes[i]; + if (offset < size) + { + relOffset = offset; + return i; + } + offset -= size; + } + const UInt64 size = Sizes[last]; + const UInt64 v = offset / size; + if (v >= ((UInt32)(Int32)-1) - last) + return (unsigned)(int)-1; // saturation + relOffset = offset - (unsigned)v * size; + return last + (unsigned)(v); +} + + +Z7_COM7F_IMF(CMultiOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + COM_TRY_BEGIN + + // begin = end = 0; // for debug + + PRF(printf("\n==================== CMultiOutStream::SetRestriction %u, %u\n", (unsigned)begin, (unsigned)end)) + if (begin > end) + { + // these value are FAILED values. + return E_FAIL; + // return E_INVALIDARG; + /* + // or we can ignore error with 3 ways: no change, non-restricted, saturation: + end = begin; // non-restricted + end = (UInt64)(Int64)-1; // saturation: + return S_OK; + */ + } + UInt64 b = _restrict_Begin; + UInt64 e = _restrict_End; + _restrict_Begin = begin; + _restrict_End = end; + + if (b == e) // if there were no restriction before + return S_OK; // no work to derestrict now. + + /* [b, e) is previous restricted region. So all volumes that + intersect that [b, e) region are candidats for derestriction */ + + if (begin != end) // if there is new non-empty restricted region + { + /* Now we will try to reduce or change (b) and (e) bounds + to reduce main loop that checks volumes for derestriction. + We still use one big derestriction region in main loop, although + in some cases we could have two smaller derestriction regions. + Also usually restriction region cannot move back from previous start position, + so (b <= begin) is expected here for normal cases */ + if (b == begin) // if same low bounds + b = end; // we need to derestrict only after the end of new restricted region + if (e == end) // if same high bounds + e = begin; // we need to derestrict only before the begin of new restricted region + } + + if (b > e) // || b == (UInt64)(Int64)-1 + return S_OK; + + /* Here we close finished volumes that are not restricted anymore. + We close (low number) volumes at first. */ + + UInt64 offset; + unsigned index = GetStreamIndex_for_Offset(b, offset); + + for (; index < Streams.Size(); index++) + { + { + const CVolStream &s = Streams[index]; + if (_length <= s.Start) + break; // we don't close streams after _length + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + { + if (e < s.Start) + break; + // we don't close empty stream, if next byte [s.Start, s.Start] is restricted + if (IsRestricted_Empty(s)) + continue; + } + else + { + if (e <= s.Start) + break; + // we don't close non full streams + if (_length - s.Start < volSize) + break; + // (volSize == s.RealSize) is expected here. So no need to check it + // if (volSize != s.RealSize) break; + if (IsRestricted(s)) + continue; + } + } + RINOK(CloseStream_and_FinalRename(index)) + } + + return S_OK; + COM_TRY_END +} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/MultiOutStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.h --- 7zip-22.01+dfsg/CPP/7zip/Common/MultiOutStream.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/MultiOutStream.h 2023-04-05 17:00:00.000000000 +0000 @@ -0,0 +1,160 @@ +// MultiOutStream.h + +#ifndef ZIP7_INC_MULTI_OUT_STREAM_H +#define ZIP7_INC_MULTI_OUT_STREAM_H + +#include "FileStreams.h" + +Z7_CLASS_IMP_COM_2( + CMultiOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + Z7_CLASS_NO_COPY(CMultiOutStream) + + struct CVolStream + { + COutFileStream *StreamSpec; + CMyComPtr Stream; + UInt64 Start; // start pos of current Stream in global stream + UInt64 Pos; // pos in current Stream + UInt64 RealSize; + int Next; // next older + int Prev; // prev newer + AString Postfix; + + HRESULT SetSize2(UInt64 size) + { + const HRESULT res = Stream->SetSize(size); + if (res == SZ_OK) + RealSize = size; + return res; + } + }; + + unsigned _streamIndex; // (_streamIndex >= Stream.Size()) is allowed in some internal code + UInt64 _offsetPos; // offset relative to Streams[_streamIndex] volume. (_offsetPos >= volSize is allowed) + UInt64 _absPos; + UInt64 _length; // virtual Length + UInt64 _absLimit; + + CObjectVector Streams; + CRecordVector Sizes; + + UInt64 _restrict_Begin; + UInt64 _restrict_End; + UInt64 _restrict_Global; + + unsigned NumOpenFiles_AllowedMax; + + // ----- Double Linked List ----- + + unsigned NumListItems; + int Head; // newest + int Tail; // oldest + + void InitLinkedList() + { + Head = -1; + Tail = -1; + NumListItems = 0; + } + + void InsertToLinkedList(unsigned index) + { + { + CVolStream &node = Streams[index]; + node.Next = Head; + node.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; + } + + void RemoveFromLinkedList(unsigned index) + { + CVolStream &s = Streams[index]; + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; + } + + /* + void Delete_LastStream_Records() + { + if (Streams.Back().Stream) + RemoveFromLinkedList(Streams.Size() - 1); + Streams.DeleteBack(); + } + */ + + UInt64 GetVolSize_for_Stream(unsigned i) const + { + const unsigned last = Sizes.Size() - 1; + return Sizes[i < last ? i : last]; + } + UInt64 GetGlobalOffset_for_NewStream() const + { + return Streams.Size() == 0 ? 0: + Streams.Back().Start + + GetVolSize_for_Stream(Streams.Size() - 1); + } + unsigned GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const; + bool IsRestricted(const CVolStream &s) const; + bool IsRestricted_Empty(const CVolStream &s) const + { + // (s) must be stream that has (VolSize == 0). + // we treat empty stream as restricted, if next byte is restricted. + if (s.Start < _restrict_Global) + return true; + return + (_restrict_Begin != _restrict_End) + && (_restrict_Begin <= s.Start) + && (_restrict_Begin == s.Start || _restrict_End > s.Start); + } + // bool IsRestricted_for_Close(unsigned index) const; + FString GetFilePath(unsigned index); + + HRESULT CloseStream(unsigned index); + HRESULT CloseStream_and_DeleteFile(unsigned index); + HRESULT CloseStream_and_FinalRename(unsigned index); + + HRESULT PrepareToOpenNew(); + HRESULT CreateNewStream(UInt64 newSize); + HRESULT CreateStreams_If_Required(unsigned streamIndex); + HRESULT ReOpenStream(unsigned streamIndex); + HRESULT OptReOpen_and_SetSize(unsigned index, UInt64 size); + + HRESULT Normalize_finalMode(bool finalMode); +public: + FString Prefix; + CFiTime MTime; + bool MTime_Defined; + bool FinalVol_WasReopen; + bool NeedDelete; + + CMultiOutStream() {} + ~CMultiOutStream(); + void Init(const CRecordVector &sizes); + bool SetMTime_Final(const CFiTime &mTime); + UInt64 GetSize() const { return _length; } + /* it makes final flushing, closes open files and renames to final name if required + but it still keeps Streams array of all closed files. + So we still can delete all files later, if required */ + HRESULT FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes); + // Destruct object without exceptions + HRESULT Destruct(); +}; + +#endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OffsetStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/OffsetStream.cpp 2021-05-08 09:24:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../../Common/Defs.h" - #include "OffsetStream.h" HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) @@ -13,12 +11,12 @@ return _stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } -STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _stream->Write(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin == STREAM_SEEK_SET) { @@ -27,13 +25,13 @@ offset += _offset; } UInt64 absoluteNewPosition = 0; // =0 for gcc-10 - HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + const HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); if (newPosition) *newPosition = absoluteNewPosition - _offset; return result; } -STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COffsetOutStream::SetSize(UInt64 newSize)) { return _stream->SetSize(_offset + newSize); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OffsetStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.h --- 7zip-22.01+dfsg/CPP/7zip/Common/OffsetStream.h 2013-01-17 08:06:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OffsetStream.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,26 +1,22 @@ // OffsetStream.h -#ifndef __OFFSET_STREAM_H -#define __OFFSET_STREAM_H +#ifndef ZIP7_INC_OFFSET_STREAM_H +#define ZIP7_INC_OFFSET_STREAM_H #include "../../Common/MyCom.h" #include "../IStream.h" -class COffsetOutStream: - public IOutStream, - public CMyUnknownImp -{ - UInt64 _offset; +Z7_CLASS_IMP_NOQIB_1( + COffsetOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + CMyComPtr _stream; + UInt64 _offset; public: HRESULT Init(IOutStream *stream, UInt64 offset); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OutBuffer.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/OutBuffer.cpp 2014-12-30 19:15:44.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -11,18 +11,18 @@ const UInt32 kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_buf != 0 && _bufSize == bufSize) + if (_buf && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _buf = (Byte *)::MidAlloc(bufSize); - return (_buf != 0); + return (_buf != NULL); } void COutBuffer::Free() throw() { ::MidFree(_buf); - _buf = 0; + _buf = NULL; } void COutBuffer::Init() throw() @@ -32,7 +32,7 @@ _pos = 0; _processedSize = 0; _overDict = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif } @@ -51,17 +51,17 @@ // _streamPos < _bufSize UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); HRESULT result = S_OK; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS result = ErrorCode; #endif - if (_buf2 != 0) + if (_buf2) { memcpy(_buf2, _buf + _streamPos, size); _buf2 += size; } - if (_stream != 0 - #ifdef _NO_EXCEPTIONS + if (_stream + #ifdef Z7_NO_EXCEPTIONS && (ErrorCode == S_OK) #endif ) @@ -85,14 +85,14 @@ HRESULT COutBuffer::Flush() throw() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return ErrorCode; #endif while (_streamPos != _pos) { - HRESULT result = FlushPart(); + const HRESULT result = FlushPart(); if (result != S_OK) return result; } @@ -101,8 +101,8 @@ void COutBuffer::FlushWithCheck() { - HRESULT result = Flush(); - #ifdef _NO_EXCEPTIONS + const HRESULT result = Flush(); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OutBuffer.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.h --- 7zip-22.01+dfsg/CPP/7zip/Common/OutBuffer.h 2017-01-24 08:57:32.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutBuffer.h 2025-02-23 14:00:00.000000000 +0000 @@ -1,13 +1,13 @@ // OutBuffer.h -#ifndef __OUT_BUFFER_H -#define __OUT_BUFFER_H +#ifndef ZIP7_INC_OUT_BUFFER_H +#define ZIP7_INC_OUT_BUFFER_H #include "../IStream.h" #include "../../Common/MyCom.h" #include "../../Common/MyException.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct COutBufferException: public CSystemException { COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -29,11 +29,11 @@ HRESULT FlushPart() throw(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif - COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {} + COutBuffer(): _buf(NULL), _pos(0), _stream(NULL), _buf2(NULL) {} ~COutBuffer() { Free(); } bool Create(UInt32 bufSize) throw(); @@ -45,6 +45,7 @@ HRESULT Flush() throw(); void FlushWithCheck(); + Z7_FORCE_INLINE void WriteByte(Byte b) { UInt32 pos = _pos; @@ -54,11 +55,77 @@ if (pos == _limitPos) FlushWithCheck(); } + void WriteBytes(const void *data, size_t size) { - for (size_t i = 0; i < size; i++) - WriteByte(((const Byte *)data)[i]); + while (size) + { + UInt32 pos = _pos; + size_t cur = (size_t)(_limitPos - pos); + if (cur >= size) + cur = size; + size -= cur; + Byte *dest = _buf + pos; + pos += (UInt32)cur; + _pos = pos; +#if 0 + memcpy(dest, data, cur); + data = (const void *)((const Byte *)data + cur); +#else + const Byte * const lim = (const Byte *)data + cur; + do + { + *dest++ = *(const Byte *)data; + data = (const void *)((const Byte *)data + 1); + } + while (data != lim); +#endif + if (pos == _limitPos) + FlushWithCheck(); + } + } + + Byte *GetOutBuffer(size_t &avail) + { + const UInt32 pos = _pos; + avail = (size_t)(_limitPos - pos); + return _buf + pos; + } + + void SkipWrittenBytes(size_t num) + { + const UInt32 pos = _pos; + const UInt32 rem = _limitPos - pos; + if (rem > num) + { + _pos = pos + (UInt32)num; + return; + } + // (rem <= num) + // the caller must not call it with (rem < num) + // so (rem == num) + _pos = _limitPos; + FlushWithCheck(); + } + /* + void WriteBytesBig(const void *data, size_t size) + { + while (size) + { + UInt32 pos = _pos; + UInt32 rem = _limitPos - pos; + if (rem > size) + { + _pos = pos + size; + memcpy(_buf + pos, data, size); + return; + } + memcpy(_buf + pos, data, rem); + _pos = pos + rem; + FlushWithCheck(); + } } + */ UInt64 GetProcessedSize() const throw(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OutMemStream.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/OutMemStream.cpp 2021-04-01 12:11:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -31,13 +31,13 @@ HRESULT COutMemStream::WriteToRealStream() { - RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); + RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)) Blocks.Free(_memManager); return S_OK; } -STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (_realStreamMode) return OutSeqStream->Write(data, size, processedSize); @@ -58,7 +58,7 @@ size -= (UInt32)curSize; _curBlockPos += curSize; - UInt64 pos64 = GetPos(); + const UInt64 pos64 = GetPos(); if (pos64 > Blocks.TotalSize) Blocks.TotalSize = pos64; if (_curBlockPos == _memManager->GetBlockSize()) @@ -83,9 +83,9 @@ case (WAIT_OBJECT_0 + 1): { _realStreamMode = true; - RINOK(WriteToRealStream()); + RINOK(WriteToRealStream()) UInt32 processedSize2; - HRESULT res = OutSeqStream->Write(data, size, &processedSize2); + const HRESULT res = OutSeqStream->Write(data, size, &processedSize2); if (processedSize) *processedSize += processedSize2; return res; @@ -103,7 +103,7 @@ { if (waitResult == WAIT_FAILED) { - DWORD res = ::GetLastError(); + const DWORD res = ::GetLastError(); if (res != 0) return HRESULT_FROM_WIN32(res); } @@ -118,7 +118,7 @@ return S_OK; } -STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (_realStreamMode) { @@ -145,7 +145,7 @@ return S_OK; } -STDMETHODIMP COutMemStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COutMemStream::SetSize(UInt64 newSize)) { if (_realStreamMode) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/OutMemStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.h --- 7zip-22.01+dfsg/CPP/7zip/Common/OutMemStream.h 2020-10-14 17:36:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/OutMemStream.h 2023-09-06 10:00:00.000000000 +0000 @@ -1,19 +1,21 @@ // OutMemStream.h -#ifndef __OUT_MEM_STREAM_H -#define __OUT_MEM_STREAM_H +#ifndef ZIP7_INC_OUT_MEM_STREAM_H +#define ZIP7_INC_OUT_MEM_STREAM_H #include "../../Common/MyCom.h" #include "MemBlocks.h" -class COutMemStream: - public IOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutMemStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + CMemBlockManagerMt *_memManager; - unsigned _curBlockIndex; size_t _curBlockPos; + unsigned _curBlockIndex; bool _realStreamMode; bool _unlockEventWasSent; @@ -24,15 +26,14 @@ HRESULT StopWriteResult; CMemLockBlocks Blocks; - UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } - CMyComPtr OutSeqStream; CMyComPtr OutStream; + UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } + public: - - HRes CreateEvents(SYNC_PARAM_DECL(synchro)) + HRESULT CreateEvents(SYNC_PARAM_DECL(synchro)) { WRes wres = StopWritingEvent.CreateIfNotCreated_Reset(SYNC_WFMO(synchro)); if (wres == 0) @@ -98,12 +99,6 @@ StopWriteResult = res; StopWritingEvent.Set(); } - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/ProgressMt.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/ProgressMt.cpp 2021-01-24 15:59:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -31,13 +31,13 @@ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); if (inSize) { - UInt64 diff = *inSize - InSizes[index]; + const UInt64 diff = *inSize - InSizes[index]; InSizes[index] = *inSize; TotalInSize += diff; } if (outSize) { - UInt64 diff = *outSize - OutSizes[index]; + const UInt64 diff = *outSize - OutSizes[index]; OutSizes[index] = *outSize; TotalOutSize += diff; } @@ -47,7 +47,7 @@ } -STDMETHODIMP CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { return _progress->SetRatioInfo(_index, inSize, outSize); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/ProgressMt.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.h --- 7zip-22.01+dfsg/CPP/7zip/Common/ProgressMt.h 2021-01-24 15:59:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressMt.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ProgressMt.h -#ifndef __PROGRESSMT_H -#define __PROGRESSMT_H +#ifndef ZIP7_INC_PROGRESSMT_H +#define ZIP7_INC_PROGRESSMT_H #include "../../Common/MyCom.h" #include "../../Common/MyVector.h" @@ -24,12 +24,13 @@ HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize); }; -class CMtCompressProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMtCompressProgressMixer *_progress; + +Z7_CLASS_IMP_NOQIB_1( + CMtCompressProgress + , ICompressProgressInfo +) unsigned _index; + CMtCompressProgressMixer *_progress; public: void Init(CMtCompressProgressMixer *progress, unsigned index) { @@ -37,10 +38,6 @@ _index = index; } void Reinit() { _progress->Reinit(_index); } - - MY_UNKNOWN_IMP - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/ProgressUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/ProgressUtils.cpp 2015-02-13 07:34:31.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -5,11 +5,11 @@ #include "ProgressUtils.h" CLocalProgress::CLocalProgress(): + SendRatio(true), + SendProgress(true), ProgressOffset(0), InSize(0), - OutSize(0), - SendRatio(true), - SendProgress(true) + OutSize(0) {} void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) @@ -20,7 +20,7 @@ _inSizeIsMain = inSizeIsMain; } -STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { UInt64 inSize2 = InSize; UInt64 outSize2 = OutSize; @@ -32,7 +32,7 @@ if (SendRatio && _ratioProgress) { - RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)); + RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)) } if (SendProgress) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/ProgressUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.h --- 7zip-22.01+dfsg/CPP/7zip/Common/ProgressUtils.h 2015-02-13 07:34:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/ProgressUtils.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,35 +1,33 @@ // ProgressUtils.h -#ifndef __PROGRESS_UTILS_H -#define __PROGRESS_UTILS_H +#ifndef ZIP7_INC_PROGRESS_UTILS_H +#define ZIP7_INC_PROGRESS_UTILS_H #include "../../Common/MyCom.h" #include "../ICoder.h" #include "../IProgress.h" -class CLocalProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLocalProgress + , ICompressProgressInfo +) +public: + bool SendRatio; + bool SendProgress; +private: + bool _inSizeIsMain; CMyComPtr _progress; CMyComPtr _ratioProgress; - bool _inSizeIsMain; public: UInt64 ProgressOffset; UInt64 InSize; UInt64 OutSize; - bool SendRatio; - bool SendProgress; CLocalProgress(); void Init(IProgress *progress, bool inSizeIsMain); HRESULT SetCur(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/PropId.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/PropId.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/PropId.cpp 2022-05-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/PropId.cpp 2022-11-05 14:00:00.000000000 +0000 @@ -111,5 +111,7 @@ VT_UI4, VT_UI4, VT_UI4, - VT_UI4 // kpidDeviceMinor + VT_UI4, + VT_UI4, + VT_UI4 // kpidDevMinor }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/RegisterArc.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterArc.h --- 7zip-22.01+dfsg/CPP/7zip/Common/RegisterArc.h 2022-05-18 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterArc.h 2023-03-06 16:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RegisterArc.h -#ifndef __REGISTER_ARC_H -#define __REGISTER_ARC_H +#ifndef ZIP7_INC_REGISTER_ARC_H +#define ZIP7_INC_REGISTER_ARC_H #include "../Archive/IArchive.h" @@ -34,7 +34,7 @@ #define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler()) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define IMP_CreateArcOut #define CreateArcOut NULL #else @@ -52,7 +52,7 @@ #define REGISTER_ARC_I_CLS(cls, n, e, ae, id, sig, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, 0, CreateArc, NULL, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, 0, CreateArc, NULL, isArc) #define REGISTER_ARC_I_CLS_NO_SIG(cls, n, e, ae, id, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ @@ -68,12 +68,12 @@ #define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) #define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_V(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) \ + REGISTER_ARC_V(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) \ struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \ static CRegisterArcDecSig g_RegisterArc; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/RegisterCodec.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterCodec.h --- 7zip-22.01+dfsg/CPP/7zip/Common/RegisterCodec.h 2019-08-28 14:41:07.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/RegisterCodec.h 2023-03-06 16:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RegisterCodec.h -#ifndef __REGISTER_CODEC_H -#define __REGISTER_CODEC_H +#ifndef ZIP7_INC_REGISTER_CODEC_H +#define ZIP7_INC_REGISTER_CODEC_H #include "../Common/MethodId.h" @@ -37,7 +37,7 @@ #define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] = #define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \ - REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \ + REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CodecsInfo); i++) \ RegisterCodec(&g_CodecsInfo[i]); }}; \ static REGISTER_CODECS_NAME(x) g_RegisterCodecs; @@ -48,7 +48,7 @@ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ REGISTER_CODEC_CREATE(CreateDec, clsDec) \ REGISTER_CODEC_2(x, CreateDec, NULL, id, name) @@ -71,7 +71,7 @@ REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ REGISTER_FILTER(x, x ## _CreateDec, NULL, id, name) @@ -97,7 +97,7 @@ #define REGISTER_HASHER_NAME(x) CRegHasher_ ## x #define REGISTER_HASHER(cls, id, name, size) \ - STDMETHODIMP_(UInt32) cls::GetDigestSize() throw() { return size; } \ + Z7_COM7F_IMF2(UInt32, cls::GetDigestSize()) { return size; } \ static IHasher *CreateHasherSpec() { return new cls(); } \ static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Common/StdAfx.h 2013-11-24 12:55:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamBinder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamBinder.cpp 2021-06-05 11:25:17.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -6,51 +6,44 @@ #include "StreamBinder.h" -class CBinderInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CBinderInStream + , ISequentialInStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); ~CBinderInStream() { _binder->CloseRead_CallOnce(); } CBinderInStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Read(data, size, processedSize); } -class CBinderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CBinderOutStream + , ISequentialOutStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); ~CBinderOutStream() { _binder->CloseWrite(); } CBinderOutStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Write(data, size, processedSize); } -static HRESULT Event__Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event) +static HRESULT Event_Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event) { - WRes wres; - if (event.IsCreated()) - wres = event.Reset(); - else - wres = event.Create(); + const WRes wres = event.CreateIfNotCreated_Reset(); return HRESULT_FROM_WIN32(wres); } HRESULT CStreamBinder::Create_ReInit() { - RINOK(Event__Create_or_Reset(_canRead_Event)); - // RINOK(Event__Create_or_Reset(_canWrite_Event)); + RINOK(Event_Create_or_Reset(_canRead_Event)) + // RINOK(Event_Create_or_Reset(_canWrite_Event)) // _canWrite_Semaphore.Close(); // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamBinder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.h --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamBinder.h 2020-11-27 11:36:31.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamBinder.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // StreamBinder.h -#ifndef __STREAM_BINDER_H -#define __STREAM_BINDER_H +#ifndef ZIP7_INC_STREAM_BINDER_H +#define ZIP7_INC_STREAM_BINDER_H #include "../../Windows/Synchronization.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamObjects.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamObjects.cpp 2021-01-24 16:05:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -2,13 +2,11 @@ #include "StdAfx.h" -#include - #include "../../../C/Alloc.h" #include "StreamObjects.h" -STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -26,7 +24,7 @@ return S_OK; } -STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -43,7 +41,7 @@ return S_OK; } -STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -61,7 +59,7 @@ return S_OK; } -STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -99,8 +97,8 @@ void CByteDynBuffer::Free() throw() { - free(_buf); - _buf = 0; + MyFree(_buf); + _buf = NULL; _capacity = 0; } @@ -108,11 +106,10 @@ { if (cap <= _capacity) return true; - size_t delta = _capacity / 4; - size_t cap2 = _capacity + delta; + const size_t cap2 = _capacity + _capacity / 4; if (cap < cap2) cap = cap2; - Byte *buf = (Byte *)realloc(_buf, cap); + Byte *buf = (Byte *)MyRealloc(_buf, cap); if (!buf) return false; _buf = buf; @@ -135,7 +132,7 @@ dest.CopyFrom((const Byte *)_buffer, _size); } -STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -151,7 +148,7 @@ return S_OK; } -STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t rem = _size - _pos; if (rem > size) @@ -166,7 +163,7 @@ return (rem != 0 || size == 0) ? S_OK : E_FAIL; } -STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize; HRESULT result = _stream->Write(data, size, &realProcessedSize); @@ -216,12 +213,12 @@ { _size = size; _pos = 0; - size_t numBlocks = (size_t)1 << _numBlocksLog; + const size_t numBlocks = (size_t)1 << _numBlocksLog; for (size_t i = 0; i < numBlocks; i++) _tags[i] = kEmptyTag; } -STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -231,7 +228,7 @@ return S_OK; { - UInt64 rem = _size - _pos; + const UInt64 rem = _size - _pos; if (size > rem) size = (UInt32)rem; } @@ -245,12 +242,12 @@ if (_tags[cacheIndex] != cacheTag) { _tags[cacheIndex] = kEmptyTag; - UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); + const UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); size_t blockSize = (size_t)1 << _blockSizeLog; if (blockSize > remInBlock) blockSize = (size_t)remInBlock; - RINOK(ReadBlock(cacheTag, p, blockSize)); + RINOK(ReadBlock(cacheTag, p, blockSize)) _tags[cacheIndex] = cacheTag; } @@ -275,7 +272,7 @@ } -STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamObjects.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.h --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamObjects.h 2019-08-27 18:12:44.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamObjects.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // StreamObjects.h -#ifndef __STREAM_OBJECTS_H -#define __STREAM_OBJECTS_H +#ifndef ZIP7_INC_STREAM_OBJECTS_H +#define ZIP7_INC_STREAM_OBJECTS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -9,35 +9,27 @@ #include "../IStream.h" -class CBufferInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CBufferInStream +) UInt64 _pos; public: CByteBuffer Buf; void Init() { _pos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; -struct CReferenceBuf: - public IUnknown, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_0( + CReferenceBuf +) +public: CByteBuffer Buf; - MY_UNKNOWN_IMP }; -class CBufInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CBufInStream +) const Byte *_data; UInt64 _pos; size_t _size; @@ -52,9 +44,8 @@ } void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + // Seek() is allowed here. So reading order could be changed + bool WasFinished() const { return _pos == _size; } }; @@ -64,13 +55,13 @@ { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); } -class CByteDynBuffer +class CByteDynBuffer Z7_final { size_t _capacity; Byte *_buf; - CLASS_NO_COPY(CByteDynBuffer); + Z7_CLASS_NO_COPY(CByteDynBuffer) public: - CByteDynBuffer(): _capacity(0), _buf(NULL) {}; + CByteDynBuffer(): _capacity(0), _buf(NULL) {} // there is no copy constructor. So don't copy this object. ~CByteDynBuffer() { Free(); } void Free() throw(); @@ -81,10 +72,10 @@ }; -class CDynBufSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CDynBufSeqOutStream + , ISequentialOutStream +) CByteDynBuffer _buffer; size_t _size; public: @@ -95,16 +86,13 @@ void CopyToBuffer(CByteBuffer &dest) const; Byte *GetBufPtrForWriting(size_t addSize); void UpdateSize(size_t addSize) { _size += addSize; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CBufPtrSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CBufPtrSeqOutStream + , ISequentialOutStream +) Byte *_buffer; size_t _size; size_t _pos; @@ -116,25 +104,19 @@ _size = size; } size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CSequentialOutStreamSizeCount: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CSequentialOutStreamSizeCount + , ISequentialOutStream +) CMyComPtr _stream; UInt64 _size; public: void SetStream(ISequentialOutStream *stream) { _stream = stream; } void Init() { _size = 0; } UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; @@ -142,6 +124,8 @@ public IInStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) + UInt64 *_tags; Byte *_data; size_t _dataSize; @@ -153,14 +137,10 @@ virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; public: CCachedInStream(): _tags(NULL), _data(NULL) {} - virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!! + virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (Release() calls it) !!! void Free() throw(); bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); void Init(UInt64 size) throw(); - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamUtils.cpp 2014-08-08 11:40:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.cpp 2023-03-26 18:00:00.000000000 +0000 @@ -2,10 +2,55 @@ #include "StdAfx.h" +#include "../../Common/MyCom.h" + #include "StreamUtils.h" static const UInt32 kBlockSize = ((UInt32)1 << 31); + +HRESULT InStream_SeekToBegin(IInStream *stream) throw() +{ + return InStream_SeekSet(stream, 0); +} + + +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw() +{ +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekToBegin(stream); + return hres != S_OK ? hres : hres2; +} + + +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw() +{ + RINOK(InStream_GetPos(stream, curPosRes)) +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekSet(stream, curPosRes); + return hres != S_OK ? hres : hres2; +} + + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() { size_t size = *processedSize; @@ -18,7 +63,7 @@ *processedSize += processedSizeLoc; data = (void *)((Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return S_OK; } @@ -28,14 +73,14 @@ HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : S_FALSE; } HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : E_FAIL; } @@ -48,7 +93,7 @@ HRESULT res = stream->Write(data, curSize, &processedSizeLoc); data = (const void *)((const Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return E_FAIL; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/StreamUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.h --- 7zip-22.01+dfsg/CPP/7zip/Common/StreamUtils.h 2013-01-28 19:15:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/StreamUtils.h 2023-01-19 09:00:00.000000000 +0000 @@ -1,10 +1,28 @@ // StreamUtils.h -#ifndef __STREAM_UTILS_H -#define __STREAM_UTILS_H +#ifndef ZIP7_INC_STREAM_UTILS_H +#define ZIP7_INC_STREAM_UTILS_H #include "../IStream.h" +inline HRESULT InStream_SeekSet(IInStream *stream, UInt64 offset) throw() + { return stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } +inline HRESULT InStream_GetPos(IInStream *stream, UInt64 &curPosRes) throw() + { return stream->Seek(0, STREAM_SEEK_CUR, &curPosRes); } +inline HRESULT InStream_GetSize_SeekToEnd(IInStream *stream, UInt64 &sizeRes) throw() + { return stream->Seek(0, STREAM_SEEK_END, &sizeRes); } + +HRESULT InStream_SeekToBegin(IInStream *stream) throw(); +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &size) throw(); +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw(); + +inline HRESULT InStream_GetSize_SeekToBegin(IInStream *stream, UInt64 &sizeRes) throw() +{ + RINOK(InStream_SeekToBegin(stream)) + return InStream_AtBegin_GetSize(stream, sizeRes); +} + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw(); HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw(); HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/UniqBlocks.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/UniqBlocks.h --- 7zip-22.01+dfsg/CPP/7zip/Common/UniqBlocks.h 2022-04-02 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/UniqBlocks.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UniqBlocks.h -#ifndef __UNIQ_BLOCKS_H -#define __UNIQ_BLOCKS_H +#ifndef ZIP7_INC_UNIQ_BLOCKS_H +#define ZIP7_INC_UNIQ_BLOCKS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/VirtThread.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.cpp --- 7zip-22.01+dfsg/CPP/7zip/Common/VirtThread.cpp 2021-01-24 16:07:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.cpp 2023-03-21 07:00:00.000000000 +0000 @@ -11,7 +11,7 @@ CVirtThread *t = (CVirtThread *)p; t->StartEvent.Lock(); if (t->Exit) - return 0; + return THREAD_FUNC_RET_ZERO; t->Execute(); t->FinishedEvent.Set(); } @@ -19,8 +19,8 @@ WRes CVirtThread::Create() { - RINOK_WRes(StartEvent.CreateIfNotCreated_Reset()); - RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset()); + RINOK_WRes(StartEvent.CreateIfNotCreated_Reset()) + RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset()) // StartEvent.Reset(); // FinishedEvent.Reset(); Exit = false; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Common/VirtThread.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.h --- 7zip-22.01+dfsg/CPP/7zip/Common/VirtThread.h 2020-11-27 13:09:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Common/VirtThread.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // VirtThread.h -#ifndef __VIRT_THREAD_H -#define __VIRT_THREAD_H +#ifndef ZIP7_INC_VIRT_THREAD_H +#define ZIP7_INC_VIRT_THREAD_H #include "../../Windows/Synchronization.h" #include "../../Windows/Thread.h" @@ -13,7 +13,7 @@ NWindows::CThread Thread; bool Exit; - ~CVirtThread() { WaitThreadFinish(); } + virtual ~CVirtThread() { WaitThreadFinish(); } void WaitThreadFinish(); // call it in destructor of child class ! WRes Create(); WRes Start(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Const.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Const.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Const.h 2019-12-28 11:02:11.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Const.h 2024-12-17 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Compress/BZip2Const.h -#ifndef __COMPRESS_BZIP2_CONST_H -#define __COMPRESS_BZIP2_CONST_H +#ifndef ZIP7_INC_COMPRESS_BZIP2_CONST_H +#define ZIP7_INC_COMPRESS_BZIP2_CONST_H namespace NCompress { namespace NBZip2 { @@ -46,7 +46,7 @@ const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; const unsigned kNumSelectorsBits = 15; -const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); +const unsigned kNumSelectorsMax = 2 + kBlockSizeMax / kGroupSize; const unsigned kRleModeRepSize = 4; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Crc.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Crc.cpp 2021-01-23 08:09:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.cpp 2023-11-12 15:00:00.000000000 +0000 @@ -4,6 +4,7 @@ #include "BZip2Crc.h" +MY_ALIGN(64) UInt32 CBZip2Crc::Table[256]; static const UInt32 kBZip2CrcPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ @@ -12,7 +13,7 @@ { for (UInt32 i = 0; i < 256; i++) { - UInt32 r = (i << 24); + UInt32 r = i << 24; for (unsigned j = 0; j < 8; j++) r = (r << 1) ^ (kBZip2CrcPoly & ((UInt32)0 - (r >> 31))); Table[i] = r; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Crc.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Crc.h 2021-09-13 18:28:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Crc.h 2023-03-28 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // BZip2Crc.h -#ifndef __BZIP2_CRC_H -#define __BZIP2_CRC_H +#ifndef ZIP7_INC_BZIP2_CRC_H +#define ZIP7_INC_BZIP2_CRC_H #include "../../Common/MyTypes.h" @@ -11,10 +11,10 @@ static UInt32 Table[256]; public: static void InitTable(); - CBZip2Crc(UInt32 initVal = 0xFFFFFFFF): _value(initVal) {}; + CBZip2Crc(UInt32 initVal = 0xFFFFFFFF): _value(initVal) {} void Init(UInt32 initVal = 0xFFFFFFFF) { _value = initVal; } void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } - void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + void UpdateByte(unsigned b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } }; @@ -22,7 +22,7 @@ { UInt32 _value; public: - CBZip2CombinedCrc(): _value(0){}; + CBZip2CombinedCrc(): _value(0) {} void Init() { _value = 0; } void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } UInt32 GetDigest() const { return _value ; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Decoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Decoder.cpp 2021-02-27 08:45:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -32,7 +32,7 @@ namespace NBZip2 { // #undef NO_INLINE -#define NO_INLINE MY_NO_INLINE +#define NO_INLINE Z7_NO_INLINE #define BZIP2_BYTE_MODE @@ -42,7 +42,7 @@ static const UInt32 kProgressStep = (UInt32)1 << 16; - +MY_ALIGN(64) static const UInt16 kRandNums[512] = { 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, @@ -120,18 +120,18 @@ }; -#define UPDATE_VAL_2(val) { \ - val |= (UInt32)(*_buf) << (24 - _numBits); \ - _numBits += 8; \ +#define UPDATE_VAL_2(val, num_bits) { \ + val |= (UInt32)(*_buf) << (24 - num_bits); \ + num_bits += 8; \ _buf++; \ } -#define UPDATE_VAL UPDATE_VAL_2(VAL) +#define UPDATE_VAL UPDATE_VAL_2(VAL, NUM_BITS) #define READ_BITS(res, num) { \ while (_numBits < num) { \ if (_buf == _lim) return SZ_OK; \ - UPDATE_VAL_2(_value) } \ + UPDATE_VAL_2(_value, _numBits) } \ res = _value >> (32 - num); \ _value <<= num; \ _numBits -= num; \ @@ -140,7 +140,7 @@ #define READ_BITS_8(res, num) { \ if (_numBits < num) { \ if (_buf == _lim) return SZ_OK; \ - UPDATE_VAL_2(_value) } \ + UPDATE_VAL_2(_value, _numBits) } \ res = _value >> (32 - num); \ _value <<= num; \ _numBits -= num; \ @@ -151,16 +151,20 @@ #define VAL _value2 +// #define NUM_BITS _numBits2 +#define NUM_BITS _numBits #define BLOCK_SIZE blockSize2 #define RUN_COUNTER runCounter2 #define LOAD_LOCAL \ UInt32 VAL = this->_value; \ + /* unsigned NUM_BITS = this->_numBits; */ \ UInt32 BLOCK_SIZE = this->blockSize; \ UInt32 RUN_COUNTER = this->runCounter; \ #define SAVE_LOCAL \ this->_value = VAL; \ + /* this->_numBits = NUM_BITS; */ \ this->blockSize = BLOCK_SIZE; \ this->runCounter = RUN_COUNTER; \ @@ -169,7 +173,7 @@ SRes CBitDecoder::ReadByte(int &b) { b = -1; - READ_BITS_8(b, 8); + READ_BITS_8(b, 8) return SZ_OK; } @@ -180,7 +184,7 @@ for (;;) { unsigned b; - READ_BITS_8(b, 8); + READ_BITS_8(b, 8) if ( (state2 == 0 && b != kArSig0) || (state2 == 1 && b != kArSig1) @@ -230,7 +234,7 @@ while (state2 < 10) { unsigned b; - READ_BITS_8(b, 8); + READ_BITS_8(b, 8) temp[state2] = (Byte)b; state2++; } @@ -285,7 +289,7 @@ { if (Props.randMode) { - READ_BIT(Props.randMode); + READ_BIT(Props.randMode) } state = STATE_ORIG_BITS; // g_Tick = GetCpuTicks(); @@ -293,7 +297,7 @@ if (state == STATE_ORIG_BITS) { - READ_BITS(Props.origPtr, kNumOrigBits); + READ_BITS(Props.origPtr, kNumOrigBits) if (Props.origPtr >= blockSizeMax) return SZ_ERROR_DATA; state = STATE_IN_USE; @@ -303,7 +307,7 @@ if (state == STATE_IN_USE) { - READ_BITS(state2, 16); + READ_BITS(state2, 16) state = STATE_IN_USE2; state3 = 0; numInUse = 0; @@ -316,7 +320,7 @@ if (state2 & ((UInt32)0x8000 >> (state3 >> 4))) { unsigned b; - READ_BIT(b); + READ_BIT(b) if (b) mtf.Add(numInUse++, (Byte)state3); } @@ -328,7 +332,7 @@ if (state == STATE_NUM_TABLES) { - READ_BITS_8(numTables, kNumTablesBits); + READ_BITS_8(numTables, kNumTablesBits) state = STATE_NUM_SELECTORS; if (numTables < kNumTablesMin || numTables > kNumTablesMax) return SZ_ERROR_DATA; @@ -336,7 +340,7 @@ if (state == STATE_NUM_SELECTORS) { - READ_BITS(numSelectors, kNumSelectorsBits); + READ_BITS(numSelectors, kNumSelectorsBits) state = STATE_SELECTORS; state2 = 0x543210; state3 = 0; @@ -358,14 +362,14 @@ for (;;) { unsigned b; - READ_BIT(b); + READ_BIT(b) if (!b) break; if (++state4 >= numTables) return SZ_ERROR_DATA; } - UInt32 tmp = (state2 >> (kMtfBits * state4)) & kMtfMask; - UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1; + const UInt32 tmp = (state2 >> (kMtfBits * state4)) & kMtfMask; + const UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1; state4 = 0; state2 = ((state2 << kMtfBits) & mask) | (state2 & ~mask) | tmp; // 20.01: here we keep compatibility with bzip2-1.0.8 decoder: @@ -392,7 +396,7 @@ { if (state3 == 0) { - READ_BITS_8(state3, kNumLevelsBits); + READ_BITS_8(state3, kNumLevelsBits) state4 = 0; state5 = 0; } @@ -407,14 +411,14 @@ if (state5 == 0) { unsigned b; - READ_BIT(b); + READ_BIT(b) if (!b) break; } state5 = 1; unsigned b; - READ_BIT(b); + READ_BIT(b) state5 = 0; state3++; @@ -424,15 +428,11 @@ state5 = 0; } - // 19.03: we use Build() instead of BuildFull() to support lbzip2 archives + // 19.03: we use non-full Build() to support lbzip2 archives. // lbzip2 2.5 can produce dummy tree, where lens[i] = kMaxHuffmanLen - // BuildFull() returns error for such tree for (unsigned i = state4; i < kMaxAlphaSize; i++) lens[i] = 0; - if (!huffs[state2].Build(lens)) - /* - if (!huffs[state2].BuildFull(lens, state4)) - */ + if (!huffs[state2].Build(lens)) // k_BuildMode_Partial return SZ_ERROR_DATA; state3 = 0; } @@ -462,7 +462,7 @@ { LOAD_LOCAL - const CHuffmanDecoder *huff = &huffs[selectors[groupIndex]]; + const CHuffmanDecoder *huf = &huffs[selectors[groupIndex]]; for (;;) { @@ -470,58 +470,38 @@ { if (++groupIndex >= numSelectors) return SZ_ERROR_DATA; - huff = &huffs[selectors[groupIndex]]; + huf = &huffs[selectors[groupIndex]]; groupSize = kGroupSize; } - if (_numBits <= 8 && - _buf != _lim) { UPDATE_VAL - if (_buf != _lim) { UPDATE_VAL - if (_buf != _lim) { UPDATE_VAL }}} - - UInt32 sym; - UInt32 val = VAL >> (32 - kMaxHuffmanLen); - if (val >= huff->_limits[kNumTableBits]) - { - if (_numBits <= kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL - if (_numBits <= kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL }} - - val = VAL >> (32 - kMaxHuffmanLen); - unsigned len; - for (len = kNumTableBits + 1; val >= huff->_limits[len]; len++); - - // 19.03: we use that check to support partial trees created Build() for lbzip2 archives - if (len > kNumBitsMax) - return SZ_ERROR_DATA; // that check is required, if NHuffman::Build() was used instead of BuildFull() - - if (_numBits < len) - { - SAVE_LOCAL - return SZ_OK; - } - sym = huff->_symbols[huff->_poses[len] + ((val - huff->_limits[(size_t)len - 1]) >> (kNumBitsMax - len))]; - VAL <<= len; - _numBits -= len; - } - else - { - sym = huff->_lens[val >> (kMaxHuffmanLen - kNumTableBits)]; - unsigned len = (sym & NHuffman::kPairLenMask); - sym >>= NHuffman::kNumPairLenBits; - if (_numBits < len) - { - SAVE_LOCAL - return SZ_OK; - } - VAL <<= len; - _numBits -= len; - } + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL }}} + + unsigned sym; + + #define MOV_POS(bs, len) \ + { \ + if (NUM_BITS < len) \ + { \ + SAVE_LOCAL \ + return SZ_OK; \ + } \ + VAL <<= len; \ + NUM_BITS -= (unsigned)len; \ + } + + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kMaxHuffmanLen, kNumTableBits, + VAL, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, + { return SZ_ERROR_DATA; }, + MOV_POS, {}, bs) groupSize--; if (sym < 2) { - RUN_COUNTER += ((UInt32)(sym + 1) << runPower); + RUN_COUNTER += (UInt32)(sym + 1) << runPower; runPower++; if (blockSizeMax - BLOCK_SIZE < RUN_COUNTER) return SZ_ERROR_DATA; @@ -573,8 +553,8 @@ // UInt32 b = (UInt32)mtf.GetAndMove((unsigned)sym); - const unsigned lim = sym >> MTF_MOVS; - const unsigned pos = (sym & MTF_MASK) << 3; + const unsigned lim = sym >> Z7_MTF_MOVS; + const unsigned pos = (sym & Z7_MTF_MASK) << 3; CMtfVar next = mtf.Buf[lim]; CMtfVar prev = (next >> pos) & 0xFF; @@ -593,7 +573,7 @@ { CMtfVar n0 = *m; *m = (n0 << 8) | prev; - prev = (n0 >> (MTF_MASK << 3)); + prev = (n0 >> (Z7_MTF_MASK << 3)); } while (++m != mLim); } @@ -879,7 +859,7 @@ if (processed >= size) { - RINOK(Flush()); + RINOK(Flush()) } if (block.Finished()) @@ -900,7 +880,7 @@ _inBuf(NULL), _inProcessed(0) { - #ifndef _7ZIP_ST + #ifndef Z7_ST MtMode = false; NeedWaitScout = false; // ScoutRes = S_OK; @@ -912,7 +892,7 @@ { PRIN("\n~CDecoder()"); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (Thread.IsCreated()) { @@ -966,7 +946,7 @@ { for (;;) { - RINOK(ReadInput()); + RINOK(ReadInput()) SRes res = Base.ReadStreamSignature2(); if (res != SZ_OK) return S_FALSE; @@ -992,7 +972,7 @@ { for (;;) { - RINOK(ReadInput()); + RINOK(ReadInput()) SRes res = Base.ReadBlockSignature2(); @@ -1015,7 +995,7 @@ { for (;;) { - RINOK(ReadInput()); + RINOK(ReadInput()) SRes res = Base.ReadBlock2(); @@ -1036,18 +1016,18 @@ HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress) { { - #ifndef _7ZIP_ST + #ifndef Z7_ST _block.StopScout = false; #endif } - RINOK(StartRead()); + RINOK(StartRead()) UInt64 inPrev = 0; UInt64 outPrev = 0; { - #ifndef _7ZIP_ST + #ifndef Z7_ST CWaitScout_Releaser waitScout_Releaser(this); bool useMt = false; @@ -1072,7 +1052,7 @@ const UInt64 outCur = GetOutProcessedSize(); if (packPos - inPrev >= kProgressStep || outCur - outPrev >= kProgressStep) { - RINOK(progress->SetRatioInfo(&packPos, &outCur)); + RINOK(progress->SetRatioInfo(&packPos, &outCur)) inPrev = packPos; outPrev = outCur; } @@ -1083,7 +1063,7 @@ return nextRes; if ( - #ifndef _7ZIP_ST + #ifndef Z7_ST !useMt && #endif !wasFinished && Base.state == STATE_BLOCK_SIGNATURE) @@ -1125,7 +1105,7 @@ wasFinished = false; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (MtMode) if (props.blockSize != 0) { @@ -1136,7 +1116,7 @@ if (!Thread.IsCreated()) { PRIN("=== MT_MODE"); - RINOK(CreateThread()); + RINOK(CreateThread()) } useMt = true; } @@ -1148,7 +1128,7 @@ { crc = nextCrc; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (useMt) { PRIN("DecoderEvent.Lock()"); @@ -1165,7 +1145,7 @@ crc = _block.Crc; packPos = _block.PackPos; wasFinished = _block.WasFinished; - RINOK(_block.Res); + RINOK(_block.Res) } else #endif @@ -1175,7 +1155,7 @@ TICKS_START Base.Props.randMode = 1; - RINOK(ReadBlock()); + RINOK(ReadBlock()) TICKS_UPDATE(0) props = Base.Props; @@ -1190,7 +1170,7 @@ TICKS_UPDATE(1) } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (useMt && !wasFinished) { /* @@ -1216,7 +1196,7 @@ if (props.blockSize == 0) continue; - RINOK(DecodeBlock(props)); + RINOK(DecodeBlock(props)) if (!_blockFinished) return nextRes; @@ -1278,8 +1258,8 @@ } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { /* { @@ -1344,21 +1324,21 @@ } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { FinishMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = GetInStreamSize(); return S_OK; } -STDMETHODIMP CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) { Base.AlignToByte(); UInt32 i; @@ -1376,7 +1356,7 @@ } -#ifndef _7ZIP_ST +#ifndef Z7_ST #define PRIN_MT(s) PRIN(" " s) @@ -1397,9 +1377,9 @@ for (;;) { { - PRIN_MT("ScoutEvent.Lock()"); + PRIN_MT("ScoutEvent.Lock()") WRes wres = ScoutEvent.Lock(); - PRIN_MT("-- ScoutEvent.Lock()"); + PRIN_MT("-- ScoutEvent.Lock()") if (wres != 0) { // ScoutRes = wres; @@ -1461,7 +1441,7 @@ res = ReadBlock(); - PRIN_MT("-- Base.ReadBlock"); + PRIN_MT("-- Base.ReadBlock") if (res != S_OK) break; block.Props = Base.Props; @@ -1505,13 +1485,13 @@ if (res != S_OK) { - PRIN_MT("error"); + PRIN_MT("error") block.Res = res; block.WasFinished = true; } block.PackPos = GetInputProcessedSize(); - PRIN_MT("DecoderEvent.Set()"); + PRIN_MT("DecoderEvent.Set()") WRes wres = DecoderEvent.Set(); if (wres != 0) { @@ -1522,7 +1502,7 @@ } -STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) +Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads)) { MtMode = (numThreads > 1); @@ -1538,10 +1518,10 @@ -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) { Base.InStreamRef = inStream; Base.InStream = inStream; @@ -1549,7 +1529,7 @@ } -STDMETHODIMP CDecoder::ReleaseInStream() +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) { Base.InStreamRef.Release(); Base.InStream = NULL; @@ -1558,7 +1538,7 @@ -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { InitOutSize(outSize); @@ -1583,7 +1563,7 @@ -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { *processedSize = 0; @@ -1689,7 +1669,7 @@ // ---------- NSIS ---------- -STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { *processedSize = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Decoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Decoder.h 2021-01-25 15:02:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Decoder.h 2024-01-01 16:00:00.000000000 +0000 @@ -1,14 +1,14 @@ // Compress/BZip2Decoder.h -#ifndef __COMPRESS_BZIP2_DECODER_H -#define __COMPRESS_BZIP2_DECODER_H +#ifndef ZIP7_INC_COMPRESS_BZIP2_DECODER_H +#define ZIP7_INC_COMPRESS_BZIP2_DECODER_H #include "../../Common/MyCom.h" -// #define NO_READ_FROM_CODER -// #define _7ZIP_ST +// #define Z7_NO_READ_FROM_CODER +// #define Z7_ST -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #include "../../Windows/Thread.h" #endif @@ -27,7 +27,6 @@ bool IsBlockSig(const Byte *p) throw(); const unsigned kNumTableBits = 9; -const unsigned kNumBitsMax = kMaxHuffmanLen; typedef NHuffman::CDecoder CHuffmanDecoder; @@ -99,7 +98,7 @@ UInt32 blockSizeMax; unsigned state; - unsigned state2; + UInt32 state2; unsigned state3; unsigned state4; unsigned state5; @@ -134,7 +133,7 @@ ISequentialInStream *InStream; - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER CMyComPtr InStreamRef; #endif @@ -194,24 +193,51 @@ -class CDecoder : +class CDecoder: public ICompressCoder, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, public ICompressReadUnusedFromInBuf, - - #ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif - - #ifndef _7ZIP_ST +#endif +#ifndef Z7_ST public ICompressSetCoderMt, - #endif - +#endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) +#ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) +#endif +#ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP_NONFINAL(ISequentialInStream) +#endif +public: +#ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) +#endif + +private: Byte *_outBuf; size_t _outPos; UInt64 _outWritten; @@ -235,7 +261,7 @@ CSpecState _spec; UInt32 *_counters; - #ifndef _7ZIP_ST + #ifndef Z7_ST struct CBlock { @@ -339,60 +365,20 @@ HRESULT DecodeBlock(const CBlockProps &props); HRESULT DecodeStreams(ICompressProgressInfo *progress); - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf) - - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - #endif - - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize); - UInt64 GetNumStreams() const { return Base.NumStreams; } UInt64 GetNumBlocks() const { return Base.NumBlocks; } - #ifndef NO_READ_FROM_CODER - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - #endif - - #ifndef _7ZIP_ST - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - #endif - CDecoder(); - ~CDecoder(); + virtual ~CDecoder(); }; -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -class CNsisDecoder : public CDecoder +class CNsisDecoder Z7_final: public CDecoder { -public: - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + Z7_IFACE_COM7_IMP(ISequentialInStream) }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Encoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Encoder.cpp 2022-02-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.cpp 2025-07-06 06:00:00.000000000 +0000 @@ -6,18 +6,20 @@ #include "../../../C/BwtSort.h" #include "../../../C/HuffEnc.h" -#include "BZip2Crc.h" #include "BZip2Encoder.h" -#include "Mtf8.h" namespace NCompress { namespace NBZip2 { -const unsigned kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20 - -static const UInt32 kBufferSize = (1 << 17); +#define HUFFMAN_LEN 16 +#if HUFFMAN_LEN > Z7_HUFFMAN_LEN_MAX + #error Stop_Compiling_Bad_HUFFMAN_LEN_BZip2Encoder +#endif + +static const size_t kBufferSize = 1 << 17; static const unsigned kNumHuffPasses = 4; + bool CThreadInfo::Alloc() { if (!m_BlockSorterIndex) @@ -27,11 +29,15 @@ return false; } - if (!m_Block) + if (!m_Block_Base) { - m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10)); - if (!m_Block) + const unsigned kPadSize = 1 << 7; // we need at least 1 byte backward padding, becuase we use (m_Block - 1) pointer; + m_Block_Base = (Byte *)::MidAlloc(kBlockSizeMax * 5 + + kBlockSizeMax / 10 + (20 << 10) + + kPadSize); + if (!m_Block_Base) return false; + m_Block = m_Block_Base + kPadSize; m_MtfArray = m_Block + kBlockSizeMax; m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2; } @@ -42,11 +48,11 @@ { ::BigFree(m_BlockSorterIndex); m_BlockSorterIndex = NULL; - ::MidFree(m_Block); - m_Block = NULL; + ::MidFree(m_Block_Base); + m_Block_Base = NULL; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static THREAD_FUNC_DECL MFThread(void *threadCoderInfo) { @@ -60,10 +66,14 @@ if (wres == 0) { wres = CanWriteEvent.Create(); if (wres == 0) { - if (Encoder->_props.Affinity != 0) - wres = Thread.Create_With_Affinity(MFThread, this, (CAffinityMask)Encoder->_props.Affinity); - else - wres = Thread.Create(MFThread, this); + wres = +#ifdef _WIN32 + Encoder->_props.NumThreadGroups > 1 ? + Thread.Create_With_Group(MFThread, this, ThreadNextGroup_GetNext(&Encoder->ThreadNextGroup), 0) : // affinity +#endif + Encoder->_props.Affinity != 0 ? + Thread.Create_With_Affinity(MFThread, this, (CAffinityMask)Encoder->_props.Affinity) : + Thread.Create(MFThread, this); }}} return HRESULT_FROM_WIN32(wres); } @@ -146,14 +156,14 @@ { _props.Normalize(-1); - #ifndef _7ZIP_ST + #ifndef Z7_ST ThreadsInfo = NULL; m_NumThreadsPrev = 0; NumThreads = 1; #endif } -#ifndef _7ZIP_ST +#ifndef Z7_ST CEncoder::~CEncoder() { Free(); @@ -216,94 +226,251 @@ } #endif +struct CRleEncoder +{ + const Byte *_src; + const Byte *_srcLim; + Byte *_dest; + const Byte *_destLim; + Byte _prevByte; + unsigned _numReps; + + void Encode(); +}; + +Z7_NO_INLINE +void CRleEncoder::Encode() +{ + const Byte *src = _src; + const Byte * const srcLim = _srcLim; + Byte *dest = _dest; + const Byte * const destLim = _destLim; + Byte prev = _prevByte; + unsigned numReps = _numReps; + // (dest < destLim) + // src = srcLim; // for debug + while (dest < destLim) + { + if (src == srcLim) + break; + const Byte b = *src++; + if (b != prev) + { + if (numReps >= kRleModeRepSize) + *dest++ = (Byte)(numReps - kRleModeRepSize); + *dest++ = b; + numReps = 1; + prev = b; + /* + { // speed optimization code: + if (dest >= destLim || src == srcLim) + break; + const Byte b2 = *src++; + *dest++ = b2; + numReps += (prev == b2); + prev = b2; + } + */ + continue; + } + numReps++; + if (numReps <= kRleModeRepSize) + *dest++ = b; + else if (numReps == kRleModeRepSize + 255) + { + *dest++ = (Byte)(numReps - kRleModeRepSize); + numReps = 0; + } + } + _src = src; + _dest = dest; + _prevByte = prev; + _numReps = numReps; + // (dest <= destLim + 1) +} + + +// out: return value is blockSize: size of data filled in buffer[]: +// (returned_blockSize <= _props.BlockSizeMult * kBlockSizeStep) UInt32 CEncoder::ReadRleBlock(Byte *buffer) { + CRleEncoder rle; UInt32 i = 0; - Byte prevByte; - if (m_InStream.ReadByte(prevByte)) + if (m_InStream.ReadByte(rle._prevByte)) { NumBlocks++; - const UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1; - unsigned numReps = 1; - buffer[i++] = prevByte; - while (i < blockSize) // "- 1" to support RLE - { - Byte b; - if (!m_InStream.ReadByte(b)) + const UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1; // -1 for RLE + rle._destLim = buffer + blockSize; + rle._numReps = 1; + buffer[i++] = rle._prevByte; + while (i < blockSize) + { + rle._dest = buffer + i; + size_t rem; + const Byte * const ptr = m_InStream.Lookahead(rem); + if (rem == 0) break; - if (b != prevByte) - { - if (numReps >= kRleModeRepSize) - buffer[i++] = (Byte)(numReps - kRleModeRepSize); - buffer[i++] = b; - numReps = 1; - prevByte = b; - continue; - } - numReps++; - if (numReps <= kRleModeRepSize) - buffer[i++] = b; - else if (numReps == kRleModeRepSize + 255) - { - buffer[i++] = (Byte)(numReps - kRleModeRepSize); - numReps = 0; - } - } - // it's to support original BZip2 decoder - if (numReps >= kRleModeRepSize) - buffer[i++] = (Byte)(numReps - kRleModeRepSize); + rle._src = ptr; + rle._srcLim = ptr + rem; + rle.Encode(); + m_InStream.Skip((size_t)(rle._src - ptr)); + i = (UInt32)(size_t)(rle._dest - buffer); + // (i <= blockSize + 1) + } + const int n = (int)rle._numReps - (int)kRleModeRepSize; + if (n >= 0) + buffer[i++] = (Byte)n; } return i; } -void CThreadInfo::WriteBits2(UInt32 value, unsigned numBits) { m_OutStreamCurrent->WriteBits(value, numBits); } -void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b, 8); } -void CThreadInfo::WriteBit2(Byte v) { WriteBits2(v, 1); } -void CThreadInfo::WriteCrc2(UInt32 v) -{ - for (unsigned i = 0; i < 4; i++) - WriteByte2(((Byte)(v >> (24 - i * 8)))); -} - -void CEncoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } -void CEncoder::WriteByte(Byte b) { WriteBits(b, 8); } -// void CEncoder::WriteBit(Byte v) { WriteBits(v, 1); } -void CEncoder::WriteCrc(UInt32 v) -{ - for (unsigned i = 0; i < 4; i++) - WriteByte(((Byte)(v >> (24 - i * 8)))); + + +Z7_NO_INLINE +void CThreadInfo::WriteBits2(UInt32 value, unsigned numBits) + { m_OutStreamCurrent.WriteBits(value, numBits); } +/* +Z7_NO_INLINE +void CThreadInfo::WriteByte2(unsigned b) + { m_OutStreamCurrent.WriteByte(b); } +*/ +// void CEncoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } +Z7_NO_INLINE +void CEncoder::WriteByte(Byte b) { m_OutStream.WriteByte(b); } + + +#define WRITE_BITS_UPDATE(value, numBits) \ +{ \ + numBits -= _bitPos; \ + const UInt32 hi = value >> numBits; \ + *_buf++ = (Byte)(_curByte | hi); \ + value -= hi << numBits; \ + _bitPos = 8; \ + _curByte = 0; \ +} + +#if HUFFMAN_LEN > 16 + +#define WRITE_BITS_HUFF(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + while (numBits >= _bitPos) { \ + WRITE_BITS_UPDATE(value, numBits) \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#else // HUFFMAN_LEN <= 16 + +// numBits2 <= 16 is supported +#define WRITE_BITS_HUFF(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + if (numBits >= _bitPos) \ + { \ + WRITE_BITS_UPDATE(value, numBits) \ + if (numBits >= _bitPos) \ + { \ + numBits -= _bitPos; \ + const UInt32 hi = value >> numBits; \ + *_buf++ = (Byte)hi; \ + value -= hi << numBits; \ + } \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#endif + +#define WRITE_BITS_8(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + if (numBits >= _bitPos) \ + { \ + WRITE_BITS_UPDATE(value, numBits) \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#define WRITE_BIT_PRE \ + { _bitPos--; } + +#define WRITE_BIT_POST \ +{ \ + if (_bitPos == 0) \ + { \ + *_buf++ = (Byte)_curByte; \ + _curByte = 0; \ + _bitPos = 8; \ + } \ +} + +#define WRITE_BIT_0 \ +{ \ + WRITE_BIT_PRE \ + WRITE_BIT_POST \ +} + +#define WRITE_BIT_1 \ +{ \ + WRITE_BIT_PRE \ + _curByte |= 1u << _bitPos; \ + WRITE_BIT_POST \ } // blockSize > 0 void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) { - WriteBit2(0); // Randomised = false - + // WriteBit2(0); // Randomised = false { - UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); + const UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); // if (m_BlockSorterIndex[origPtr] != 0) throw 1; m_BlockSorterIndex[origPtr] = blockSize; - WriteBits2(origPtr, kNumOrigBits); + WriteBits2(origPtr, kNumOrigBits + 1); // + 1 for additional high bit flag (Randomised = false) } - - CMtf8Encoder mtf; - unsigned numInUse = 0; + Byte mtfBuf[256]; + // memset(mtfBuf, 0, sizeof(mtfBuf)); // to disable MSVC warning + unsigned numInUse; { Byte inUse[256]; Byte inUse16[16]; - UInt32 i; + unsigned i; for (i = 0; i < 256; i++) inUse[i] = 0; for (i = 0; i < 16; i++) inUse16[i] = 0; - for (i = 0; i < blockSize; i++) - inUse[block[i]] = 1; + { + const Byte * cur = block; + block = block + (size_t)blockSize - 1; + if (cur != block) + { + do + { + const unsigned b0 = cur[0]; + const unsigned b1 = cur[1]; + cur += 2; + inUse[b0] = 1; + inUse[b1] = 1; + } + while (cur < block); + } + if (cur == block) + inUse[cur[0]] = 1; + block -= blockSize; // block pointer is (original_block - 1) + } + numInUse = 0; for (i = 0; i < 256; i++) if (inUse[i]) { inUse16[i >> 4] = 1; - mtf.Buf[numInUse++] = (Byte)i; + mtfBuf[numInUse++] = (Byte)i; } for (i = 0; i < 16; i++) WriteBit2(inUse16[i]); @@ -311,65 +478,88 @@ if (inUse16[i >> 4]) WriteBit2(inUse[i]); } - unsigned alphaSize = numInUse + 2; + const unsigned alphaSize = numInUse + 2; - Byte *mtfs = m_MtfArray; - UInt32 mtfArraySize = 0; UInt32 symbolCounts[kMaxAlphaSize]; { for (unsigned i = 0; i < kMaxAlphaSize; i++) symbolCounts[i] = 0; + symbolCounts[(size_t)alphaSize - 1] = 1; } + Byte *mtfs = m_MtfArray; { - UInt32 rleSize = 0; - UInt32 i = 0; const UInt32 *bsIndex = m_BlockSorterIndex; - block--; + const UInt32 *bsIndex_rle = bsIndex; + const UInt32 * const bsIndex_end = bsIndex + blockSize; + // block--; // backward fix + // block pointer is (original_block - 1) do { - unsigned pos = mtf.FindAndMove(block[bsIndex[i]]); - if (pos == 0) - rleSize++; - else + const Byte v = block[*bsIndex++]; + Byte a = mtfBuf[0]; + if (v != a) { - while (rleSize != 0) + mtfBuf[0] = v; { - rleSize--; - mtfs[mtfArraySize++] = (Byte)(rleSize & 1); - symbolCounts[rleSize & 1]++; - rleSize >>= 1; + UInt32 rleSize = (UInt32)(size_t)(bsIndex - bsIndex_rle) - 1; + bsIndex_rle = bsIndex; + while (rleSize) + { + const unsigned sym = (unsigned)(--rleSize & 1); + *mtfs++ = (Byte)sym; + symbolCounts[sym]++; + rleSize >>= 1; + } } - if (pos >= 0xFE) + unsigned pos1 = 2; // = real_pos + 1 + Byte b; + b = mtfBuf[1]; mtfBuf[1] = a; if (v != b) + { a = mtfBuf[2]; mtfBuf[2] = b; if (v == a) pos1 = 3; + else { b = mtfBuf[3]; mtfBuf[3] = a; if (v == b) pos1 = 4; + else { - mtfs[mtfArraySize++] = 0xFF; - mtfs[mtfArraySize++] = (Byte)(pos - 0xFE); + Byte *m = mtfBuf + 7; + for (;;) + { + a = m[-3]; m[-3] = b; if (v == a) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 2)); break; } + b = m[-2]; m[-2] = a; if (v == b) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 1)); break; } + a = m[-1]; m[-1] = b; if (v == a) { pos1 = (unsigned)(size_t)(m - (mtfBuf )); break; } + b = m[ 0]; m[ 0] = a; m += 4; if (v == b) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 3)); break; } + } + }}} + symbolCounts[pos1]++; + if (pos1 >= 0xff) + { + *mtfs++ = 0xff; + // pos1 -= 0xff; + pos1++; // we need only low byte } - else - mtfs[mtfArraySize++] = (Byte)(pos + 1); - symbolCounts[(size_t)pos + 1]++; + *mtfs++ = (Byte)pos1; } } - while (++i < blockSize); + while (bsIndex < bsIndex_end); - while (rleSize != 0) + UInt32 rleSize = (UInt32)(size_t)(bsIndex - bsIndex_rle); + while (rleSize) { - rleSize--; - mtfs[mtfArraySize++] = (Byte)(rleSize & 1); - symbolCounts[rleSize & 1]++; + const unsigned sym = (unsigned)(--rleSize & 1); + *mtfs++ = (Byte)sym; + symbolCounts[sym]++; rleSize >>= 1; } - - if (alphaSize < 256) - mtfs[mtfArraySize++] = (Byte)(alphaSize - 1); - else + + unsigned d = alphaSize - 1; + if (alphaSize >= 256) { - mtfs[mtfArraySize++] = 0xFF; - mtfs[mtfArraySize++] = (Byte)(alphaSize - 256); + *mtfs++ = 0xff; + d = alphaSize; // (-256) } - symbolCounts[(size_t)alphaSize - 1]++; + *mtfs++ = (Byte)d; } + const Byte * const mtf_lim = mtfs; + UInt32 numSymbols = 0; { for (unsigned i = 0; i < kMaxAlphaSize; i++) @@ -378,34 +568,30 @@ unsigned bestNumTables = kNumTablesMin; UInt32 bestPrice = 0xFFFFFFFF; - UInt32 startPos = m_OutStreamCurrent->GetPos(); - Byte startCurByte = m_OutStreamCurrent->GetCurByte(); + const UInt32 startPos = m_OutStreamCurrent.GetPos(); + const unsigned startCurByte = m_OutStreamCurrent.GetCurByte(); for (unsigned nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) { unsigned numTables; if (m_OptimizeNumTables) { - m_OutStreamCurrent->SetPos(startPos); - m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); - if (nt <= kNumTablesMax) - numTables = nt; - else - numTables = bestNumTables; + m_OutStreamCurrent.SetPos(startPos); + m_OutStreamCurrent.SetCurState(startPos & 7, startCurByte); + numTables = (nt <= kNumTablesMax ? nt : bestNumTables); } else { - if (numSymbols < 200) numTables = 2; - else if (numSymbols < 600) numTables = 3; + if (numSymbols < 200) numTables = 2; + else if (numSymbols < 600) numTables = 3; else if (numSymbols < 1200) numTables = 4; else if (numSymbols < 2400) numTables = 5; - else numTables = 6; + else numTables = 6; } WriteBits2(numTables, kNumTablesBits); - - UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; - WriteBits2(numSelectors, kNumSelectorsBits); + const unsigned numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; + WriteBits2((UInt32)numSelectors, kNumSelectorsBits); { UInt32 remFreq = numSymbols; @@ -436,28 +622,23 @@ for (unsigned pass = 0; pass < kNumHuffPasses; pass++) { + memset(Freqs, 0, sizeof(Freqs[0]) * numTables); + // memset(Freqs, 0, sizeof(Freqs)); { - unsigned t = 0; - do - memset(Freqs[t], 0, sizeof(Freqs[t])); - while (++t < numTables); - } - - { - UInt32 mtfPos = 0; + mtfs = m_MtfArray; UInt32 g = 0; do { - UInt32 symbols[kGroupSize]; + unsigned symbols[kGroupSize]; unsigned i = 0; do { - UInt32 symbol = mtfs[mtfPos++]; + UInt32 symbol = *mtfs++; if (symbol >= 0xFF) - symbol += mtfs[mtfPos++]; + symbol += *mtfs++; symbols[i] = symbol; } - while (++i < kGroupSize && mtfPos < mtfArraySize); + while (++i < kGroupSize && mtfs < mtf_lim); UInt32 bestPrice2 = 0xFFFFFFFF; unsigned t = 0; @@ -482,7 +663,7 @@ freqs[symbols[j]]++; while (++j < i); } - while (mtfPos < mtfArraySize); + while (mtfs < mtf_lim); } unsigned t = 0; @@ -494,11 +675,15 @@ if (freqs[i] == 0) freqs[i] = 1; while (++i < alphaSize); - Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding); + Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, HUFFMAN_LEN); } while (++t < numTables); } + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled + Byte *_buf; { Byte mtfSel[kNumTablesMax]; { @@ -507,81 +692,97 @@ mtfSel[t] = (Byte)t; while (++t < numTables); } + + _bitPos = m_OutStreamCurrent._bitPos; + _curByte = m_OutStreamCurrent._curByte; + _buf = m_OutStreamCurrent._buf; + // stream.Init_from_Global(m_OutStreamCurrent); - UInt32 i = 0; + const Byte *selectors = m_Selectors; + const Byte * const selectors_lim = selectors + numSelectors; + Byte prev = 0; // mtfSel[0]; do { - Byte sel = m_Selectors[i]; - unsigned pos; - for (pos = 0; mtfSel[pos] != sel; pos++) - WriteBit2(1); - WriteBit2(0); - for (; pos > 0; pos--) - mtfSel[pos] = mtfSel[(size_t)pos - 1]; - mtfSel[0] = sel; + const Byte sel = *selectors++; + if (prev != sel) + { + Byte *mtfSel_cur = &mtfSel[1]; + for (;;) + { + WRITE_BIT_1 + const Byte next = *mtfSel_cur; + *mtfSel_cur++ = prev; + prev = next; + if (next == sel) + break; + } + // mtfSel[0] = sel; + } + WRITE_BIT_0 } - while (++i < numSelectors); + while (selectors != selectors_lim); } - { unsigned t = 0; do { const Byte *lens = Lens[t]; - UInt32 len = lens[0]; - WriteBits2(len, kNumLevelsBits); + unsigned len = lens[0]; + WRITE_BITS_8(len, kNumLevelsBits) unsigned i = 0; do { - UInt32 level = lens[i]; + const unsigned level = lens[i]; while (len != level) { - WriteBit2(1); + WRITE_BIT_1 if (len < level) { - WriteBit2(0); len++; + WRITE_BIT_0 } else { - WriteBit2(1); len--; + WRITE_BIT_1 } } - WriteBit2(0); + WRITE_BIT_0 } while (++i < alphaSize); } while (++t < numTables); } - { - UInt32 groupSize = 0; - UInt32 groupIndex = 0; - const Byte *lens = 0; - const UInt32 *codes = 0; - UInt32 mtfPos = 0; + UInt32 groupSize = 1; + const Byte *selectors = m_Selectors; + const Byte *lens = NULL; + const UInt32 *codes = NULL; + mtfs = m_MtfArray; do { - UInt32 symbol = mtfs[mtfPos++]; + unsigned symbol = *mtfs++; if (symbol >= 0xFF) - symbol += mtfs[mtfPos++]; - if (groupSize == 0) + symbol += *mtfs++; + if (--groupSize == 0) { groupSize = kGroupSize; - unsigned t = m_Selectors[groupIndex++]; + const unsigned t = *selectors++; lens = Lens[t]; codes = Codes[t]; } - groupSize--; - m_OutStreamCurrent->WriteBits(codes[symbol], lens[symbol]); + WRITE_BITS_HUFF(codes[symbol], lens[symbol]) } - while (mtfPos < mtfArraySize); + while (mtfs < mtf_lim); } + // Restore_from_Local: + m_OutStreamCurrent._bitPos = _bitPos; + m_OutStreamCurrent._curByte = _curByte; + m_OutStreamCurrent._buf = _buf; if (!m_OptimizeNumTables) break; - UInt32 price = m_OutStreamCurrent->GetPos() - startPos; + const UInt32 price = m_OutStreamCurrent.GetPos() - startPos; if (price <= bestPrice) { if (nt == kNumTablesMax) @@ -592,6 +793,7 @@ } } + // blockSize > 0 UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize) { @@ -603,142 +805,126 @@ WriteByte2(kBlockSig5); CBZip2Crc crc; - unsigned numReps = 0; - Byte prevByte = block[0]; - UInt32 i = 0; - do + const Byte * const lim = block + blockSize; + unsigned b = *block++; + crc.UpdateByte(b); + for (;;) { - Byte b = block[i]; - if (numReps == kRleModeRepSize) - { - for (; b > 0; b--) - crc.UpdateByte(prevByte); - numReps = 0; - continue; - } - if (prevByte == b) - numReps++; - else - { - numReps = 1; - prevByte = b; - } - crc.UpdateByte(b); - } - while (++i < blockSize); - UInt32 crcRes = crc.GetDigest(); - WriteCrc2(crcRes); - EncodeBlock(block, blockSize); + const unsigned prev = b; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; if (b) do crc.UpdateByte(prev); while (--b); + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); + } + const UInt32 crcRes = crc.GetDigest(); + for (int i = 24; i >= 0; i -= 8) + WriteByte2((Byte)(crcRes >> i)); + EncodeBlock(lim - blockSize, blockSize); return crcRes; } + void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses) { - UInt32 numCrcs = m_NumCrcs; - bool needCompare = false; + const UInt32 numCrcs = m_NumCrcs; - UInt32 startBytePos = m_OutStreamCurrent->GetBytePos(); - UInt32 startPos = m_OutStreamCurrent->GetPos(); - Byte startCurByte = m_OutStreamCurrent->GetCurByte(); - Byte endCurByte = 0; - UInt32 endPos = 0; + const UInt32 startBytePos = m_OutStreamCurrent.GetBytePos(); + const UInt32 startPos = m_OutStreamCurrent.GetPos(); + const unsigned startCurByte = m_OutStreamCurrent.GetCurByte(); + unsigned endCurByte = 0; + UInt32 endPos = 0; // 0 means no no additional passes if (numPasses > 1 && blockSize >= (1 << 10)) { - UInt32 blockSize0 = blockSize / 2; // ???? + UInt32 bs0 = blockSize / 2; + for (; bs0 < blockSize && + (block[ bs0 ] == + block[(size_t)bs0 - 1] || + block[(size_t)bs0 - 1] == + block[(size_t)bs0 - 2]); + bs0++) + {} - for (; (block[blockSize0] == block[(size_t)blockSize0 - 1] - || block[(size_t)blockSize0 - 1] == block[(size_t)blockSize0 - 2]) - && blockSize0 < blockSize; - blockSize0++); - - if (blockSize0 < blockSize) + if (bs0 < blockSize) { - EncodeBlock2(block, blockSize0, numPasses - 1); - EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1); - endPos = m_OutStreamCurrent->GetPos(); - endCurByte = m_OutStreamCurrent->GetCurByte(); - if ((endPos & 7) > 0) + EncodeBlock2(block, bs0, numPasses - 1); + EncodeBlock2(block + bs0, blockSize - bs0, numPasses - 1); + endPos = m_OutStreamCurrent.GetPos(); + endCurByte = m_OutStreamCurrent.GetCurByte(); + // we prepare next byte as identical byte to starting byte for main encoding attempt: + if (endPos & 7) WriteBits2(0, 8 - (endPos & 7)); - m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); - needCompare = true; + m_OutStreamCurrent.SetCurState((startPos & 7), startCurByte); } } - UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos(); - UInt32 startPos2 = m_OutStreamCurrent->GetPos(); - UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); - UInt32 endPos2 = m_OutStreamCurrent->GetPos(); + const UInt32 startBytePos2 = m_OutStreamCurrent.GetBytePos(); + const UInt32 startPos2 = m_OutStreamCurrent.GetPos(); + const UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); - if (needCompare) + if (endPos) { - UInt32 size2 = endPos2 - startPos2; - if (size2 < endPos - startPos) - { - UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2; - Byte *buffer = m_OutStreamCurrent->GetStream(); - for (UInt32 i = 0; i < numBytes; i++) - buffer[startBytePos + i] = buffer[startBytePos2 + i]; - m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2); - m_NumCrcs = numCrcs; - m_CRCs[m_NumCrcs++] = crcVal; - } - else + const UInt32 size2 = m_OutStreamCurrent.GetPos() - startPos2; + if (size2 >= endPos - startPos) { - m_OutStreamCurrent->SetPos(endPos); - m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte); + m_OutStreamCurrent.SetPos(endPos); + m_OutStreamCurrent.SetCurState((endPos & 7), endCurByte); + return; } + const UInt32 numBytes = m_OutStreamCurrent.GetBytePos() - startBytePos2; + Byte * const buffer = m_OutStreamCurrent.GetStream(); + memmove(buffer + startBytePos, buffer + startBytePos2, numBytes); + m_OutStreamCurrent.SetPos(startPos + size2); + // we don't call m_OutStreamCurrent.SetCurState() here because + // m_OutStreamCurrent._curByte is correct already } - else - { - m_NumCrcs = numCrcs; - m_CRCs[m_NumCrcs++] = crcVal; - } + m_CRCs[numCrcs] = crcVal; + m_NumCrcs = numCrcs + 1; } + HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize) { - CMsbfEncoderTemp outStreamTemp; + CMsbfEncoderTemp &outStreamTemp = m_OutStreamCurrent; outStreamTemp.SetStream(m_TempArray); outStreamTemp.Init(); - m_OutStreamCurrent = &outStreamTemp; - m_NumCrcs = 0; EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses); - #ifndef _7ZIP_ST +#ifndef Z7_ST if (Encoder->MtMode) Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock(); - #endif +#endif + for (UInt32 i = 0; i < m_NumCrcs; i++) Encoder->CombinedCrc.Update(m_CRCs[i]); - Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte()); + Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetNonFlushedByteBits()); HRESULT res = S_OK; - #ifndef _7ZIP_ST + +#ifndef Z7_ST if (Encoder->MtMode) { UInt32 blockIndex = m_BlockIndex + 1; if (blockIndex == Encoder->NumThreads) blockIndex = 0; - if (Encoder->Progress) { const UInt64 packSize = Encoder->m_OutStream.GetProcessedSize(); res = Encoder->Progress->SetRatioInfo(&m_UnpackSize, &packSize); } - Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set(); } - #endif +#endif return res; } -void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte) +void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, unsigned lastByteBits) { - UInt32 bytesSize = (sizeInBits >> 3); - for (UInt32 i = 0; i < bytesSize; i++) - m_OutStream.WriteBits(data[i], 8); - WriteBits(lastByte, (sizeInBits & 7)); + m_OutStream.WriteBytes(data, sizeInBits >> 3); + sizeInBits &= 7; + if (sizeInBits) + m_OutStream.WriteBits(lastByteBits, sizeInBits); } @@ -746,13 +932,14 @@ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) { NumBlocks = 0; - #ifndef _7ZIP_ST +#ifndef Z7_ST Progress = progress; - RINOK(Create()); + ThreadNextGroup_Init(&ThreadNextGroup, _props.NumThreadGroups, 0); // startGroup + RINOK(Create()) for (UInt32 t = 0; t < NumThreads; t++) - #endif +#endif { - #ifndef _7ZIP_ST + #ifndef Z7_ST CThreadInfo &ti = ThreadsInfo[t]; if (MtMode) { @@ -787,7 +974,7 @@ m_OutStream.Init(); CombinedCrc.Init(); - #ifndef _7ZIP_ST + #ifndef Z7_ST NextBlockIndex = 0; StreamWasFinished = false; CloseThreads = false; @@ -799,7 +986,7 @@ WriteByte(kArSig2); WriteByte((Byte)(kArSig3 + _props.BlockSizeMult)); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (MtMode) { @@ -814,7 +1001,7 @@ for (t = 0; t < NumThreads; t++) ThreadsInfo[t].WaitingWasStartedEvent.Lock(); CanStartWaitingEvent.Reset(); - RINOK(Result); + RINOK(Result) } else #endif @@ -822,20 +1009,20 @@ for (;;) { CThreadInfo &ti = - #ifndef _7ZIP_ST - ThreadsInfo[0]; + #ifndef Z7_ST + ThreadsInfo[0]; #else - ThreadsInfo; + ThreadsInfo; #endif - UInt32 blockSize = ReadRleBlock(ti.m_Block); + const UInt32 blockSize = ReadRleBlock(ti.m_Block); if (blockSize == 0) break; - RINOK(ti.EncodeBlock3(blockSize)); + RINOK(ti.EncodeBlock3(blockSize)) if (progress) { const UInt64 unpackSize = m_InStream.GetProcessedSize(); const UInt64 packSize = m_OutStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&unpackSize, &packSize)); + RINOK(progress->SetRatioInfo(&unpackSize, &packSize)) } } } @@ -845,16 +1032,19 @@ WriteByte(kFinSig3); WriteByte(kFinSig4); WriteByte(kFinSig5); - - WriteCrc(CombinedCrc.GetDigest()); - RINOK(Flush()); + { + const UInt32 v = CombinedCrc.GetDigest(); + for (int i = 24; i >= 0; i -= 8) + WriteByte((Byte)(v >> i)); + } + RINOK(Flush()) if (!m_InStream.WasFinished()) return E_FAIL; return S_OK; } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } catch(const CInBufferException &e) { return e.ErrorCode; } @@ -862,21 +1052,28 @@ catch(...) { return S_FALSE; } } -HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { int level = -1; CEncProps props; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID == NCoderPropID::kAffinity) { - if (prop.vt == VT_UI8) - props.Affinity = prop.uhVal.QuadPart; - else + if (prop.vt != VT_UI8) + return E_INVALIDARG; + props.Affinity = prop.uhVal.QuadPart; + continue; + } + + if (propID == NCoderPropID::kNumThreadGroups) + { + if (prop.vt != VT_UI4) return E_INVALIDARG; + props.NumThreadGroups = (UInt32)prop.ulVal; continue; } @@ -884,7 +1081,7 @@ continue; if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; + const UInt32 v = (UInt32)prop.ulVal; switch (propID) { case NCoderPropID::kNumPasses: props.NumPasses = v; break; @@ -892,7 +1089,7 @@ case NCoderPropID::kLevel: level = (int)v; break; case NCoderPropID::kNumThreads: { - #ifndef _7ZIP_ST + #ifndef Z7_ST SetNumberOfThreads(v); #endif break; @@ -905,8 +1102,8 @@ return S_OK; } -#ifndef _7ZIP_ST -STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads) +#ifndef Z7_ST +Z7_COM7F_IMF(CEncoder::SetNumberOfThreads(UInt32 numThreads)) { const UInt32 kNumThreadsMax = 64; if (numThreads < 1) numThreads = 1; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Encoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Encoder.h 2022-02-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Encoder.h 2025-02-28 06:00:00.000000000 +0000 @@ -1,12 +1,11 @@ // BZip2Encoder.h -#ifndef __COMPRESS_BZIP2_ENCODER_H -#define __COMPRESS_BZIP2_ENCODER_H +#ifndef ZIP7_INC_COMPRESS_BZIP2_ENCODER_H +#define ZIP7_INC_COMPRESS_BZIP2_ENCODER_H -#include "../../Common/Defs.h" #include "../../Common/MyCom.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #include "../../Windows/Thread.h" #endif @@ -23,80 +22,114 @@ namespace NCompress { namespace NBZip2 { -class CMsbfEncoderTemp +const unsigned kNumPassesMax = 10; + +struct CMsbfEncoderTemp { - UInt32 _pos; - unsigned _bitPos; - Byte _curByte; + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled Byte *_buf; -public: - void SetStream(Byte *buf) { _buf = buf; } - Byte *GetStream() const { return _buf; } + Byte *_buf_base; + void SetStream(Byte *buf) { _buf_base = _buf = buf; } + Byte *GetStream() const { return _buf_base; } void Init() { - _pos = 0; _bitPos = 8; _curByte = 0; + _buf = _buf_base; } - void Flush() - { - if (_bitPos < 8) - WriteBits(0, _bitPos); - } - + // required condition: (value >> numBits) == 0 + // numBits == 0 is allowed void WriteBits(UInt32 value, unsigned numBits) { - while (numBits > 0) + do { - unsigned numNewBits = MyMin(numBits, _bitPos); - numBits -= numNewBits; - - _curByte = (Byte)(_curByte << numNewBits); - UInt32 newBits = value >> numBits; - _curByte |= Byte(newBits); - value -= (newBits << numBits); - - _bitPos -= numNewBits; - - if (_bitPos == 0) + unsigned bp = _bitPos; + unsigned curByte = _curByte; + if (numBits < bp) { - _buf[_pos++] = _curByte; - _bitPos = 8; + bp -= numBits; + _curByte = curByte | (value << bp); + _bitPos = bp; + return; } + numBits -= bp; + const UInt32 hi = value >> numBits; + value -= (hi << numBits); + Byte *buf = _buf; + _bitPos = 8; + _curByte = 0; + *buf++ = (Byte)(curByte | hi); + _buf = buf; } + while (numBits); } - - UInt32 GetBytePos() const { return _pos ; } - UInt32 GetPos() const { return _pos * 8 + (8 - _bitPos); } - Byte GetCurByte() const { return _curByte; } + + void WriteBit(unsigned value) + { + const unsigned bp = _bitPos - 1; + const unsigned curByte = _curByte | (value << bp); + _curByte = curByte; + _bitPos = bp; + if (bp == 0) + { + *_buf++ = (Byte)curByte; + _curByte = 0; + _bitPos = 8; + } + } + + void WriteByte(unsigned b) + { + const unsigned bp = _bitPos; + const unsigned a = _curByte | (b >> (8 - bp)); + _curByte = b << bp; + Byte *buf = _buf; + *buf++ = (Byte)a; + _buf = buf; + } + + UInt32 GetBytePos() const { return (UInt32)(size_t)(_buf - _buf_base); } + UInt32 GetPos() const { return GetBytePos() * 8 + 8 - _bitPos; } + unsigned GetCurByte() const { return _curByte; } + unsigned GetNonFlushedByteBits() const { return _curByte >> _bitPos; } void SetPos(UInt32 bitPos) { - _pos = bitPos >> 3; + _buf = _buf_base + (bitPos >> 3); _bitPos = 8 - ((unsigned)bitPos & 7); } - void SetCurState(unsigned bitPos, Byte curByte) + void SetCurState(unsigned bitPos, unsigned curByte) { _bitPos = 8 - bitPos; _curByte = curByte; } }; -class CEncoder; -const unsigned kNumPassesMax = 10; +class CEncoder; class CThreadInfo { +private: + CMsbfEncoderTemp m_OutStreamCurrent; public: + CEncoder *Encoder; Byte *m_Block; private: Byte *m_MtfArray; Byte *m_TempArray; UInt32 *m_BlockSorterIndex; - CMsbfEncoderTemp *m_OutStreamCurrent; +public: + bool m_OptimizeNumTables; + UInt32 m_NumCrcs; + UInt32 m_BlockIndex; + UInt64 m_UnpackSize; + + Byte *m_Block_Base; Byte Lens[kNumTablesMax][kMaxAlphaSize]; UInt32 Freqs[kNumTablesMax][kMaxAlphaSize]; @@ -105,22 +138,16 @@ Byte m_Selectors[kNumSelectorsMax]; UInt32 m_CRCs[1 << kNumPassesMax]; - UInt32 m_NumCrcs; - - UInt32 m_BlockIndex; void WriteBits2(UInt32 value, unsigned numBits); - void WriteByte2(Byte b); - void WriteBit2(Byte v); - void WriteCrc2(UInt32 v); + void WriteByte2(unsigned b) { WriteBits2(b, 8); } + void WriteBit2(unsigned v) { m_OutStreamCurrent.WriteBit(v); } void EncodeBlock(const Byte *block, UInt32 blockSize); UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize); void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses); public: - bool m_OptimizeNumTables; - CEncoder *Encoder; - #ifndef _7ZIP_ST +#ifndef Z7_ST NWindows::CThread Thread; NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; @@ -129,15 +156,14 @@ // it's not member of this thread. We just need one event per thread NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; - UInt64 m_UnpackSize; - +public: Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. HRESULT Create(); void FinishStream(bool needLeave); THREAD_FUNC_RET_TYPE ThreadFunc(); - #endif +#endif - CThreadInfo(): m_Block(NULL), m_BlockSorterIndex(NULL) {} + CThreadInfo(): m_BlockSorterIndex(NULL), m_Block_Base(NULL) {} ~CThreadInfo() { Free(); } bool Alloc(); void Free(); @@ -145,39 +171,60 @@ HRESULT EncodeBlock3(UInt32 blockSize); }; + struct CEncProps { UInt32 BlockSizeMult; UInt32 NumPasses; + UInt32 NumThreadGroups; UInt64 Affinity; CEncProps() { BlockSizeMult = (UInt32)(Int32)-1; NumPasses = (UInt32)(Int32)-1; + NumThreadGroups = 0; Affinity = 0; } void Normalize(int level); bool DoOptimizeNumTables() const { return NumPasses > 1; } }; -class CEncoder : +class CEncoder Z7_final: public ICompressCoder, public ICompressSetCoderProperties, - #ifndef _7ZIP_ST + #ifndef Z7_ST public ICompressSetCoderMt, - #endif + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetCoderProperties) + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + #endif + + #ifndef Z7_ST UInt32 m_NumThreadsPrev; + #endif public: CInBuffer m_InStream; + #ifndef Z7_ST Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + #endif CBitmEncoder m_OutStream; CEncProps _props; CBZip2CombinedCrc CombinedCrc; - #ifndef _7ZIP_ST + #ifndef Z7_ST CThreadInfo *ThreadsInfo; NWindows::NSynchronization::CManualResetEvent CanProcessEvent; NWindows::NSynchronization::CCriticalSection CS; @@ -188,56 +235,37 @@ bool CloseThreads; bool StreamWasFinished; NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + CThreadNextGroup ThreadNextGroup; HRESULT Result; ICompressProgressInfo *Progress; - #else + #else CThreadInfo ThreadsInfo; - #endif + #endif UInt64 NumBlocks; UInt64 GetInProcessedSize() const { return m_InStream.GetProcessedSize(); } UInt32 ReadRleBlock(Byte *buf); - void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte); - - void WriteBits(UInt32 value, unsigned numBits); + void WriteBytes(const Byte *data, UInt32 sizeInBits, unsigned lastByteBits); void WriteByte(Byte b); - // void WriteBit(Byte v); - void WriteCrc(UInt32 v); - #ifndef _7ZIP_ST + #ifndef Z7_ST HRESULT Create(); void Free(); - #endif + #endif public: CEncoder(); - #ifndef _7ZIP_ST + #ifndef Z7_ST ~CEncoder(); - #endif + #endif HRESULT Flush() { return m_OutStream.Flush(); } - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - #endif - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - #ifndef _7ZIP_ST - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - #endif }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Register.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Register.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BZip2Register.cpp 2016-04-25 10:02:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BZip2Register.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -5,7 +5,7 @@ #include "../Common/RegisterCodec.h" #include "BZip2Decoder.h" -#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_BZIP2_EXTRACT_ONLY) #include "BZip2Encoder.h" #endif @@ -14,7 +14,7 @@ REGISTER_CODEC_CREATE(CreateDec, CDecoder) -#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_BZIP2_EXTRACT_ONLY) REGISTER_CODEC_CREATE(CreateEnc, CEncoder) #else #define CreateEnc NULL diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Coder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Coder.cpp 2021-01-25 11:14:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.cpp 2023-12-21 11:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include + #include "../../../C/Alloc.h" #include "../Common/StreamUtils.h" @@ -13,42 +15,47 @@ CBaseCoder::CBaseCoder() { - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) { _bufs[i] = NULL; - _bufsCurSizes[i] = 0; - _bufsNewSizes[i] = (1 << 18); + _bufsSizes[i] = 0; + _bufsSizes_New[i] = (1 << 18); } } CBaseCoder::~CBaseCoder() { - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) ::MidFree(_bufs[i]); } HRESULT CBaseCoder::Alloc(bool allocForOrig) { - unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; + const unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; for (unsigned i = 0; i < num; i++) { - UInt32 newSize = _bufsNewSizes[i]; - const UInt32 kMinBufSize = 1; - if (newSize < kMinBufSize) - newSize = kMinBufSize; - if (!_bufs[i] || newSize != _bufsCurSizes[i]) + UInt32 size = _bufsSizes_New[i]; + /* buffer sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP streams + must be aligned for 4 */ + size &= ~(UInt32)3; + const UInt32 kMinBufSize = 4; + if (size < kMinBufSize) + size = kMinBufSize; + // size = 4 * 100; // for debug + // if (BCJ2_IS_32BIT_STREAM(i) == 1) size = 4 * 1; // for debug + if (!_bufs[i] || size != _bufsSizes[i]) { if (_bufs[i]) { ::MidFree(_bufs[i]); - _bufs[i] = 0; + _bufs[i] = NULL; } - _bufsCurSizes[i] = 0; - Byte *buf = (Byte *)::MidAlloc(newSize); - _bufs[i] = buf; + _bufsSizes[i] = 0; + Byte *buf = (Byte *)::MidAlloc(size); if (!buf) return E_OUTOFMEMORY; - _bufsCurSizes[i] = newSize; + _bufs[i] = buf; + _bufsSizes[i] = size; } } return S_OK; @@ -56,23 +63,30 @@ -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -CEncoder::CEncoder(): _relatLim(BCJ2_RELAT_LIMIT) {} +CEncoder::CEncoder(): + _relatLim(BCJ2_ENC_RELAT_LIMIT_DEFAULT) + // , _excludeRangeBits(BCJ2_RELAT_EXCLUDE_NUM_BITS) + {} CEncoder::~CEncoder() {} -STDMETHODIMP CEncoder::SetInBufSize(UInt32, UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } -STDMETHODIMP CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } +Z7_COM7F_IMF(CEncoder::SetInBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } +Z7_COM7F_IMF(CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - UInt32 relatLim = BCJ2_RELAT_LIMIT; - + UInt32 relatLim = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // UInt32 excludeRangeBits = BCJ2_RELAT_EXCLUDE_NUM_BITS; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) + const PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize + // && propID != NCoderPropID::kHashBits + ) continue; switch (propID) { @@ -87,225 +101,310 @@ relatLim = (UInt32)1 << v; break; } + case NCoderPropID::kHashBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = prop.ulVal; + if (v > 31) + return E_INVALIDARG; + excludeRangeBits = v; + break; + } */ case NCoderPropID::kDictionarySize: { if (prop.vt != VT_UI4) return E_INVALIDARG; relatLim = prop.ulVal; - if (relatLim > ((UInt32)1 << 31)) + if (relatLim > BCJ2_ENC_RELAT_LIMIT_MAX) return E_INVALIDARG; break; } - case NCoderPropID::kNumThreads: - continue; case NCoderPropID::kLevel: continue; - default: return E_INVALIDARG; } } - _relatLim = relatLim; - + // _excludeRangeBits = excludeRangeBits; return S_OK; } -HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, +HRESULT CEncoder::CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams, ICompressProgressInfo *progress) { if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS) return E_INVALIDARG; - RINOK(Alloc()); + RINOK(Alloc()) - UInt32 fileSize_for_Conv = 0; + CBcj2Enc_ip_unsigned fileSize_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; if (inSizes && inSizes[0]) { - UInt64 inSize = *inSizes[0]; - if (inSize <= BCJ2_FileSize_MAX) - fileSize_for_Conv = (UInt32)inSize; + const UInt64 inSize = *inSizes[0]; + #ifdef BCJ2_ENC_FileSize_MAX + if (inSize <= BCJ2_ENC_FileSize_MAX) + #endif + fileSize_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(inSize); } - CMyComPtr getSubStreamSize; - inStreams[0]->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + Z7_DECL_CMyComPtr_QI_FROM(ICompressGetSubStreamSize, getSubStreamSize, inStreams[0]) CBcj2Enc enc; - enc.src = _bufs[BCJ2_NUM_STREAMS]; enc.srcLim = enc.src; - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { enc.bufs[i] = _bufs[i]; - enc.lims[i] = _bufs[i] + _bufsCurSizes[i]; + enc.lims[i] = _bufs[i] + _bufsSizes[i]; } } - - size_t numBytes_in_ReadBuf = 0; - UInt64 prevProgress = 0; - UInt64 totalStreamRead = 0; // size read from InputStream - UInt64 currentInPos = 0; // data that was processed, it doesn't include data in input buffer and data in enc.temp - UInt64 outSizeRc = 0; - Bcj2Enc_Init(&enc); - - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; enc.relatLimit = _relatLim; - + // enc.relatExcludeBits = _excludeRangeBits; enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - bool needSubSize = false; - UInt64 subStreamIndex = 0; - UInt64 subStreamStartPos = 0; + // Varibales that correspond processed data in input stream: + UInt64 inPos_without_Temp = 0; // it doesn't include data in enc.temp[] + UInt64 inPos_with_Temp = 0; // it includes data in enc.temp[] + + UInt64 prevProgress = 0; + UInt64 totalRead = 0; // size read from input stream + UInt64 outSizeRc = 0; + UInt64 subStream_Index = 0; + UInt64 subStream_StartPos = 0; // global start offset of subStreams[subStream_Index] + UInt64 subStream_Size = 0; + const Byte *srcLim_Read = _bufs[BCJ2_NUM_STREAMS]; bool readWasFinished = false; + bool isAccurate = false; + bool wasUnknownSize = false; for (;;) { - if (needSubSize && getSubStreamSize) - { - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - for (;;) - { - UInt64 subStreamSize = 0; - HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); - needSubSize = false; - - if (result == S_OK) - { - UInt64 newEndPos = subStreamStartPos + subStreamSize; - - bool isAccurateEnd = (newEndPos < totalStreamRead || - (newEndPos <= totalStreamRead && readWasFinished)); - - if (newEndPos <= currentInPos && isAccurateEnd) - { - subStreamStartPos = newEndPos; - subStreamIndex++; - continue; - } - - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - - if (isAccurateEnd) - { - // data in enc.temp is possible here - size_t rem = (size_t)(totalStreamRead - newEndPos); - - /* Pos_of(enc.src) <= old newEndPos <= newEndPos - in another case, it's fail in some code */ - if ((size_t)(enc.srcLim - enc.src) < rem) - return E_FAIL; - - enc.srcLim -= rem; - enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; - } - - if (subStreamSize <= BCJ2_FileSize_MAX) - { - enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos); - enc.fileSize = (UInt32)subStreamSize; - } - break; - } - - if (result == S_FALSE) - break; - if (result == E_NOTIMPL) - { - getSubStreamSize.Release(); - break; - } - return result; - } - } - - if (readWasFinished && totalStreamRead - currentInPos == Bcj2Enc_Get_InputData_Size(&enc)) + if (readWasFinished && enc.srcLim == srcLim_Read) enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM; + // for debug: + // for (int y=0;y<100;y++) { CBcj2Enc enc2 = enc; Bcj2Enc_Encode(&enc2); } + Bcj2Enc_Encode(&enc); - currentInPos = totalStreamRead - numBytes_in_ReadBuf + (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos; + inPos_with_Temp = totalRead - (size_t)(srcLim_Read - enc.src); + inPos_without_Temp = inPos_with_Temp - Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); + // if (inPos_without_Temp != enc.ip64) return E_FAIL; + if (Bcj2Enc_IsFinished(&enc)) break; if (enc.state < BCJ2_NUM_STREAMS) { + if (enc.bufs[enc.state] != enc.lims[enc.state]) + return E_FAIL; const size_t curSize = (size_t)(enc.bufs[enc.state] - _bufs[enc.state]); // printf("Write stream = %2d %6d\n", enc.state, curSize); - RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)); + RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)) if (enc.state == BCJ2_STREAM_RC) outSizeRc += curSize; - enc.bufs[enc.state] = _bufs[enc.state]; - enc.lims[enc.state] = _bufs[enc.state] + _bufsCurSizes[enc.state]; + enc.lims[enc.state] = _bufs[enc.state] + _bufsSizes[enc.state]; } - else if (enc.state != BCJ2_ENC_STATE_ORIG) - return E_FAIL; else { - needSubSize = true; + if (enc.state != BCJ2_ENC_STATE_ORIG) + return E_FAIL; + // (enc.state == BCJ2_ENC_STATE_ORIG) + if (enc.src != enc.srcLim) + return E_FAIL; + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE + && Bcj2Enc_Get_AvailInputSize_in_Temp(&enc) != 0) + return E_FAIL; + + if (enc.src == srcLim_Read) + { + if (readWasFinished) + return E_FAIL; + UInt32 curSize = _bufsSizes[BCJ2_NUM_STREAMS]; + RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)) + // printf("Read %6u bytes\n", curSize); + if (curSize == 0) + readWasFinished = true; + totalRead += curSize; + enc.src = _bufs[BCJ2_NUM_STREAMS]; + srcLim_Read = _bufs[BCJ2_NUM_STREAMS] + curSize; + } + enc.srcLim = srcLim_Read; - if (numBytes_in_ReadBuf != (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS])) + if (getSubStreamSize) { - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - continue; - } + /* we set base default conversions options that will be used, + if subStream related options will be not OK */ + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; + for (;;) + { + UInt64 nextPos; + if (isAccurate) + nextPos = subStream_StartPos + subStream_Size; + else + { + const HRESULT hres = getSubStreamSize->GetSubStreamSize(subStream_Index, &subStream_Size); + if (hres != S_OK) + { + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* if sub-stream size is unknown, we use default settings. + We still can recover to normal mode for next sub-stream, + if GetSubStreamSize() will return S_OK, when current + sub-stream will be finished. + */ + if (hres == S_FALSE) + { + wasUnknownSize = true; + break; + } + if (hres == E_NOTIMPL) + { + getSubStreamSize.Release(); + break; + } + return hres; + } + // printf("GetSubStreamSize %6u : %6u \n", (unsigned)subStream_Index, (unsigned)subStream_Size); + nextPos = subStream_StartPos + subStream_Size; + if ((Int64)subStream_Size == -1) + { + /* it's not expected, but (-1) can mean unknown size. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + wasUnknownSize = true; + break; + } + if (nextPos < subStream_StartPos) + return E_FAIL; + isAccurate = + (nextPos < totalRead + || (nextPos <= totalRead && readWasFinished)); + } + + /* (nextPos) is estimated end position of current sub_stream. + But only (totalRead) and (readWasFinished) values + can confirm that this estimated end position is accurate. + That end position is accurate, if it can't be changed in + further calls of GetSubStreamSize() */ + + /* (nextPos < inPos_with_Temp) is unexpected case here, that we + can get if from some incorrect ICompressGetSubStreamSize object, + where new GetSubStreamSize() call returns smaller size than + confirmed by Read() size from previous GetSubStreamSize() call. + */ + if (nextPos < inPos_with_Temp) + { + if (wasUnknownSize) + { + /* that case can be complicated for recovering. + so we disable sub-streams requesting. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + getSubStreamSize.Release(); + break; + } + return E_FAIL; // to stop after failure + } - if (readWasFinished) - continue; - - numBytes_in_ReadBuf = 0; - enc.src = _bufs[BCJ2_NUM_STREAMS]; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS]; - - UInt32 curSize = _bufsCurSizes[BCJ2_NUM_STREAMS]; - RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)); + if (nextPos <= inPos_with_Temp) + { + // (nextPos == inPos_with_Temp) + /* CBcj2Enc encoder requires to finish each [non-empty] block (sub-stream) + with BCJ2_ENC_FINISH_MODE_END_BLOCK + or with BCJ2_ENC_FINISH_MODE_END_STREAM for last block: + And we send data of new block to CBcj2Enc, only if previous block was finished. + So we switch to next sub-stream if after Bcj2Enc_Encode() call we have + && (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + && (nextPos == inPos_with_Temp) + && (enc.state == BCJ2_ENC_STATE_ORIG) + */ + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + { + /* subStream_StartPos is increased only here. + (subStream_StartPos == inPos_with_Temp) : at start + (subStream_StartPos <= inPos_with_Temp) : will be later + */ + subStream_StartPos = nextPos; + subStream_Size = 0; + wasUnknownSize = false; + subStream_Index++; + isAccurate = false; + // we don't change finishMode here + continue; + } + } + + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* for (!isAccurate) case: + (totalRead <= real_end_of_subStream) + so we can use BCJ2_ENC_FINISH_MODE_CONTINUE up to (totalRead) + // we don't change settings at the end of substream, if settings were unknown, + */ + + /* if (wasUnknownSize) then we can't trust size of that sub-stream. + so we use default settings instead */ + if (!wasUnknownSize) + #ifdef BCJ2_ENC_FileSize_MAX + if (subStream_Size <= BCJ2_ENC_FileSize_MAX) + #endif + { + enc.fileIp64 = + (CBcj2Enc_ip_unsigned)( + (CBcj2Enc_ip_signed)enc.ip64 + + (CBcj2Enc_ip_signed)(subStream_StartPos - inPos_without_Temp)); + Bcj2Enc_SET_FileSize(&enc, subStream_Size) + } - // printf("Read %6d bytes\n", curSize); - if (curSize == 0) - { - readWasFinished = true; - continue; - } + if (isAccurate) + { + /* (real_end_of_subStream == nextPos <= totalRead) + So we can use BCJ2_ENC_FINISH_MODE_END_BLOCK up to (nextPos). */ + const size_t rem = (size_t)(totalRead - nextPos); + if ((size_t)(enc.srcLim - enc.src) < rem) + return E_FAIL; + enc.srcLim -= rem; + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; + } - numBytes_in_ReadBuf = curSize; - totalStreamRead += numBytes_in_ReadBuf; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; + break; + } // for() loop + } // getSubStreamSize } - if (progress && currentInPos - prevProgress >= (1 << 20)) + if (progress && inPos_without_Temp - prevProgress >= (1 << 22)) { - const UInt64 outSize2 = currentInPos + outSizeRc + (size_t)(enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC]); - prevProgress = currentInPos; - // printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2); - RINOK(progress->SetRatioInfo(¤tInPos, &outSize2)); + prevProgress = inPos_without_Temp; + const UInt64 outSize2 = inPos_without_Temp + outSizeRc + + (size_t)(enc.bufs[BCJ2_STREAM_RC] - _bufs[BCJ2_STREAM_RC]); + // printf("progress %8u, %8u\n", (unsigned)inSize2, (unsigned)outSize2); + RINOK(progress->SetRatioInfo(&inPos_without_Temp, &outSize2)) } } - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - RINOK(WriteStream(outStreams[i], _bufs[i], (size_t)(enc.bufs[i] - _bufs[i]))); + RINOK(WriteStream(outStreams[i], _bufs[i], (size_t)(enc.bufs[i] - _bufs[i]))) } - - // if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL; - + // if (inPos_without_Temp != subStream_StartPos + subStream_Size) return E_FAIL; return S_OK; } -STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + +Z7_COM7F_IMF(CEncoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { try { @@ -321,141 +420,170 @@ -STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } - -CDecoder::CDecoder(): _finishMode(false), _outSizeDefined(false), _outSize(0) +CDecoder::CDecoder(): + _finishMode(false) +#ifndef Z7_NO_READ_FROM_CODER + , _outSizeDefined(false) + , _outSize(0) + , _outSize_Processed(0) +#endif {} -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { _finishMode = (finishMode != 0); return S_OK; } -void CDecoder::InitCommon() +void CBaseDecoder::InitCommon() { + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - dec.lims[i] = dec.bufs[i] = _bufs[i]; + dec.lims[i] = dec.bufs[i] = _bufs[i]; + _readRes[i] = S_OK; + _extraSizes[i] = 0; + _readSizes[i] = 0; } + Bcj2Dec_Init(&dec); +} + +/* call ReadInStream() only after Bcj2Dec_Decode(). + input requirement: + (dec.state < BCJ2_NUM_STREAMS) +*/ +void CBaseDecoder::ReadInStream(ISequentialInStream *inStream) +{ + const unsigned state = dec.state; + UInt32 total; + { + Byte *buf = _bufs[state]; + const Byte *cur = dec.bufs[state]; + // if (cur != dec.lims[state]) throw 1; // unexpected case + dec.lims[state] = + dec.bufs[state] = buf; + total = (UInt32)_extraSizes[state]; + for (UInt32 i = 0; i < total; i++) + buf[i] = cur[i]; + } + + if (_readRes[state] != S_OK) + return; + + do { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + UInt32 curSize = _bufsSizes[state] - total; + // if (state == 0) curSize = 0; // for debug + // curSize = 7; // for debug + /* even if we have reached provided inSizes[state] limit, + we call Read() with (curSize != 0), because + we want the called handler of stream->Read() could + execute required Init/Flushing code even for empty stream. + In another way we could call Read() with (curSize == 0) for + finished streams, but some Read() handlers can ignore Read(size=0) calls. + */ + const HRESULT hres = inStream->Read(_bufs[state] + total, curSize, &curSize); + _readRes[state] = hres; + if (curSize == 0) + break; + _readSizes[state] += curSize; + total += curSize; + if (hres != S_OK) + break; + } + while (total < 4 && BCJ2_IS_32BIT_STREAM(state)); + + /* we exit from decoding loop here, if we can't + provide new data for input stream. + Usually it's normal exit after full stream decoding. */ + if (total == 0) + return; + + if (BCJ2_IS_32BIT_STREAM(state)) + { + const unsigned extra = (unsigned)total & 3; + _extraSizes[state] = extra; + if (total < 4) { - _extraReadSizes[i] = 0; - _inStreamsProcessed[i] = 0; - _readRes[i] = S_OK; + if (_readRes[state] == S_OK) + _readRes[state] = S_FALSE; // actually it's stream error. So maybe we need another error code. + return; } + total -= (UInt32)extra; } - - Bcj2Dec_Init(&dec); + + dec.lims[state] += total; // = _bufs[state] + total; } -HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + +Z7_COM7F_IMF(CDecoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1) return E_INVALIDARG; - RINOK(Alloc()); - + RINOK(Alloc()) InitCommon(); dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS]; - UInt64 outSizeProcessed = 0; + UInt64 outSizeWritten = 0; UInt64 prevProgress = 0; - HRESULT res = S_OK; + HRESULT hres_Crit = S_OK; // critical hres status (mostly from input stream reading) + HRESULT hres_Weak = S_OK; // first non-critical error code from input stream reading for (;;) { if (Bcj2Dec_Decode(&dec) != SZ_OK) - return S_FALSE; - + { + /* it's possible only at start (first 5 bytes in RC stream) */ + hres_Crit = S_FALSE; + break; + } if (dec.state < BCJ2_NUM_STREAMS) { - size_t totalRead = _extraReadSizes[dec.state]; - { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) + ReadInStream(inStreams[dec.state]); + const unsigned state = dec.state; + const HRESULT hres = _readRes[state]; + if (dec.lims[state] == _bufs[state]) { - res = _readRes[dec.state]; + // we break decoding, if there are no new data in input stream + hres_Crit = hres; break; } - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - /* - we want to call Read even even if size is 0 - if (inSizes && inSizes[dec.state]) - { - UInt64 rem = *inSizes[dec.state] - _inStreamsProcessed[dec.state]; - if (curSize > rem) - curSize = (UInt32)rem; - } - */ - - HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (_readRes[dec.state] != S_OK) - res = _readRes[dec.state]; - - if (totalRead == 0) - break; - - // res == S_OK; - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - res = (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - break; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; + if (hres != S_OK && hres_Weak == S_OK) + hres_Weak = hres; } - else // if (dec.state <= BCJ2_STATE_ORIG) + else // (BCJ2_DEC_STATE_ORIG_0 <= state <= BCJ2_STATE_ORIG) { - const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); - if (curSize != 0) { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } } - dec.dest = _bufs[BCJ2_NUM_STREAMS]; { - size_t rem = _bufsCurSizes[BCJ2_NUM_STREAMS]; + UInt32 rem = _bufsSizes[BCJ2_NUM_STREAMS]; if (outSizes && outSizes[0]) { - UInt64 outSize = *outSizes[0] - outSizeProcessed; + const UInt64 outSize = *outSizes[0] - outSizeWritten; if (rem > outSize) - rem = (size_t)outSize; + rem = (UInt32)outSize; } + dec.dest = _bufs[BCJ2_NUM_STREAMS]; dec.destLim = dec.dest + rem; + /* we exit from decoding loop here, + if (outSizes[0]) limit for output stream was reached */ if (rem == 0) break; } @@ -463,98 +591,148 @@ if (progress) { - const UInt64 outSize2 = outSizeProcessed + (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); - if (outSize2 - prevProgress >= (1 << 22)) + // here we don't count additional data in dec.temp (up to 4 bytes for output stream) + const UInt64 processed = outSizeWritten + (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (processed - prevProgress >= (1 << 24)) { - const UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (size_t)(dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]); - RINOK(progress->SetRatioInfo(&inSize2, &outSize2)); - prevProgress = outSize2; + prevProgress = processed; + const UInt64 inSize = processed + + _readSizes[BCJ2_STREAM_RC] - (size_t)( + dec.lims[BCJ2_STREAM_RC] - + dec.bufs[BCJ2_STREAM_RC]); + RINOK(progress->SetRatioInfo(&inSize, &prevProgress)) } } } - const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); - if (curSize != 0) { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } } - if (res != S_OK) - return res; + if (hres_Crit == S_OK) hres_Crit = hres_Weak; + if (hres_Crit != S_OK) return hres_Crit; if (_finishMode) { - if (!Bcj2Dec_IsFinished(&dec)) + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) return S_FALSE; - // we still allow the cases when input streams are larger than required for decoding. - // so the case (dec.state == BCJ2_STATE_ORIG) is also allowed, if MAIN stream is larger than required. - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) + /* here we support two correct ways to finish full stream decoding + with one of the following conditions: + - the end of input stream MAIN was reached + - the end of output stream ORIG was reached + Currently 7-Zip/7z code ends with (state == BCJ2_STREAM_MAIN), + because the sizes of MAIN and ORIG streams are known and these + sizes are stored in 7z archive headers. + And Bcj2Dec_Decode() exits with (state == BCJ2_STREAM_MAIN), + if both MAIN and ORIG streams have reached buffers limits. + But if the size of MAIN stream is not known or if the + size of MAIN stream includes some padding after payload data, + then we still can correctly finish decoding with + (state == BCJ2_DEC_STATE_ORIG), if we know the exact size + of output ORIG stream. + */ + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + + /* the caller also will know written size. + So the following check is optional: */ + if (outSizes && outSizes[0] && *outSizes[0] != outSizeWritten) return S_FALSE; if (inSizes) { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - const size_t rem = (size_t)(dec.lims[i] - dec.bufs[i]) + _extraReadSizes[i]; - /* - if (rem != 0) - return S_FALSE; - */ - if (inSizes[i] && *inSizes[i] != _inStreamsProcessed[i] - rem) + /* if (inSizes[i]) is defined, we do full check for processed stream size. */ + if (inSizes[i] && *inSizes[i] != GetProcessedSize_ForInStream(i)) return S_FALSE; } } + + /* v23.02: we call Read(0) for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP streams, + if there were no Read() calls for such stream. + So the handlers of these input streams objects can do + Init/Flushing even for case when stream is empty: + */ + for (unsigned i = BCJ2_STREAM_CALL; i < BCJ2_STREAM_CALL + 2; i++) + { + if (_readSizes[i]) + continue; + Byte b; + UInt32 processed; + RINOK(inStreams[i]->Read(&b, 0, &processed)) + } } return S_OK; } -STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream) + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +{ + *value = GetProcessedSize_ForInStream(streamIndex); + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) { _inStreams[streamIndex] = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream2(UInt32 streamIndex) +Z7_COM7F_IMF(CDecoder::ReleaseInStream2(UInt32 streamIndex)) { _inStreams[streamIndex].Release(); return S_OK; } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { _outSizeDefined = (outSize != NULL); _outSize = 0; if (_outSizeDefined) _outSize = *outSize; - _outSize_Processed = 0; - HRESULT res = Alloc(false); - + const HRESULT res = Alloc(false); // allocForOrig InitCommon(); dec.destLim = dec.dest = NULL; - return res; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - if (size == 0) - return S_OK; + /* Note the case: + The output (ORIG) stream can be empty. + But BCJ2_STREAM_RC stream always is not empty. + And we want to support full data processing for all streams. + We disable check (size == 0) here. + So if the caller calls this CDecoder::Read() with (size == 0), + we execute required Init/Flushing code in this CDecoder object. + Also this CDecoder::Read() function will call Read() for input streams. + So the handlers of input streams objects also can do Init/Flushing. + */ + // if (size == 0) return S_OK; // disabled to allow (size == 0) processing UInt32 totalProcessed = 0; if (_outSizeDefined) { - UInt64 rem = _outSize - _outSize_Processed; + const UInt64 rem = _outSize - _outSize_Processed; if (size > rem) size = (UInt32)rem; } @@ -565,102 +743,125 @@ for (;;) { - SRes sres = Bcj2Dec_Decode(&dec); - if (sres != SZ_OK) - return S_FALSE; - + if (Bcj2Dec_Decode(&dec) != SZ_OK) + return S_FALSE; // this error can be only at start of stream { - UInt32 curSize = (UInt32)(dec.dest - (Byte *)data); + const UInt32 curSize = (UInt32)(size_t)(dec.dest - (Byte *)data); if (curSize != 0) { - totalProcessed += curSize; - if (processedSize) - *processedSize = totalProcessed; data = (void *)((Byte *)data + curSize); size -= curSize; _outSize_Processed += curSize; + totalProcessed += curSize; + if (processedSize) + *processedSize = totalProcessed; } } - if (dec.state >= BCJ2_NUM_STREAMS) break; - + ReadInStream(_inStreams[dec.state]); + if (dec.lims[dec.state] == _bufs[dec.state]) { - size_t totalRead = _extraReadSizes[dec.state]; - { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) - return _readRes[dec.state]; - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - HRESULT res2 = _inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (totalRead == 0) - { - if (totalProcessed == 0) - res = _readRes[dec.state]; - break; - } - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - if (totalProcessed != 0) - return S_OK; - return (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; + /* we break decoding, if there are no new data in input stream. + and we ignore error code, if some data were written to output buffer. */ + if (totalProcessed == 0) + res = _readRes[dec.state]; + break; } } + if (res == S_OK) if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed) { - if (!Bcj2Dec_IsFinished(&dec)) + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) return S_FALSE; - - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) return S_FALSE; - - /* - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - if (dec.bufs[i] != dec.lims[i] || _extraReadSizes[i] != 0) - return S_FALSE; - */ } return res; } +#endif + +}} + -STDMETHODIMP CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value) +/* +extern "C" { - const size_t rem = (size_t)(dec.lims[streamIndex] - dec.bufs[streamIndex]) + _extraReadSizes[streamIndex]; - *value = _inStreamsProcessed[streamIndex] - rem; - return S_OK; +extern UInt32 bcj2_stats[256 + 2][2]; } -}} +static class CBcj2Stat +{ +public: + ~CBcj2Stat() + { + printf("\nBCJ2 stat:"); + unsigned sums[2] = { 0, 0 }; + int i; + for (i = 2; i < 256 + 2; i++) + { + sums[0] += bcj2_stats[i][0]; + sums[1] += bcj2_stats[i][1]; + } + const unsigned sums2 = sums[0] + sums[1]; + for (int vi = 0; vi < 256 + 3; vi++) + { + printf("\n"); + UInt32 n0, n1; + if (vi < 4) + printf("\n"); + + if (vi < 2) + i = vi; + else if (vi == 2) + i = -1; + else + i = vi - 1; + + if (i < 0) + { + n0 = sums[0]; + n1 = sums[1]; + printf("calls :"); + } + else + { + if (i == 0) + printf("jcc :"); + else if (i == 1) + printf("jump :"); + else + printf("call %02x :", i - 2); + n0 = bcj2_stats[i][0]; + n1 = bcj2_stats[i][1]; + } + + const UInt32 sum = n0 + n1; + printf(" %10u", sum); + + #define PRINT_PERC(val, sum) \ + { UInt32 _sum = sum; if (_sum == 0) _sum = 1; \ + printf(" %7.3f %%", (double)((double)val * (double)100 / (double)_sum )); } + + if (i >= 2 || i < 0) + { + PRINT_PERC(sum, sums2); + } + else + printf("%10s", ""); + + printf(" :%10u", n0); + PRINT_PERC(n0, sum); + + printf(" :%10u", n1); + PRINT_PERC(n1, sum); + } + printf("\n\n"); + fflush(stdout); + } +} g_CBcjStat; +*/ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Coder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Coder.h 2016-12-28 15:40:58.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Coder.h 2023-02-22 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Bcj2Coder.h -#ifndef __COMPRESS_BCJ2_CODER_H -#define __COMPRESS_BCJ2_CODER_H +#ifndef ZIP7_INC_COMPRESS_BCJ2_CODER_H +#define ZIP7_INC_COMPRESS_BCJ2_CODER_H #include "../../../C/Bcj2.h" @@ -16,8 +16,8 @@ { protected: Byte *_bufs[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsCurSizes[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsNewSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes_New[BCJ2_NUM_STREAMS + 1]; HRESULT Alloc(bool allocForOrig = true); public: @@ -26,92 +26,99 @@ }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public ICompressCoder2, public ICompressSetCoderProperties, public ICompressSetBufSize, public CMyUnknownImp, public CBaseCoder { + Z7_IFACES_IMP_UNK_3( + ICompressCoder2, + ICompressSetCoderProperties, + ICompressSetBufSize) + UInt32 _relatLim; + // UInt32 _excludeRangeBits; - HRESULT CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + HRESULT CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); - public: - MY_UNKNOWN_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize) - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - CEncoder(); ~CEncoder(); }; #endif -class CDecoder: + + +class CBaseDecoder: public CBaseCoder +{ +protected: + HRESULT _readRes[BCJ2_NUM_STREAMS]; + unsigned _extraSizes[BCJ2_NUM_STREAMS]; + UInt64 _readSizes[BCJ2_NUM_STREAMS]; + + CBcj2Dec dec; + + UInt64 GetProcessedSize_ForInStream(unsigned i) const + { + return _readSizes[i] - ((size_t)(dec.lims[i] - dec.bufs[i]) + _extraSizes[i]); + } + void InitCommon(); + void ReadInStream(ISequentialInStream *inStream); +}; + + +class CDecoder Z7_final: public ICompressCoder2, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize2, + public ICompressSetBufSize, +#ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream2, - public ISequentialInStream, public ICompressSetOutStreamSize, - public ICompressSetBufSize, + public ISequentialInStream, +#endif public CMyUnknownImp, - public CBaseCoder + public CBaseDecoder { - unsigned _extraReadSizes[BCJ2_NUM_STREAMS]; - UInt64 _inStreamsProcessed[BCJ2_NUM_STREAMS]; - HRESULT _readRes[BCJ2_NUM_STREAMS]; - CMyComPtr _inStreams[BCJ2_NUM_STREAMS]; + Z7_COM_QI_BEGIN2(ICompressCoder2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize2) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream2) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize2) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetInStream2) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ISequentialInStream) +#endif bool _finishMode; + +#ifndef Z7_NO_READ_FROM_CODER bool _outSizeDefined; UInt64 _outSize; UInt64 _outSize_Processed; - CBcj2Dec dec; - - void InitCommon(); - // HRESULT ReadSpec(); - + CMyComPtr _inStreams[BCJ2_NUM_STREAMS]; +#endif + public: - MY_UNKNOWN_IMP7( - ICompressCoder2, - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize2, - ICompressSetInStream2, - ISequentialInStream, - ICompressSetOutStreamSize, - ICompressSetBufSize - ); - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value); - - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex); - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - CDecoder(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Register.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Register.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Bcj2Register.cpp 2019-03-28 11:32:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Bcj2Register.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -10,7 +10,7 @@ namespace NBcj2 { REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2) -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2) #else #define CreateCodecOut NULL diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BcjCoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BcjCoder.cpp 2016-04-25 10:18:10.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.cpp 2023-03-27 18:00:00.000000000 +0000 @@ -7,17 +7,17 @@ namespace NCompress { namespace NBcj { -STDMETHODIMP CCoder::Init() +Z7_COM7F_IMF(CCoder2::Init()) { - _bufferPos = 0; - x86_Convert_Init(_prevMask); + _pc = 0; + _state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; return S_OK; } -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CCoder2::Filter(Byte *data, UInt32 size)) { - UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); - _bufferPos += processed; + const UInt32 processed = (UInt32)(size_t)(_convFunc(data, size, _pc, &_state) - data); + _pc += processed; return processed; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BcjCoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BcjCoder.h 2016-04-25 10:17:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjCoder.h 2023-03-01 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // BcjCoder.h -#ifndef __COMPRESS_BCJ_CODER_H -#define __COMPRESS_BCJ_CODER_H +#ifndef ZIP7_INC_COMPRESS_BCJ_CODER_H +#define ZIP7_INC_COMPRESS_BCJ_CODER_H #include "../../../C/Bra.h" @@ -12,18 +12,24 @@ namespace NCompress { namespace NBcj { -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - UInt32 _prevMask; - int _encode; +/* CCoder in old versions used another constructor parameter CCoder(int encode). + And some code called it as CCoder(0). + We have changed constructor parameter type. + So we have changed the name of class also to CCoder2. */ + +Z7_CLASS_IMP_COM_1( + CCoder2 + , ICompressFilter +) + UInt32 _pc; + UInt32 _state; + z7_Func_BranchConvSt _convFunc; public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) - - CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } + CCoder2(z7_Func_BranchConvSt convFunc): + _pc(0), + _state(Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL), + _convFunc(convFunc) + {} }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BcjRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BcjRegister.cpp 2016-04-25 10:17:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BcjRegister.cpp 2023-02-20 11:00:00.000000000 +0000 @@ -10,8 +10,8 @@ namespace NBcj { REGISTER_FILTER_E(BCJ, - CCoder(false), - CCoder(true), + CCoder2(z7_BranchConvSt_X86_Dec), + CCoder2(z7_BranchConvSt_X86_Enc), 0x3030103, "BCJ") }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BitlDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BitlDecoder.cpp 2021-01-23 08:09:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.cpp 2023-12-24 13:00:00.000000000 +0000 @@ -6,20 +6,27 @@ namespace NBitl { -Byte kInvertTable[256]; +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) + +MY_ALIGN(64) +Byte kReverseTable[256]; static -struct CInverterTableInitializer +struct CReverseerTableInitializer { - CInverterTableInitializer() + CReverseerTableInitializer() { for (unsigned i = 0; i < 256; i++) { - unsigned x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); - x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); - kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4)); + unsigned + x = ((i & 0x55) << 1) | ((i >> 1) & 0x55); + x = ((x & 0x33) << 2) | ((x >> 2) & 0x33); + kReverseTable[i] = (Byte)((x << 4) | (x >> 4)); } } -} g_InverterTableInitializer; +} g_ReverseerTableInitializer; +#elif 0 +unsigned ReverseBits8test(unsigned i) { return ReverseBits8(i); } +#endif } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BitlDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BitlDecoder.h 2022-01-28 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlDecoder.h 2023-12-25 11:00:00.000000000 +0000 @@ -1,7 +1,9 @@ // BitlDecoder.h -- the Least Significant Bit of byte is First -#ifndef __BITL_DECODER_H -#define __BITL_DECODER_H +#ifndef ZIP7_INC_BITL_DECODER_H +#define ZIP7_INC_BITL_DECODER_H + +#include "../../../C/CpuArch.h" #include "../IStream.h" @@ -10,10 +12,50 @@ const unsigned kNumBigValueBits = 8 * 4; const unsigned kNumValueBytes = 3; const unsigned kNumValueBits = 8 * kNumValueBytes; - const UInt32 kMask = (1 << kNumValueBits) - 1; -extern Byte kInvertTable[256]; +#if !defined(Z7_BITL_USE_REVERSE_BITS_TABLE) +#if 1 && defined(MY_CPU_ARM_OR_ARM64) \ + && (defined(MY_CPU_ARM64) || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) \ + && (defined(__GNUC__) && (__GNUC__ >= 4) \ + || defined(__clang__) && (__clang_major__ >= 4)) + #define Z7_BITL_USE_REVERSE_BITS_INSTRUCTION +#elif 1 + #define Z7_BITL_USE_REVERSE_BITS_TABLE +#endif +#endif + +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) +extern Byte kReverseTable[256]; +#endif + +inline unsigned ReverseBits8(unsigned i) +{ +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) + return kReverseTable[i]; +#elif defined(Z7_BITL_USE_REVERSE_BITS_INSTRUCTION) + // rbit is available in ARMv6T2 and above + asm ("rbit " +#if defined(MY_CPU_ARM) + "%0,%0" // it uses default register size, + // but we need 32-bit register here. + // we must use it only if default register size is 32-bit. + // it will work incorrectly for ARM64. +#else + "%w0,%w0" // it uses 32-bit registers in ARM64. + // compiler for (MY_CPU_ARM) can't compile it. +#endif + : "+r" (i)); + return i >> 24; +#else + unsigned + x = ((i & 0x55) << 1) | ((i >> 1) & 0x55); + x = ((x & 0x33) << 2) | ((x >> 2) & 0x33); + return ((x & 0x0f) << 4) | (x >> 4); +#endif +} + /* TInByte must support "Extra Bytes" (bytes that can be read after the end of stream TInByte::ReadByte() returns 0xFF after the end of stream @@ -31,6 +73,7 @@ public: bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream); } + void ClearStreamPtr() { _stream.ClearStreamPtr(); } void Init() { _stream.Init(); @@ -54,14 +97,14 @@ bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; } - MY_FORCE_INLINE + Z7_FORCE_INLINE void Normalize() { for (; _bitPos >= 8; _bitPos -= 8) _value = ((UInt32)_stream.ReadByte() << (kNumBigValueBits - _bitPos)) | _value; } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 ReadBits(unsigned numBits) { Normalize(); @@ -102,32 +145,39 @@ _normalValue = 0; } - MY_FORCE_INLINE + Z7_FORCE_INLINE void Normalize() { for (; this->_bitPos >= 8; this->_bitPos -= 8) { - Byte b = this->_stream.ReadByte(); + const unsigned b = this->_stream.ReadByte(); _normalValue = ((UInt32)b << (kNumBigValueBits - this->_bitPos)) | _normalValue; - this->_value = (this->_value << 8) | kInvertTable[b]; + this->_value = (this->_value << 8) | ReverseBits8(b); } } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 GetValue(unsigned numBits) { Normalize(); return ((this->_value >> (8 - this->_bitPos)) & kMask) >> (kNumValueBits - numBits); } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() + { + Normalize(); + return this->_value << this->_bitPos; + } - MY_FORCE_INLINE - void MovePos(unsigned numBits) + Z7_FORCE_INLINE + void MovePos(size_t numBits) { - this->_bitPos += numBits; + this->_bitPos += (unsigned)numBits; _normalValue >>= numBits; } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 ReadBits(unsigned numBits) { Normalize(); @@ -138,10 +188,13 @@ void AlignToByte() { MovePos((32 - this->_bitPos) & 7); } - MY_FORCE_INLINE + Z7_FORCE_INLINE Byte ReadDirectByte() { return this->_stream.ReadByte(); } + + Z7_FORCE_INLINE + size_t ReadDirectBytesPart(Byte *buf, size_t size) { return this->_stream.ReadBytesPart(buf, size); } - MY_FORCE_INLINE + Z7_FORCE_INLINE Byte ReadAlignedByte() { if (this->_bitPos == kNumBigValueBits) @@ -152,7 +205,7 @@ } // call it only if the object is aligned for byte. - MY_FORCE_INLINE + Z7_FORCE_INLINE bool ReadAlignedByte_FromBuf(Byte &b) { if (this->_stream.NumExtraBytes != 0) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BitlEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BitlEncoder.h 2021-01-28 08:49:33.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitlEncoder.h 2025-03-13 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // BitlEncoder.h -- the Least Significant Bit of byte is First -#ifndef __BITL_ENCODER_H -#define __BITL_ENCODER_H +#ifndef ZIP7_INC_BITL_ENCODER_H +#define ZIP7_INC_BITL_ENCODER_H #include "../Common/OutBuffer.h" @@ -33,6 +33,7 @@ _bitPos = 8; _curByte = 0; } + Z7_FORCE_INLINE void WriteBits(UInt32 value, unsigned numBits) { while (numBits > 0) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BitmDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BitmDecoder.h 2017-04-28 09:57:53.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmDecoder.h 2023-12-25 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // BitmDecoder.h -- the Most Significant Bit of byte is First -#ifndef __BITM_DECODER_H -#define __BITM_DECODER_H +#ifndef ZIP7_INC_BITM_DECODER_H +#define ZIP7_INC_BITM_DECODER_H #include "../IStream.h" @@ -47,28 +47,34 @@ return (_stream.NumExtraBytes > 4); } - MY_FORCE_INLINE + Z7_FORCE_INLINE void Normalize() { for (; _bitPos >= 8; _bitPos -= 8) _value = (_value << 8) | _stream.ReadByte(); } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 GetValue(unsigned numBits) const { // return (_value << _bitPos) >> (kNumBigValueBits - numBits); return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits); } - MY_FORCE_INLINE + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() const + { + return this->_value << this->_bitPos; + } + + Z7_FORCE_INLINE void MovePos(unsigned numBits) { _bitPos += numBits; Normalize(); } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 ReadBits(unsigned numBits) { UInt32 res = GetValue(numBits); @@ -91,7 +97,7 @@ void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BitmEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BitmEncoder.h 2021-04-01 09:36:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BitmEncoder.h 2025-02-28 06:00:00.000000000 +0000 @@ -1,15 +1,16 @@ // BitmEncoder.h -- the Most Significant Bit of byte is First -#ifndef __BITM_ENCODER_H -#define __BITM_ENCODER_H +#ifndef ZIP7_INC_BITM_ENCODER_H +#define ZIP7_INC_BITM_ENCODER_H #include "../IStream.h" template class CBitmEncoder { - unsigned _bitPos; - Byte _curByte; + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled TOutByte _stream; public: bool Create(UInt32 bufferSize) { return _stream.Create(bufferSize); } @@ -24,25 +25,65 @@ HRESULT Flush() { if (_bitPos < 8) - WriteBits(0, _bitPos); + { + _stream.WriteByte((Byte)_curByte); + _bitPos = 8; + _curByte = 0; + } return _stream.Flush(); } + + // required condition: (value >> numBits) == 0 + // numBits == 0 is allowed void WriteBits(UInt32 value, unsigned numBits) { - while (numBits > 0) + do { - if (numBits < _bitPos) + unsigned bp = _bitPos; + unsigned curByte = _curByte; + if (numBits < bp) { - _curByte = (Byte)(_curByte | (value << (_bitPos -= numBits))); + bp -= numBits; + _curByte = curByte | (value << bp); + _bitPos = bp; return; } - numBits -= _bitPos; - UInt32 newBits = (value >> numBits); - value -= (newBits << numBits); - _stream.WriteByte((Byte)(_curByte | newBits)); + numBits -= bp; + const UInt32 hi = (value >> numBits); + value -= (hi << numBits); + _stream.WriteByte((Byte)(curByte | hi)); _bitPos = 8; _curByte = 0; } + while (numBits); + } + void WriteByte(unsigned b) + { + const unsigned bp = _bitPos; + const unsigned a = _curByte | (b >> (8 - bp)); + _curByte = b << bp; + _stream.WriteByte((Byte)a); + } + + void WriteBytes(const Byte *data, size_t num) + { + const unsigned bp = _bitPos; +#if 1 // 1 for optional speed-optimized code branch + if (bp == 8) + { + _stream.WriteBytes(data, num); + return; + } +#endif + unsigned c = _curByte; + const unsigned bp_rev = 8 - bp; + for (size_t i = 0; i < num; i++) + { + const unsigned b = data[i]; + _stream.WriteByte((Byte)(c | (b >> bp_rev))); + c = b << bp; + } + _curByte = c; } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BranchMisc.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BranchMisc.cpp 2016-04-25 10:09:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.cpp 2024-02-17 10:00:00.000000000 +0000 @@ -2,22 +2,105 @@ #include "StdAfx.h" +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + #include "BranchMisc.h" namespace NCompress { namespace NBranch { -STDMETHODIMP CCoder::Init() +Z7_COM7F_IMF(CCoder::Init()) +{ + _pc = 0; + return S_OK; +} + + +Z7_COM7F_IMF2(UInt32, CCoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CEncoder::Init()) { - _bufferPos = 0; + _pc = _pc_Init; return S_OK; } -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) { - UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); - _bufferPos += processed; + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; return processed; } +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + UInt32 pc = 0; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kDefaultProp || + propID == NCoderPropID::kBranchOffset) + { + const PROPVARIANT &prop = props[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + pc = prop.ulVal; + if (pc & _alignment) + return E_INVALIDARG; + } + } + _pc_Init = pc; + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + if (_pc_Init == 0) + return S_OK; + UInt32 buf32[1]; + SetUi32(buf32, _pc_Init) + return WriteStream(outStream, buf32, 4); +} + +#endif + + +Z7_COM7F_IMF(CDecoder::Init()) +{ + _pc = _pc_Init; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) +{ + UInt32 val = 0; + if (size != 0) + { + if (size != 4) + return E_NOTIMPL; + val = GetUi32(props); + if (val & _alignment) + return E_NOTIMPL; + } + _pc_Init = val; + return S_OK; +} + }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BranchMisc.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/BranchMisc.h 2016-04-25 10:09:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchMisc.h 2024-01-26 11:00:00.000000000 +0000 @@ -1,33 +1,57 @@ // BranchMisc.h -#ifndef __COMPRESS_BRANCH_MISC_H -#define __COMPRESS_BRANCH_MISC_H +#ifndef ZIP7_INC_COMPRESS_BRANCH_MISC_H +#define ZIP7_INC_COMPRESS_BRANCH_MISC_H +#include "../../../C/Bra.h" #include "../../Common/MyCom.h" #include "../ICoder.h" -EXTERN_C_BEGIN - -typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding); - -EXTERN_C_END - namespace NCompress { namespace NBranch { -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - int _encode; - Func_Bra BraFunc; +Z7_CLASS_IMP_COM_1( + CCoder + , ICompressFilter +) + UInt32 _pc; + z7_Func_BranchConv BraFunc; +public: + CCoder(z7_Func_BranchConv bra): _pc(0), BraFunc(bra) {} +}; + +#ifndef Z7_EXTRACT_ONLY + +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressFilter + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) + UInt32 _pc; + UInt32 _pc_Init; + UInt32 _alignment; + z7_Func_BranchConv BraFunc; public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) + CEncoder(z7_Func_BranchConv bra, UInt32 alignment): + _pc(0), _pc_Init(0), _alignment(alignment), BraFunc(bra) {} +}; - CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} +#endif + +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressFilter + , ICompressSetDecoderProperties2 +) + UInt32 _pc; + UInt32 _pc_Init; + UInt32 _alignment; + z7_Func_BranchConv BraFunc; +public: + CDecoder(z7_Func_BranchConv bra, UInt32 alignment): + _pc(0), _pc_Init(0), _alignment(alignment), BraFunc(bra) {} }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/BranchRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/BranchRegister.cpp 2016-04-25 10:10:55.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/BranchRegister.cpp 2024-02-07 17:00:00.000000000 +0000 @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../../../C/Bra.h" - #include "../Common/RegisterCodec.h" #include "BranchMisc.h" @@ -11,31 +9,50 @@ namespace NCompress { namespace NBranch { +#ifdef Z7_EXTRACT_ONLY +#define GET_CREATE_FUNC(x) NULL +#define CREATE_BRA_E(n) +#else +#define GET_CREATE_FUNC(x) x +#define CREATE_BRA_E(n) \ + REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(Z7_BRANCH_CONV_ENC_2(n))) +#endif + #define CREATE_BRA(n) \ - REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \ - REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \ + REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(Z7_BRANCH_CONV_DEC_2(n))) \ + CREATE_BRA_E(n) -CREATE_BRA(PPC) -CREATE_BRA(IA64) -CREATE_BRA(ARM) -CREATE_BRA(ARMT) -CREATE_BRA(SPARC) +CREATE_BRA(BranchConv_PPC) +CREATE_BRA(BranchConv_IA64) +CREATE_BRA(BranchConv_ARM) +CREATE_BRA(BranchConv_ARMT) +CREATE_BRA(BranchConv_SPARC) #define METHOD_ITEM(n, id, name) \ REGISTER_FILTER_ITEM( \ - CreateBra_Decoder_ ## n, \ - CreateBra_Encoder_ ## n, \ + CreateBra_Decoder_ ## n, GET_CREATE_FUNC( \ + CreateBra_Encoder_ ## n), \ 0x3030000 + id, name) REGISTER_CODECS_VAR { - METHOD_ITEM(PPC, 0x205, "PPC"), - METHOD_ITEM(IA64, 0x401, "IA64"), - METHOD_ITEM(ARM, 0x501, "ARM"), - METHOD_ITEM(ARMT, 0x701, "ARMT"), - METHOD_ITEM(SPARC, 0x805, "SPARC") + METHOD_ITEM(BranchConv_PPC, 0x205, "PPC"), + METHOD_ITEM(BranchConv_IA64, 0x401, "IA64"), + METHOD_ITEM(BranchConv_ARM, 0x501, "ARM"), + METHOD_ITEM(BranchConv_ARMT, 0x701, "ARMT"), + METHOD_ITEM(BranchConv_SPARC, 0x805, "SPARC") }; REGISTER_CODECS(Branch) + +#define REGISTER_FILTER_E_BRANCH(id, n, name, alignment) \ + REGISTER_FILTER_E(n, \ + CDecoder(Z7_BRANCH_CONV_DEC(n), alignment), \ + CEncoder(Z7_BRANCH_CONV_ENC(n), alignment), \ + id, name) + +REGISTER_FILTER_E_BRANCH(0xa, ARM64, "ARM64", 3) +REGISTER_FILTER_E_BRANCH(0xb, RISCV, "RISCV", 1) + }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ByteSwap.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ByteSwap.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ByteSwap.cpp 2016-04-25 10:11:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ByteSwap.cpp 2023-03-15 10:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../C/SwapBytes.h" + #include "../../Common/MyCom.h" #include "../ICoder.h" @@ -11,80 +13,77 @@ namespace NCompress { namespace NByteSwap { -class CByteSwap2: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; - -class CByteSwap4: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; +Z7_CLASS_IMP_COM_1(CByteSwap2, ICompressFilter) }; +Z7_CLASS_IMP_COM_1(CByteSwap4, ICompressFilter) }; -STDMETHODIMP CByteSwap2::Init() { return S_OK; } +Z7_COM7F_IMF(CByteSwap2::Init()) { return S_OK; } -STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CByteSwap2::Filter(Byte *data, UInt32 size)) { - const UInt32 kStep = 2; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do + const UInt32 kMask = 2 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) { - Byte b0 = data[0]; - data[0] = data[1]; - data[1] = b0; - data += kStep; + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + data[0] = data[1]; + data[1] = b0; + data += kStep; + } + while (data != end); } - while (data != end); - + else + */ + z7_SwapBytes2((UInt16 *)(void *)data, size >> 1); return size; } -STDMETHODIMP CByteSwap4::Init() { return S_OK; } -STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF(CByteSwap4::Init()) { return S_OK; } + +Z7_COM7F_IMF2(UInt32, CByteSwap4::Filter(Byte *data, UInt32 size)) { - const UInt32 kStep = 4; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do + const UInt32 kMask = 4 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) { - Byte b0 = data[0]; - Byte b1 = data[1]; - data[0] = data[3]; - data[1] = data[2]; - data[2] = b1; - data[3] = b0; - data += kStep; + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + const Byte b1 = data[1]; + data[0] = data[3]; + data[1] = data[2]; + data[2] = b1; + data[3] = b0; + data += kStep; + } + while (data != end); } - while (data != end); - + else + */ + z7_SwapBytes4((UInt32 *)(void *)data, size >> 2); return size; } +static struct C_SwapBytesPrepare { C_SwapBytesPrepare() { z7_SwapBytesPrepare(); } } g_SwapBytesPrepare; + + REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2()) REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4()) REGISTER_CODECS_VAR { REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"), - REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4") + REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4"), }; REGISTER_CODECS(ByteSwap) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Codec.def 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Codec.def --- 7zip-22.01+dfsg/CPP/7zip/Compress/Codec.def 2015-06-21 02:15:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Codec.def 2023-04-03 11:00:00.000000000 +0000 @@ -4,3 +4,4 @@ GetMethodProperty PRIVATE CreateDecoder PRIVATE CreateEncoder PRIVATE + GetModuleProp PRIVATE diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/CodecExports.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CodecExports.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/CodecExports.cpp 2021-08-07 16:26:47.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CodecExports.cpp 2023-04-08 11:00:00.000000000 +0000 @@ -3,11 +3,13 @@ #include "StdAfx.h" #include "../../../C/CpuArch.h" +#include "../../../C/7zVersion.h" #include "../../Common/ComTry.h" #include "../../Common/MyCom.h" #include "../../Windows/Defs.h" +#include "../../Windows/PropVariant.h" #include "../ICoder.h" @@ -21,7 +23,7 @@ static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() { - UINT len = (UINT)strlen(s); + const UINT len = (UINT)strlen(s); BSTR dest = ::SysAllocStringLen(NULL, len); if (dest) { @@ -45,7 +47,7 @@ clsId.Data1 = k_7zip_GUID_Data1; clsId.Data2 = k_7zip_GUID_Data2; clsId.Data3 = typeId; - SetUi64(clsId.Data4, id); + SetUi64(clsId.Data4, id) return SetPropGUID(clsId, value); } @@ -61,7 +63,7 @@ if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false; else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK; - UInt64 id = GetUi64(clsid->Data4); + const UInt64 id = GetUi64(clsid->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) { @@ -75,7 +77,7 @@ if (codec.NumStreams == 1 ? isCoder2 : !isCoder2) return E_NOINTERFACE; - index = i; + index = (int)i; return S_OK; } @@ -169,7 +171,7 @@ bool isFilter = false; bool isCoder2 = false; - bool isCoder = (*iid == IID_ICompressCoder) != 0; + const bool isCoder = (*iid == IID_ICompressCoder) != 0; if (!isCoder) { isFilter = (*iid == IID_ICompressFilter) != 0; @@ -183,13 +185,13 @@ bool encode; int codecIndex; - HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); + const HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); if (res != S_OK) return res; if (codecIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; - return CreateCoderMain(codecIndex, encode, outObject); + return CreateCoderMain((unsigned)codecIndex, encode, outObject); } @@ -255,8 +257,8 @@ } -STDAPI GetNumberOfMethods(UINT32 *numCodecs); -STDAPI GetNumberOfMethods(UINT32 *numCodecs) +STDAPI GetNumberOfMethods(UInt32 *numCodecs); +STDAPI GetNumberOfMethods(UInt32 *numCodecs) { *numCodecs = g_NumCodecs; return S_OK; @@ -271,10 +273,10 @@ clsid->Data2 != k_7zip_GUID_Data2 || clsid->Data3 != k_7zip_GUID_Data3_Hasher) return -1; - UInt64 id = GetUi64(clsid->Data4); + const UInt64 id = GetUi64(clsid->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) if (id == g_Hashers[i]->Id) - return i; + return (int)i; return -1; } @@ -292,11 +294,11 @@ STDAPI CreateHasher(const GUID *clsid, IHasher **outObject) { COM_TRY_BEGIN - *outObject = 0; - int index = FindHasherClassId(clsid); + *outObject = NULL; + const int index = FindHasherClassId(clsid); if (index < 0) return CLASS_E_CLASSNOTAVAILABLE; - return CreateHasher2(index, outObject); + return CreateHasher2((UInt32)(unsigned)index, outObject); COM_TRY_END } @@ -326,17 +328,7 @@ return S_OK; } -class CHashers: - public IHashers, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IHashers) - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); -}; +Z7_CLASS_IMP_COM_1(CHashers, IHashers) }; STDAPI GetHashers(IHashers **hashers); STDAPI GetHashers(IHashers **hashers) @@ -349,17 +341,38 @@ COM_TRY_END } -STDMETHODIMP_(UInt32) CHashers::GetNumHashers() +Z7_COM7F_IMF2(UInt32, CHashers::GetNumHashers()) { return g_NumHashers; } -STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) { return ::GetHasherProp(index, propID, value); } -STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher) +Z7_COM7F_IMF(CHashers::CreateHasher(UInt32 index, IHasher **hasher)) { return ::CreateHasher2(index, hasher); } + + +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value); +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + switch (propID) + { + case NModulePropID::kInterfaceType: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule); + break; + } + case NModulePropID::kVersion: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, (MY_VER_MAJOR << 16) | MY_VER_MINOR); + break; + } + } + return S_OK; +} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/CopyCoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/CopyCoder.cpp 2021-12-13 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.cpp 2023-02-01 10:00:00.000000000 +0000 @@ -15,15 +15,15 @@ ::MidFree(_buf); } -STDMETHODIMP CCopyCoder::SetFinishMode(UInt32 /* finishMode */) +Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */)) { return S_OK; } -STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, +Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { if (!_buf) { @@ -44,7 +44,12 @@ { size = (UInt32)rem; if (size == 0) + { + /* if we enable the following check, + we will make one call of Read(_buf, 0) for empty stream */ + // if (TotalSize != 0) return S_OK; + } } } @@ -81,7 +86,7 @@ return E_FAIL; // internal code failure pos += processed; TotalSize += processed; - RINOK(res); + RINOK(res) if (processed == 0) return E_FAIL; } @@ -90,32 +95,32 @@ else TotalSize += size; - RINOK(readRes); + RINOK(readRes) if (size != kBufSize) return S_OK; if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0) { - RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)) } } } -STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; TotalSize = 0; return S_OK; } -STDMETHODIMP CCopyCoder::ReleaseInStream() +Z7_COM7F_IMF(CCopyCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; HRESULT res = _inStream->Read(data, size, &realProcessedSize); @@ -125,7 +130,7 @@ return res; } -STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value)) { *value = TotalSize; return S_OK; @@ -141,7 +146,7 @@ { NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)) return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/CopyCoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/CopyCoder.h 2017-02-12 05:52:06.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/CopyCoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Compress/CopyCoder.h -#ifndef __COMPRESS_COPY_CODER_H -#define __COMPRESS_COPY_CODER_H +#ifndef ZIP7_INC_COMPRESS_COPY_CODER_H +#define ZIP7_INC_COMPRESS_COPY_CODER_H #include "../../Common/MyCom.h" @@ -9,36 +9,21 @@ namespace NCompress { -class CCopyCoder: - public ICompressCoder, - public ICompressSetInStream, - public ISequentialInStream, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_5( + CCopyCoder + , ICompressCoder + , ICompressSetInStream + , ISequentialInStream + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) Byte *_buf; CMyComPtr _inStream; public: UInt64 TotalSize; - CCopyCoder(): _buf(0), TotalSize(0) {}; + CCopyCoder(): _buf(NULL), TotalSize(0) {} ~CCopyCoder(); - - MY_UNKNOWN_IMP5( - ICompressCoder, - ICompressSetInStream, - ISequentialInStream, - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Deflate64Register.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Deflate64Register.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Deflate64Register.cpp 2016-04-25 10:19:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Deflate64Register.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -5,8 +5,7 @@ #include "../Common/RegisterCodec.h" #include "DeflateDecoder.h" - -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) #include "DeflateEncoder.h" #endif @@ -15,7 +14,7 @@ REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder64()) -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder64()) #else #define CreateEnc NULL diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateConst.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateConst.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateConst.h 2015-05-09 09:52:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateConst.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // DeflateConst.h -#ifndef __DEFLATE_CONST_H -#define __DEFLATE_CONST_H +#ifndef ZIP7_INC_DEFLATE_CONST_H +#define ZIP7_INC_DEFLATE_CONST_H namespace NCompress { namespace NDeflate { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateDecoder.cpp 2022-01-26 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.cpp 2025-03-04 12:00:00.000000000 +0000 @@ -15,8 +15,8 @@ _needFinishInput(false), _needInitInStream(true), _outSizeDefined(false), - _outStartPos(0), - ZlibMode(false) {} + _outStartPos(0) + {} UInt32 CCoder::ReadBits(unsigned numBits) { @@ -34,7 +34,7 @@ do { - UInt32 sym = m_LevelDecoder.Decode(&m_InBitStream); + unsigned sym = m_LevelDecoder.Decode(&m_InBitStream); if (sym < kTableDirectLevels) levels[i++] = (Byte)sym; else @@ -83,7 +83,7 @@ m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); if (m_InBitStream.ExtraBitsWereRead()) return false; - UInt32 blockType = ReadBits(kBlockTypeFieldSize); + const UInt32 blockType = ReadBits(kBlockTypeFieldSize); if (blockType > NBlockType::kDynamicHuffman) return false; if (m_InBitStream.ExtraBitsWereRead()) @@ -109,28 +109,26 @@ } else { - unsigned numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; - _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; - unsigned numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; + const unsigned numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; + _numDistLevels = (unsigned)ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; + const unsigned numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; if (!_deflate64Mode) if (_numDistLevels > kDistTableSize32) return false; - Byte levelLevels[kLevelTableSize]; - for (unsigned i = 0; i < kLevelTableSize; i++) - { - unsigned position = kCodeLengthAlphabetOrder[i]; - if (i < numLevelCodes) - levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); - else - levelLevels[position] = 0; - } + const unsigned kLevelTableSize_aligned4 = kLevelTableSize + 1; + Byte levelLevels[kLevelTableSize_aligned4]; + memset (levelLevels, 0, sizeof(levelLevels)); + unsigned i = 0; + do + levelLevels[kCodeLengthAlphabetOrder[i++]] = (Byte)ReadBits(kLevelFieldSize); + while (i != numLevelCodes); if (m_InBitStream.ExtraBitsWereRead()) return false; - RIF(m_LevelDecoder.Build(levelLevels)); + RIF(m_LevelDecoder.Build(levelLevels, false)) // full Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; if (!DecodeLevels(tmpLevels, numLitLenLevels + _numDistLevels)) @@ -143,7 +141,7 @@ memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels); } - RIF(m_MainDecoder.Build(levels.litLenLevels)); + RIF(m_MainDecoder.Build(levels.litLenLevels)) return m_DistDecoder.Build(levels.distLevels); } @@ -174,7 +172,7 @@ if (!_keepHistory) if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) return E_OUTOFMEMORY; - RINOK(InitInStream(_needInitInStream)); + RINOK(InitInStream(_needInitInStream)) m_OutWindowStream.Init(_keepHistory); m_FinalBlock = false; @@ -182,10 +180,11 @@ _needReadTable = true; } - while (_remainLen > 0 && curSize > 0) + // _remainLen >= 0 + while (_remainLen && curSize) { _remainLen--; - Byte b = m_OutWindowStream.GetByte(_rep0); + const Byte b = m_OutWindowStream.GetByte(_rep0); m_OutWindowStream.PutByte(b); curSize--; } @@ -194,7 +193,7 @@ if (inputProgressLimit != 0) inputStart = m_InBitStream.GetProcessedSize(); - while (curSize > 0 || finishInputStream) + while (curSize || finishInputStream) { if (m_InBitStream.ExtraBitsWereRead()) return S_FALSE; @@ -224,20 +223,53 @@ return S_FALSE; /* NSIS version contains some bits in bitl bits buffer. So we must read some first bytes via ReadAlignedByte */ - for (; m_StoredBlockSize > 0 && curSize > 0 && m_InBitStream.ThereAreDataInBitsBuffer(); m_StoredBlockSize--, curSize--) + UInt32 num = m_StoredBlockSize; + if (num > curSize) + num = curSize; + m_StoredBlockSize -= num; + curSize -= num; + for (; num && m_InBitStream.ThereAreDataInBitsBuffer(); num--) m_OutWindowStream.PutByte(ReadAlignedByte()); - for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) - m_OutWindowStream.PutByte(m_InBitStream.ReadDirectByte()); + if (num) + { +#if 1 + // fast code + do + { + size_t a; + Byte *buf = m_OutWindowStream.GetOutBuffer(a); + // a != 0 + if (a > num) + a = num; + // a != 0 + a = m_InBitStream.ReadDirectBytesPart(buf, a); + if (a == 0) + return S_FALSE; + m_OutWindowStream.SkipWrittenBytes(a); + num -= (UInt32)a; + } + while (num); +#else + // slow code: + do + m_OutWindowStream.PutByte(m_InBitStream.ReadDirectByte()); + while (--num); +#endif + } _needReadTable = (m_StoredBlockSize == 0); continue; } - while (curSize > 0) + while (curSize) { if (m_InBitStream.ExtraBitsWereRead_Fast()) return S_FALSE; - - UInt32 sym = m_MainDecoder.Decode(&m_InBitStream); + unsigned sym; +#if 0 + sym = m_MainDecoder.Decode(&m_InBitStream); +#else + Z7_HUFF_DECODE_CHECK(sym, &m_MainDecoder, kNumHuffmanBits, kNumTableBits_Main, &m_InBitStream, { return S_FALSE; }) +#endif if (sym < 0x100) { @@ -245,12 +277,15 @@ curSize--; continue; } - else if (sym == kSymbolEndOfBlock) + if (sym == kSymbolEndOfBlock) { _needReadTable = true; break; } - else if (sym < kMainTableSize) +#if 0 + if (sym >= kMainTableSize) + return S_FALSE; +#endif { sym -= kSymbolMatch; UInt32 len; @@ -268,22 +303,29 @@ } len += kMatchMinLen + m_InBitStream.ReadBits(numBits); } - UInt32 locLen = len; - if (locLen > curSize) - locLen = (UInt32)curSize; + +#if 0 sym = m_DistDecoder.Decode(&m_InBitStream); if (sym >= _numDistLevels) return S_FALSE; +#else + Z7_HUFF_DECODE_CHECK(sym, &m_DistDecoder, kNumHuffmanBits, kNumTableBits_Dist, &m_InBitStream, { return S_FALSE; }) +#endif + +#if 1 sym = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); - /* +#else if (sym >= 4) { // sym &= 31; - const unsigned numDirectBits = (unsigned)(((sym >> 1) - 1)); - sym = (2 | (sym & 1)) << numDirectBits; + const unsigned numDirectBits = (sym - 2) >> 1; + sym = (2u | (sym & 1)) << numDirectBits; sym += m_InBitStream.ReadBits(numDirectBits); } - */ +#endif + UInt32 locLen = len; + if (locLen > curSize) + locLen = (UInt32)curSize; if (!m_OutWindowStream.CopyBlock(sym, locLen)) return S_FALSE; curSize -= locLen; @@ -295,8 +337,6 @@ break; } } - else - return S_FALSE; } if (finishInputStream && curSize == 0) @@ -314,7 +354,7 @@ } -#ifdef _NO_EXCEPTIONS +#ifdef Z7_NO_EXCEPTIONS #define DEFLATE_TRY_BEGIN #define DEFLATE_TRY_END(res) @@ -354,14 +394,14 @@ if (curSize >= rem) { curSize = (UInt32)rem; - if (ZlibMode || _needFinishInput) + if (_needFinishInput) finishInputStream = true; + else if (curSize == 0) + break; } } - if (!finishInputStream && curSize == 0) - break; - RINOK(CodeSpec(curSize, finishInputStream, progress ? kInputProgressLimit : 0)); + RINOK(CodeSpec(curSize, finishInputStream, progress ? kInputProgressLimit : 0)) if (_remainLen == kLenIdFinished) break; @@ -370,17 +410,10 @@ { const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart; const UInt64 nowPos64 = GetOutProcessedCur(); - RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)) } } - if (_remainLen == kLenIdFinished && ZlibMode) - { - m_InBitStream.AlignToByte(); - for (unsigned i = 0; i < 4; i++) - ZlibFooter[i] = ReadAlignedByte(); - } - flusher.NeedFlush = false; res = Flush(); if (res == S_OK && _remainLen != kLenIdNeedInit && InputEofError()) @@ -392,12 +425,12 @@ } -HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { SetInStream(inStream); SetOutStreamSize(outSize); - HRESULT res = CodeReal(outStream, progress); + const HRESULT res = CodeReal(outStream, progress); ReleaseInStream(); /* if (res == S_OK) @@ -408,21 +441,21 @@ } -STDMETHODIMP CCoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CCoder::SetFinishMode(UInt32 finishMode)) { Set_NeedFinishInput(finishMode != 0); return S_OK; } -STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CCoder::GetInStreamProcessedSize(UInt64 *value)) { *value = m_InBitStream.GetStreamSize(); return S_OK; } -STDMETHODIMP CCoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) { AlignToByte(); UInt32 i = 0; @@ -439,7 +472,7 @@ } -STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CCoder::SetInStream(ISequentialInStream *inStream)) { m_InStreamRef = inStream; m_InBitStream.SetStream(inStream); @@ -447,9 +480,10 @@ } -STDMETHODIMP CCoder::ReleaseInStream() +Z7_COM7F_IMF(CCoder::ReleaseInStream()) { m_InStreamRef.Release(); + m_InBitStream.ClearStreamPtr(); return S_OK; } @@ -460,15 +494,13 @@ _outSize = 0; if (_outSizeDefined) _outSize = *outSize; - m_OutWindowStream.Init(_keepHistory); _outStartPos = m_OutWindowStream.GetProcessedSize(); - _remainLen = kLenIdNeedInit; } -STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CCoder::SetOutStreamSize(const UInt64 *outSize)) { /* 18.06: @@ -484,12 +516,10 @@ } -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { - HRESULT res; - if (processedSize) *processedSize = 0; const UInt64 outPos = GetOutProcessedCur(); @@ -501,30 +531,25 @@ if (size >= rem) { size = (UInt32)rem; - if (ZlibMode || _needFinishInput) + if (_needFinishInput) finishInputStream = true; } } if (!finishInputStream && size == 0) return S_OK; + HRESULT res; DEFLATE_TRY_BEGIN - m_OutWindowStream.SetMemStream((Byte *)data); - res = CodeSpec(size, finishInputStream); - DEFLATE_TRY_END(res) - { - HRESULT res2 = Flush(); + const HRESULT res2 = Flush(); if (res2 != S_OK) res = res2; } - if (processedSize) *processedSize = (UInt32)(GetOutProcessedCur() - outPos); - m_OutWindowStream.SetMemStream(NULL); return res; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateDecoder.h 2019-09-09 17:14:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateDecoder.h 2024-01-06 19:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // DeflateDecoder.h -#ifndef __DEFLATE_DECODER_H -#define __DEFLATE_DECODER_H +#ifndef ZIP7_INC_DEFLATE_DECODER_H +#define ZIP7_INC_DEFLATE_DECODER_H #include "../../Common/MyCom.h" @@ -21,28 +21,54 @@ const int kLenIdFinished = -1; const int kLenIdNeedInit = -2; +const unsigned kNumTableBits_Main = 10; +const unsigned kNumTableBits_Dist = 6; + class CCoder: public ICompressCoder, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, public ICompressReadUnusedFromInBuf, - #ifndef NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, +#ifndef Z7_NO_READ_FROM_CODER public ISequentialInStream, - #endif +#endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ISequentialInStream) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) +public: + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ISequentialInStream) +#endif + CLzOutWindow m_OutWindowStream; - CMyComPtr m_InStreamRef; NBitl::CDecoder m_InBitStream; - NCompress::NHuffman::CDecoder m_MainDecoder; - NCompress::NHuffman::CDecoder m_DistDecoder; + NCompress::NHuffman::CDecoder m_MainDecoder; + NCompress::NHuffman::CDecoder256 m_DistDecoder; NCompress::NHuffman::CDecoder7b m_LevelDecoder; UInt32 m_StoredBlockSize; - UInt32 _numDistLevels; + unsigned _numDistLevels; bool m_FinalBlock; bool m_StoredMode; @@ -57,6 +83,7 @@ UInt32 _rep0; bool _outSizeDefined; + CMyComPtr m_InStreamRef; UInt64 _outSize; UInt64 _outStartPos; @@ -85,61 +112,29 @@ HRESULT CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit = 0); public: - bool ZlibMode; - Byte ZlibFooter[4]; CCoder(bool deflate64Mode); - virtual ~CCoder() {}; + virtual ~CCoder() {} void SetNsisMode(bool nsisMode) { _deflateNSIS = nsisMode; } void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; } - bool IsFinished() const { return _remainLen == kLenIdFinished;; } + bool IsFinished() const { return _remainLen == kLenIdFinished; } bool IsFinalBlock() const { return m_FinalBlock; } HRESULT CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress); - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf) - - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif - +public: HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); - HRESULT InitInStream(bool needInit); void AlignToByte() { m_InBitStream.AlignToByte(); } Byte ReadAlignedByte(); UInt32 ReadAligned_UInt16() // aligned for Byte range { - UInt32 v = m_InBitStream.ReadAlignedByte(); + const UInt32 v = m_InBitStream.ReadAlignedByte(); return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8); } bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateEncoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateEncoder.cpp 2021-07-13 12:51:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.cpp 2025-01-13 13:00:00.000000000 +0000 @@ -14,17 +14,21 @@ #undef NO_INLINE #ifdef _MSC_VER -#define NO_INLINE MY_NO_INLINE +#define NO_INLINE Z7_NO_INLINE #else #define NO_INLINE #endif +#define MAX_HUF_LEN_12 12 + namespace NCompress { namespace NDeflate { namespace NEncoder { +static const unsigned k_CodeValue_Len_Is_Literal_Flag = 1u << 15; + static const unsigned kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. -static const UInt32 kNumTables = (1 << kNumDivPassesMax); +static const unsigned kNumTables = 1u << kNumDivPassesMax; static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio. static const UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. @@ -43,9 +47,11 @@ static const Byte kNoLenStatPrice = 11; static const Byte kNoPosStatPrice = 6; +MY_ALIGN(64) static Byte g_LenSlots[kNumLenSymbolsMax]; #define kNumLogBits 9 // do not change it +MY_ALIGN(64) static Byte g_FastPos[1 << kNumLogBits]; class CFastPosInit @@ -57,7 +63,7 @@ for (i = 0; i < kNumLenSlots; i++) { unsigned c = kLenStart32[i]; - unsigned j = 1 << kLenDirectBits32[i]; + const unsigned j = 1u << kLenDirectBits32[i]; for (unsigned k = 0; k < j; k++, c++) g_LenSlots[c] = (Byte)i; } @@ -66,8 +72,8 @@ unsigned c = 0; for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) { - UInt32 k = (1 << kDistDirectBits[slotFast]); - for (UInt32 j = 0; j < k; j++, c++) + const unsigned k = 1u << kDistDirectBits[slotFast]; + for (unsigned j = 0; j < k; j++, c++) g_FastPos[c] = slotFast; } } @@ -75,7 +81,7 @@ static CFastPosInit g_FastPosInit; -inline UInt32 GetPosSlot(UInt32 pos) +inline unsigned GetPosSlot(UInt32 pos) { /* if (pos < 0x200) @@ -158,34 +164,34 @@ HRESULT CCoder::Create() { // COM_TRY_BEGIN - if (m_Values == 0) + if (!m_Values) { - m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue)); - if (m_Values == 0) + m_Values = (CCodeValue *)MyAlloc(kMaxUncompressedBlockSize * sizeof(CCodeValue)); + if (!m_Values) return E_OUTOFMEMORY; } - if (m_Tables == 0) + if (!m_Tables) { - m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables)); - if (m_Tables == 0) + m_Tables = (CTables *)MyAlloc(kNumTables * sizeof(CTables)); + if (!m_Tables) return E_OUTOFMEMORY; } if (m_IsMultiPass) { - if (m_OnePosMatchesMemory == 0) + if (!m_OnePosMatchesMemory) { m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16)); - if (m_OnePosMatchesMemory == 0) + if (!m_OnePosMatchesMemory) return E_OUTOFMEMORY; } } else { - if (m_DistanceMemory == 0) + if (!m_DistanceMemory) { m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16)); - if (m_DistanceMemory == 0) + if (!m_DistanceMemory) return E_OUTOFMEMORY; m_MatchDistances = m_DistanceMemory; } @@ -195,10 +201,11 @@ { _lzInWindow.btMode = (Byte)(_btMode ? 1 : 0); _lzInWindow.numHashBytes = 3; + _lzInWindow.numHashBytes_Min = 3; if (!MatchFinder_Create(&_lzInWindow, m_Deflate64Mode ? kHistorySize64 : kHistorySize32, kNumOpts + kMaxUncompressedBlockSize, - m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc)) + m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_AlignedAlloc)) return E_OUTOFMEMORY; if (!m_OutStream.Create(1 << 20)) return E_OUTOFMEMORY; @@ -239,16 +246,16 @@ void CCoder::Free() { - ::MidFree(m_OnePosMatchesMemory); m_OnePosMatchesMemory = 0; - ::MyFree(m_DistanceMemory); m_DistanceMemory = 0; - ::MyFree(m_Values); m_Values = 0; - ::MyFree(m_Tables); m_Tables = 0; + ::MidFree(m_OnePosMatchesMemory); m_OnePosMatchesMemory = NULL; + ::MyFree(m_DistanceMemory); m_DistanceMemory = NULL; + ::MyFree(m_Values); m_Values = NULL; + ::MyFree(m_Tables); m_Tables = NULL; } CCoder::~CCoder() { Free(); - MatchFinder_Free(&_lzInWindow, &g_Alloc); + MatchFinder_Free(&_lzInWindow, &g_AlignedAlloc); } NO_INLINE void CCoder::GetMatches() @@ -265,19 +272,21 @@ UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; - const UInt32 numPairs = (UInt32)((_btMode ? + const size_t numPairs = (size_t)((_btMode ? Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp): Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp)) - distanceTmp); - *m_MatchDistances = (UInt16)numPairs; + UInt16 *matchDistances = m_MatchDistances; + *matchDistances++ = (UInt16)numPairs; if (numPairs != 0) { - UInt32 i; + size_t i; for (i = 0; i < numPairs; i += 2) { - m_MatchDistances[(size_t)i + 1] = (UInt16)distanceTmp[i]; - m_MatchDistances[(size_t)i + 2] = (UInt16)distanceTmp[(size_t)i + 1]; + matchDistances[0] = (UInt16)distanceTmp[i]; + matchDistances[1] = (UInt16)distanceTmp[(size_t)i + 1]; + matchDistances += 2; } UInt32 len = distanceTmp[(size_t)numPairs - 2]; if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen) @@ -288,11 +297,11 @@ if (numAvail > m_MatchMaxLen) numAvail = m_MatchMaxLen; for (; len < numAvail && pby[len] == pby2[len]; len++); - m_MatchDistances[(size_t)i - 1] = (UInt16)len; + matchDistances[-2] = (UInt16)len; } } if (m_IsMultiPass) - m_Pos += numPairs + 1; + m_Pos += (UInt32)numPairs + 1; if (!m_SecondPass) m_AdditionalOffset++; } @@ -532,6 +541,7 @@ } #define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i]) +#define WRITE_HF2_NO_INLINE(codes, lens, i) WriteBits(codes[i], lens[i]) #define WRITE_HF(i) WriteBits(codes[i], lens[i]) NO_INLINE void CCoder::LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes) @@ -616,17 +626,22 @@ return price; } -static NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase) +static NO_INLINE UInt32 Huffman_GetPrice_Spec( + const UInt32 *freqs, const Byte *lens, UInt32 num, + const Byte *extraBits, UInt32 extraBase) { - return Huffman_GetPrice(freqs, lens, num) + + return + Huffman_GetPrice(freqs, lens, num) + Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase); } NO_INLINE UInt32 CCoder::GetLzBlockPrice() const { return - Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) + - Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0); + Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, + kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) + + Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, + kDistTableSize64, kDistDirectBits, 0); } NO_INLINE void CCoder::TryBlock() @@ -655,7 +670,7 @@ CCodeValue &codeValue = m_Values[m_ValueIndex++]; if (len >= kMatchMinLen) { - UInt32 newLen = len - kMatchMinLen; + const UInt32 newLen = len - kMatchMinLen; codeValue.Len = (UInt16)newLen; mainFreqs[kSymbolMatch + (size_t)g_LenSlots[newLen]]++; codeValue.Pos = (UInt16)pos; @@ -663,10 +678,10 @@ } else { - Byte b = *(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset); + const unsigned b = *(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset); mainFreqs[b]++; - codeValue.SetAsLiteral(); - codeValue.Pos = b; + codeValue.Len = k_CodeValue_Len_Is_Literal_Flag; + codeValue.Pos = (UInt16)b; } m_AdditionalOffset -= len; BlockSizeRes += len; @@ -701,16 +716,24 @@ } } +#if MAX_HUF_LEN_12 > 12 +// Huffman_ReverseBits() now supports 12-bits values only. +#error Stop_Compiling_Bad_MAX_HUF_LEN_12 +#endif static NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num) { - for (UInt32 i = 0; i < num; i++) + const Byte * const lens_lim = lens + num; + do { - UInt32 x = codes[i]; - x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1); - x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2); - x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4); - codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]); + // we should change constants, if lens[*] can be larger than 12. + UInt32 x = *codes; + x = ((x & (0x555 )) << 2) + (x & (0xAAA )); + x = ((x & (0x333 << 1)) << 4) | (x & (0xCCC << 1)); + x = ((x & (0xF0F << 3)) << 8) | (x & (0x0F0 << 3)); + // we can use (x) instead of (x & (0xFF << 7)), if we support garabage data after (*lens) bits. + *codes++ = (((x & (0xFF << 7)) << 16) | x) >> (*lens ^ 31); } + while (++lens != lens_lim); } NO_INLINE void CCoder::WriteBlock() @@ -718,24 +741,28 @@ Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize); Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64); - for (UInt32 i = 0; i < m_ValueIndex; i++) + CCodeValue *values = m_Values; + const CCodeValue * const values_lim = values + m_ValueIndex; + + if (values != values_lim) + do { - const CCodeValue &codeValue = m_Values[i]; - if (codeValue.IsLiteral()) - WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos); + const UInt32 len = values->Len; + const UInt32 dist = values->Pos; + if (len == k_CodeValue_Len_Is_Literal_Flag) + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, dist); else { - UInt32 len = codeValue.Len; - UInt32 lenSlot = g_LenSlots[len]; + const unsigned lenSlot = g_LenSlots[len]; WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot); m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]); - UInt32 dist = codeValue.Pos; - UInt32 posSlot = GetPosSlot(dist); + const unsigned posSlot = GetPosSlot(dist); WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot); m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]); } } - WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); + while (++values != values_lim); + WRITE_HF2_NO_INLINE(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); } static UInt32 GetStorePrice(UInt32 blockSize, unsigned bitPosition) @@ -784,10 +811,10 @@ { m_Pos = posTemp; TryBlock(); - unsigned numHuffBits = - (m_ValueIndex > 18000 ? 12 : - (m_ValueIndex > 7000 ? 11 : - (m_ValueIndex > 2000 ? 10 : 9))); + const unsigned numHuffBits = + m_ValueIndex > 18000 ? MAX_HUF_LEN_12 : + m_ValueIndex > 7000 ? 11 : + m_ValueIndex > 2000 ? 10 : 9; MakeTables(numHuffBits); SetPrices(m_NewLevels); } @@ -945,17 +972,19 @@ m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1); m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1)); - RINOK(Create()); - - m_ValueBlockSize = (7 << 10) + (1 << 12) * m_NumDivPasses; - - UInt64 nowPos = 0; + /* we can set stream mode before MatchFinder_Create + if default MatchFinder mode was not STREAM_MODE) */ + // MatchFinder_SET_STREAM_MODE(&_lzInWindow); CSeqInStreamWrap _seqInStream; - _seqInStream.Init(inStream); + MatchFinder_SET_STREAM(&_lzInWindow, &_seqInStream.vt) - _lzInWindow.stream = &_seqInStream.vt; + RINOK(Create()) + + m_ValueBlockSize = (7 << 10) + (1 << 12) * m_NumDivPasses; + + UInt64 nowPos = 0; MatchFinder_Init(&_lzInWindow); m_OutStream.SetStream(outStream); @@ -978,7 +1007,7 @@ if (progress != NULL) { UInt64 packSize = m_OutStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&nowPos, &packSize)); + RINOK(progress->SetRatioInfo(&nowPos, &packSize)) } } while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0); @@ -999,18 +1028,18 @@ catch(...) { return E_FAIL; } } -STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CCOMCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { return BaseCode(inStream, outStream, inSize, outSize, progress); } -STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CCOMCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { return BaseSetEncoderProperties2(propIDs, props, numProps); } -STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CCOMCoder64::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { return BaseCode(inStream, outStream, inSize, outSize, progress); } -STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CCOMCoder64::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { return BaseSetEncoderProperties2(propIDs, props, numProps); } }}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateEncoder.h 2017-04-05 12:49:10.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // DeflateEncoder.h -#ifndef __DEFLATE_ENCODER_H -#define __DEFLATE_ENCODER_H +#ifndef ZIP7_INC_DEFLATE_ENCODER_H +#define ZIP7_INC_DEFLATE_ENCODER_H #include "../../../C/LzFind.h" @@ -176,32 +176,26 @@ }; -class CCOMCoder : +class CCOMCoder Z7_final: public ICompressCoder, public ICompressSetCoderProperties, public CMyUnknownImp, public CCoder { + Z7_IFACES_IMP_UNK_2(ICompressCoder, ICompressSetCoderProperties) public: - MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties) - CCOMCoder(): CCoder(false) {}; - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + CCOMCoder(): CCoder(false) {} }; -class CCOMCoder64 : +class CCOMCoder64 Z7_final: public ICompressCoder, public ICompressSetCoderProperties, public CMyUnknownImp, public CCoder { + Z7_IFACES_IMP_UNK_2(ICompressCoder, ICompressSetCoderProperties) public: - MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties) - CCOMCoder64(): CCoder(true) {}; - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + CCOMCoder64(): CCoder(true) {} }; }}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeflateRegister.cpp 2016-04-25 10:01:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeflateRegister.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -5,7 +5,7 @@ #include "../Common/RegisterCodec.h" #include "DeflateDecoder.h" -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) #include "DeflateEncoder.h" #endif @@ -14,7 +14,7 @@ REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder) -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder) #else #define CreateEnc NULL diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DeltaFilter.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeltaFilter.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/DeltaFilter.cpp 2016-04-26 11:24:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DeltaFilter.cpp 2024-01-01 18:00:00.000000000 +0000 @@ -23,41 +23,40 @@ }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public ICompressFilter, public ICompressSetCoderProperties, public ICompressWriteCoderProperties, - CDelta, - public CMyUnknownImp + public CMyUnknownImp, + CDelta { -public: - MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + Z7_IFACES_IMP_UNK_3( + ICompressFilter, + ICompressSetCoderProperties, + ICompressWriteCoderProperties) }; -STDMETHODIMP CEncoder::Init() +Z7_COM7F_IMF(CEncoder::Init()) { DeltaInit(); return S_OK; } -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) { Delta_Encode(_state, _delta, data, size); return size; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - UInt32 delta = _delta; + unsigned delta = _delta; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID >= NCoderPropID::kReduceSize) continue; if (prop.vt != VT_UI4) @@ -65,9 +64,9 @@ switch (propID) { case NCoderPropID::kDefaultProp: - delta = (UInt32)prop.ulVal; - if (delta < 1 || delta > 256) + if (prop.ulVal < 1 || prop.ulVal > 256) return E_INVALIDARG; + delta = prop.ulVal; break; case NCoderPropID::kNumThreads: break; case NCoderPropID::kLevel: break; @@ -78,40 +77,39 @@ return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { - Byte prop = (Byte)(_delta - 1); + const Byte prop = (Byte)(_delta - 1); return outStream->Write(&prop, 1, NULL); } #endif -class CDecoder: +class CDecoder Z7_final: public ICompressFilter, public ICompressSetDecoderProperties2, - CDelta, - public CMyUnknownImp + public CMyUnknownImp, + CDelta { -public: - MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + Z7_IFACES_IMP_UNK_2( + ICompressFilter, + ICompressSetDecoderProperties2) }; -STDMETHODIMP CDecoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { DeltaInit(); return S_OK; } -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) { Delta_Decode(_state, _delta, data, size); return size; } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) { if (size != 1) return E_INVALIDARG; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/DllExports2Compress.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DllExports2Compress.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/DllExports2Compress.cpp 2015-01-21 16:15:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/DllExports2Compress.cpp 2024-05-22 10:00:00.000000000 +0000 @@ -15,6 +15,15 @@ #else HINSTANCE #endif + /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) { return TRUE; @@ -22,6 +31,7 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { return CreateCoder(clsid, iid, outObject); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/HuffmanDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/HuffmanDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/HuffmanDecoder.h 2017-04-10 10:00:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/HuffmanDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,180 +1,403 @@ // Compress/HuffmanDecoder.h -#ifndef __COMPRESS_HUFFMAN_DECODER_H -#define __COMPRESS_HUFFMAN_DECODER_H +#ifndef ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H +#define ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H +#include "../../../C/CpuArch.h" #include "../../Common/MyTypes.h" namespace NCompress { namespace NHuffman { -const unsigned kNumPairLenBits = 4; -const unsigned kPairLenMask = (1 << kNumPairLenBits) - 1; +// const unsigned kNumTableBits_Default = 9; -template -class CDecoder -{ -public: - UInt32 _limits[kNumBitsMax + 2]; - UInt32 _poses[kNumBitsMax + 1]; - UInt16 _lens[1 << kNumTableBits]; - UInt16 _symbols[m_NumSymbols]; +#if 0 || 0 && defined(MY_CPU_64BIT) +// for debug or optimization: +// 64-BIT limit array can be faster for some compilers. +// for debug or optimization: +#define Z7_HUFF_USE_64BIT_LIMIT +#else +// sizet value variable allows to eliminate some move operation in some compilers. +// for debug or optimization: +// #define Z7_HUFF_USE_SIZET_VALUE +#endif + +// v0 must normalized to (32 bits) : (v0 < ((UInt64)1 << 32)) + +#ifdef Z7_HUFF_USE_64BIT_LIMIT + typedef UInt64 CLimitInt; + typedef UInt64 CValueInt; + // all _limits[*] are normalized and limited by ((UInt64)1 << 32). + // we don't use (v1) in this branch + #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) 32 + #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \ + ((NCompress::NHuffman::CLimitInt)v0 >= (huf)->_limits[0]) + #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits) (v0) + #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits) ((v0) >> (32 - kNumTableBits)) + #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1) +#else + typedef UInt32 CLimitInt; + typedef + #ifdef Z7_HUFF_USE_SIZET_VALUE + size_t + #else + UInt32 + #endif + CValueInt; + // v1 must be precalculated from v0 in this branch + // _limits[0] and (v1) are normalized and limited by (1 << kNumTableBits). + // _limits[non_0] are normalized and limited by (1 << kNumBitsMax). + #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) (kNumBitsMax) + #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \ + ((NCompress::NHuffman::CLimitInt)v1 >= (huf)->_limits[0]) + #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits) ((v0) >> (32 - kNumBitsMax)) + #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits) (v1) + #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1) const UInt32 v1 = ((v0) >> (32 - kNumTableBits)); +#endif - bool Build(const Byte *lens) throw() - { - UInt32 counts[kNumBitsMax + 1]; - - unsigned i; - for (i = 0; i <= kNumBitsMax; i++) - counts[i] = 0; - - UInt32 sym; - - for (sym = 0; sym < m_NumSymbols; sym++) - counts[lens[sym]]++; - - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - _limits[0] = 0; - - UInt32 startPos = 0; - UInt32 sum = 0; - - for (i = 1; i <= kNumBitsMax; i++) - { - const UInt32 cnt = counts[i]; - startPos += cnt << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; - _limits[i] = startPos; - counts[i] = sum; - _poses[i] = sum; - sum += cnt; - } - - counts[0] = sum; - _poses[0] = sum; - _limits[kNumBitsMax + 1] = kMaxValue; - - for (sym = 0; sym < m_NumSymbols; sym++) - { - unsigned len = lens[sym]; - if (len == 0) - continue; +enum enum_BuildMode +{ + k_BuildMode_Partial = 0, + k_BuildMode_Full = 1, + k_BuildMode_Full_or_Empty = 2 +}; - unsigned offset = counts[len]++; - _symbols[offset] = (UInt16)sym; - if (len <= kNumTableBits) - { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumTableBits - len); - UInt16 val = (UInt16)((sym << kNumPairLenBits) | len); - UInt16 *dest = _lens + (_limits[(size_t)len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; - } - } - - return true; +template +struct CDecoderBase +{ + CLimitInt _limits[kNumBitsMax + 2 - kNumTableBits]; + UInt32 _poses[kNumBitsMax - kNumTableBits]; // unsigned +union +{ + // if defined(MY_CPU_64BIT), we need 64-bit alignment for _symbols. + // if !defined(MY_CPU_64BIT), we need 32-bit alignment for _symbols + // but we provide alignment for _lens. + // _symbols also will be aligned, if _lens are aligned + #if defined(MY_CPU_64BIT) + UInt64 + #else + UInt32 + #endif + _pad_align[m_NumSymbols < (1u << sizeof(symType) * 8) ? 1 : -1]; + /* if symType is Byte, we use 16-bytes padding to avoid cache + bank conflict between _lens and _symbols: */ + Byte _lens[(1 << kNumTableBits) + (sizeof(symType) == 1 ? 16 : 0)]; +} _u; + symType _symbols[(1 << kNumTableBits) + m_NumSymbols - (kNumTableBits + 1)]; + + /* + Z7_FORCE_INLINE + bool IsFull() const + { + return _limits[kNumBitsMax - kNumTableBits] == + (CLimitInt)1u << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax); } + Z7_FORCE_INLINE + bool IsEmpty() const + { + return _limits[kNumBitsMax - kNumTableBits] == 0; + } + Z7_FORCE_INLINE + bool Is_Full_or_Empty() const + { + return 0 == (_limits[kNumBitsMax - kNumTableBits] & + ~((CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax))); + } + */ - - bool BuildFull(const Byte *lens, UInt32 numSymbols = m_NumSymbols) throw() + Z7_FORCE_INLINE + bool Build(const Byte *lens, enum_BuildMode buidMode = k_BuildMode_Partial) throw() { - UInt32 counts[kNumBitsMax + 1]; - - unsigned i; + unsigned counts[kNumBitsMax + 1]; + size_t i; for (i = 0; i <= kNumBitsMax; i++) counts[i] = 0; + for (i = 0; i < m_NumSymbols; i++) + counts[lens[i]]++; - UInt32 sym; - - for (sym = 0; sym < numSymbols; sym++) - counts[lens[sym]]++; - - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - - _limits[0] = 0; - - UInt32 startPos = 0; UInt32 sum = 0; - - for (i = 1; i <= kNumBitsMax; i++) + for (i = 1; i <= kNumTableBits; i++) { - const UInt32 cnt = counts[i]; - startPos += cnt << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; - _limits[i] = startPos; + sum <<= 1; + sum += counts[i]; + } + + CLimitInt startPos = (CLimitInt)sum; + _limits[0] = + #ifdef Z7_HUFF_USE_64BIT_LIMIT + startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - kNumTableBits); + #else + startPos; + #endif + + for (i = kNumTableBits + 1; i <= kNumBitsMax; i++) + { + startPos <<= 1; + _poses[i - (kNumTableBits + 1)] = (UInt32)(startPos - sum); + const unsigned cnt = counts[i]; counts[i] = sum; - _poses[i] = sum; sum += cnt; + startPos += cnt; + _limits[i - kNumTableBits] = startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - i); } - counts[0] = sum; - _poses[0] = sum; - _limits[kNumBitsMax + 1] = kMaxValue; + _limits[kNumBitsMax + 1 - kNumTableBits] = + (CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax); + + if (buidMode == k_BuildMode_Partial) + { + if (startPos > (1u << kNumBitsMax)) return false; + } + else + { + if (buidMode != k_BuildMode_Full && startPos == 0) return true; + if (startPos != (1u << kNumBitsMax)) return false; + } + size_t sum2 = 0; + for (i = 1; i <= kNumTableBits; i++) + { + const unsigned cnt = counts[i] << (kNumTableBits - i); + counts[i] = (unsigned)sum2 >> (kNumTableBits - i); + memset(_u._lens + sum2, (int)i, cnt); + sum2 += cnt; + } - for (sym = 0; sym < numSymbols; sym++) +#ifdef MY_CPU_64BIT + symType4 + // UInt64 // for symType = UInt16 + // UInt32 // for symType = Byte +#else + UInt32 +#endif + v = 0; + for (i = 0; i < m_NumSymbols; i++, + v += + 1 + + ( (UInt32)1 << (sizeof(symType) * 8 * 1)) + // 0x00010001 // for symType = UInt16 + // 0x00000101 // for symType = Byte +#ifdef MY_CPU_64BIT + + ((symType4)1 << (sizeof(symType) * 8 * 2)) + + ((symType4)1 << (sizeof(symType) * 8 * 3)) + // 0x0001000100010001 // for symType = UInt16 + // 0x0000000001010101 // for symType = Byte +#endif + ) { - unsigned len = lens[sym]; + const unsigned len = lens[i]; if (len == 0) continue; - - unsigned offset = counts[len]++; - _symbols[offset] = (UInt16)sym; - - if (len <= kNumTableBits) + const size_t offset = counts[len]; + counts[len] = (unsigned)offset + 1; + if (len >= kNumTableBits) + _symbols[offset] = (symType)v; + else { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumTableBits - len); - UInt16 val = (UInt16)((sym << kNumPairLenBits) | len); - UInt16 *dest = _lens + (_limits[(size_t)len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; + Byte *s2 = (Byte *)(void *)_symbols + (offset << + (kNumTableBits + sizeof(symType) / 2 - len)); + Byte *lim = s2 + ((size_t)1 << + (kNumTableBits + sizeof(symType) / 2 - len)); + if (len >= kNumTableBits - 2) + { + *(symType2 *)(void *)(s2 ) = (symType2)v; + *(symType2 *)(void *)(lim - sizeof(symType) * 2) = (symType2)v; + } + else + { +#ifdef MY_CPU_64BIT + symType4 *s = (symType4 *)(void *)s2; + do + { + s[0] = v; s[1] = v; s += 2; + } + while (s != (const symType4 *)(const void *)lim); +#else + symType2 *s = (symType2 *)(void *)s2; + do + { + s[0] = (symType2)v; s[1] = (symType2)v; s += 2; + s[0] = (symType2)v; s[1] = (symType2)v; s += 2; + } + while (s != (const symType2 *)(const void *)lim); +#endif + } } } - - return startPos == kMaxValue; + return true; } + +#define Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES(_numBits_, kNumBitsMax, error_op) if (_numBits_ > kNumBitsMax) { error_op } +#define Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO( _numBits_, kNumBitsMax, error_op) + +#define Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_limits, \ + check_op, error_op, _numBits_) \ +{ \ + const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \ + _numBits_ = kNumTableBits + 1; \ + if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \ + do { _numBits_++; } \ + while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \ + check_op(_numBits_, kNumBitsMax, error_op) \ + sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \ + - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \ +} + +/* + Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_limits, \ + check_op, error_op, _numBits_) \ + +*/ + +#define Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_table, get_val_for_limits, \ + check_op, error_op, move_pos_op, after_op, bs) \ +{ \ + if (Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1)) \ + { \ + const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \ + size_t _numBits_ = kNumTableBits + 1; \ + if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \ + do { _numBits_++; } \ + while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \ + check_op(_numBits_, kNumBitsMax, error_op) \ + sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \ + - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \ + move_pos_op(bs, _numBits_); \ + } \ + else \ + { \ + const size_t _val = get_val_for_table(v0, v1, kNumBitsMax, kNumTableBits); \ + const size_t _numBits_ = (huf)->_u._lens[_val]; \ + sym = (huf)->_symbols[_val]; \ + move_pos_op(bs, _numBits_); \ + } \ + after_op \ +} + +#define Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + check_op, error_op, move_pos_op, after_op, bs) \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS, \ + check_op, error_op, move_pos_op, after_op, bs) \ + + +#define Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, \ + check_op, error_op, move_pos_op, after_op, bs) \ +{ \ + Z7_HUFF_PRECALC_V1(kNumTableBits, v0, _v1_temp) \ + Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, _v1_temp, \ + check_op, error_op, move_pos_op, after_op, bs) \ +} + +#if 0 || defined(Z7_HUFF_USE_64BIT_LIMIT) +// this branch uses bitStream->GetValue_InHigh32bits(). +#define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, \ + check_op, error_op, move_pos_op) \ +{ \ + const UInt32 v0 = (bitStream)->GetValue_InHigh32bits(); \ + Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1); \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS, \ + check_op, error_op, move_pos_op, {}, bitStream) \ +} +#else +/* +this branch uses bitStream->GetValue(). +So we use SIMPLE versions for v0, v1 calculation: + v0 is normalized for kNumBitsMax + v1 is normalized for kNumTableBits +*/ +#define Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE(v0, v1, kNumBitsMax, kNumTableBits) v0 +#define Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE( v0, v1, kNumBitsMax, kNumTableBits) v1 +#define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, move_pos_op) \ +{ \ + const UInt32 v0 = (bitStream)->GetValue(kNumBitsMax); \ + const UInt32 v1 = v0 >> (kNumBitsMax - kNumTableBits); \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE, \ + check_op, error_op, move_pos_op, {}, bitStream) \ +} +#endif + +#define Z7_HUFF_bitStream_MovePos(bitStream, numBits) (bitStream)->MovePos((unsigned)(numBits)) + +#define Z7_HUFF_DECODE_1(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \ + Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \ + Z7_HUFF_bitStream_MovePos) + +// MovePosCheck + +#define Z7_HUFF_DECODE_2(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \ + Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \ + Z7_HUFF_bitStream_MovePos) + +// MovePosCheck + +#define Z7_HUFF_DECODE_CHECK(sym, huf, kNumBitsMax, kNumTableBits, bitStream, error_op) \ + Z7_HUFF_DECODE_1( sym, huf, kNumBitsMax, kNumTableBits, bitStream, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, error_op) + template - MY_FORCE_INLINE - UInt32 Decode(TBitDecoder *bitStream) const + Z7_FORCE_INLINE + bool Decode2(TBitDecoder *bitStream, unsigned &sym) const { - UInt32 val = bitStream->GetValue(kNumBitsMax); - - if (val < _limits[kNumTableBits]) - { - UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)]; - bitStream->MovePos((unsigned)(pair & kPairLenMask)); - return pair >> kNumPairLenBits; - } + Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream, + { return false; } + ) + return true; + } - unsigned numBits; - for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++); - - if (numBits > kNumBitsMax) - return 0xFFFFFFFF; + template + Z7_FORCE_INLINE + bool Decode_SymCheck_MovePosCheck(TBitDecoder *bitStream, unsigned &sym) const + { + Z7_HUFF_DECODE_0(sym, this, kNumBitsMax, kNumTableBits, bitStream, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, + { return false; }, + { return (bitStream)->MovePosCheck; } + ) + } - bitStream->MovePos(numBits); - UInt32 index = _poses[numBits] + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits)); - return _symbols[index]; + template + Z7_FORCE_INLINE + unsigned Decode(TBitDecoder *bitStream) const + { + unsigned sym; + Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream, + { return (unsigned)(int)(Int32)0xffffffff; } + ) + return sym; } template - MY_FORCE_INLINE - UInt32 DecodeFull(TBitDecoder *bitStream) const + Z7_FORCE_INLINE + unsigned DecodeFull(TBitDecoder *bitStream) const { - UInt32 val = bitStream->GetValue(kNumBitsMax); - + /* + const UInt32 val = bitStream->GetValue(kNumBitsMax); if (val < _limits[kNumTableBits]) { - UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)]; - bitStream->MovePos((unsigned)(pair & kPairLenMask)); + const unsigned pair = _u._lens[(size_t)(val >> (kNumBitsMax - kNumTableBits))]; + bitStream->MovePos(pair & kPairLenMask); return pair >> kNumPairLenBits; } @@ -182,49 +405,55 @@ for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++); bitStream->MovePos(numBits); - UInt32 index = _poses[numBits] + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits)); - return _symbols[index]; + return _symbols[_poses[numBits] + (unsigned) + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits))]; + */ + unsigned sym; + Z7_HUFF_DECODE_2(sym, this, kNumBitsMax, kNumTableBits, bitStream, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {} + ) + return sym; } }; +template +struct CDecoder: public CDecoderBase + {}; + +template +struct CDecoder256: public CDecoderBase + {}; + -template +template class CDecoder7b { - Byte _lens[1 << 7]; public: + Byte _lens[1 << 7]; - bool Build(const Byte *lens) throw() + bool Build(const Byte *lens, bool full) throw() { const unsigned kNumBitsMax = 7; - UInt32 counts[kNumBitsMax + 1]; - UInt32 _poses[kNumBitsMax + 1]; - UInt32 _limits[kNumBitsMax + 1]; - + unsigned counts[kNumBitsMax + 1]; + unsigned _poses[kNumBitsMax + 1]; + unsigned _limits[kNumBitsMax + 1]; unsigned i; for (i = 0; i <= kNumBitsMax; i++) counts[i] = 0; + for (i = 0; i < numSymbols; i++) + counts[lens[i]]++; - UInt32 sym; - - for (sym = 0; sym < m_NumSymbols; sym++) - counts[lens[sym]]++; - - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - _limits[0] = 0; - - UInt32 startPos = 0; - UInt32 sum = 0; + const unsigned kMaxValue = 1u << kNumBitsMax; + unsigned startPos = 0; + unsigned sum = 0; for (i = 1; i <= kNumBitsMax; i++) { - const UInt32 cnt = counts[i]; + const unsigned cnt = counts[i]; startPos += cnt << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; _limits[i] = startPos; counts[i] = sum; _poses[i] = sum; @@ -234,41 +463,61 @@ counts[0] = sum; _poses[0] = sum; - for (sym = 0; sym < m_NumSymbols; sym++) + if (full) { - unsigned len = lens[sym]; - if (len == 0) - continue; + if (startPos != kMaxValue) + return false; + } + else + { + if (startPos > kMaxValue) + return false; + } - unsigned offset = counts[len]++; + for (i = 0; i < numSymbols; i++) + { + const unsigned len = lens[i]; + if (len == 0) + continue; + const unsigned offset = counts[len]++; { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumBitsMax - len); - Byte val = (Byte)((sym << 3) | len); - Byte *dest = _lens + (_limits[(size_t)len - 1]) + (offset << (kNumBitsMax - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; + Byte *dest = _lens + _limits[(size_t)len - 1] + + ((offset - _poses[len]) << (kNumBitsMax - len)); + const unsigned num = (unsigned)1 << (kNumBitsMax - len); + const unsigned val = (i << 3) + len; + for (unsigned k = 0; k < num; k++) + dest[k] = (Byte)val; } } + if (!full) { - UInt32 limit = _limits[kNumBitsMax]; - UInt32 num = ((UInt32)1 << kNumBitsMax) - limit; + const unsigned limit = _limits[kNumBitsMax]; + const unsigned num = ((unsigned)1 << kNumBitsMax) - limit; Byte *dest = _lens + limit; - for (UInt32 k = 0; k < num; k++) - dest[k] = (Byte)(0x1F << 3); + for (unsigned k = 0; k < num; k++) + dest[k] = (Byte) + // (0x1f << 3); + ((0x1f << 3) + 0x7); } return true; } +#define Z7_HUFF_DECODER_7B_DECODE(dest, huf, get_val, move_pos, bs) \ + { \ + const unsigned pair = huf->_lens[(size_t)get_val(7)]; \ + const unsigned numBits = pair & 0x7; \ + move_pos(bs, numBits); \ + dest = pair >> 3; \ + } + template - UInt32 Decode(TBitDecoder *bitStream) const + unsigned Decode(TBitDecoder *bitStream) const { - UInt32 val = bitStream->GetValue(7); - UInt32 pair = _lens[val]; - bitStream->MovePos((unsigned)(pair & 0x7)); + const unsigned pair = _lens[(size_t)bitStream->GetValue(7)]; + bitStream->MovePos(pair & 0x7); return pair >> 3; } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.cpp 2020-09-28 07:37:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.cpp 2023-12-22 11:00:00.000000000 +0000 @@ -13,26 +13,21 @@ bool CHuffmanDecoder::Build(const Byte *lens, unsigned numSymbols) throw() { unsigned counts[kNumHuffmanBits + 1]; - unsigned i; for (i = 0; i <= kNumHuffmanBits; i++) counts[i] = 0; - - unsigned sym; - for (sym = 0; sym < numSymbols; sym++) - counts[lens[sym]]++; + for (i = 0; i < numSymbols; i++) + counts[lens[i]]++; const UInt32 kMaxValue = (UInt32)1 << kNumHuffmanBits; - // _limits[0] = kMaxValue; - UInt32 startPos = kMaxValue; - UInt32 sum = 0; + unsigned sum = 0; for (i = 1; i <= kNumHuffmanBits; i++) { - const UInt32 cnt = counts[i]; - const UInt32 range = cnt << (kNumHuffmanBits - i); + const unsigned cnt = counts[i]; + const UInt32 range = (UInt32)cnt << (kNumHuffmanBits - i); if (startPos < range) return false; startPos -= range; @@ -41,29 +36,26 @@ sum += cnt; counts[i] = sum; } - // counts[0] += sum; - if (startPos != 0) return false; - - for (sym = 0; sym < numSymbols; sym++) + for (i = 0; i < numSymbols; i++) { - unsigned len = lens[sym]; + const unsigned len = lens[i]; if (len != 0) - _symbols[--counts[len]] = (Byte)sym; + _symbols[--counts[len]] = (Byte)i; } - return true; } -UInt32 CHuffmanDecoder::Decode(CInBit *inStream) const throw() +unsigned CHuffmanDecoder::Decode(CInBit *inStream) const throw() { - UInt32 val = inStream->GetValue(kNumHuffmanBits); - unsigned numBits; + const UInt32 val = inStream->GetValue(kNumHuffmanBits); + size_t numBits; for (numBits = 1; val < _limits[numBits]; numBits++); - UInt32 sym = _symbols[_poses[numBits] + ((val - _limits[numBits]) >> (kNumHuffmanBits - numBits))]; + const unsigned sym = _symbols[_poses[numBits] + + (unsigned)((val - _limits[numBits]) >> (kNumHuffmanBits - numBits))]; inStream->MovePos(numBits); return sym; } @@ -95,13 +87,13 @@ unsigned index = 0; do { - unsigned b = (unsigned)_inBitStream.ReadAlignedByte(); - Byte level = (Byte)((b & 0xF) + 1); - unsigned rep = ((unsigned)b >> 4) + 1; + const unsigned b = (unsigned)_inBitStream.ReadAlignedByte(); + const unsigned level = (b & 0xF) + 1; + const unsigned rep = ((unsigned)b >> 4) + 1; if (index + rep > numSymbols) return false; for (unsigned j = 0; j < rep; j++) - levels[index++] = level; + levels[index++] = (Byte)level; } while (--numRecords); @@ -146,11 +138,11 @@ while (pos < unPackSize) { - if (progress && (pos - prevProgress) >= (1 << 18)) + if (pos - prevProgress >= (1u << 18) && progress) { - const UInt64 packSize = _inBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); prevProgress = pos; + const UInt64 packSize = _inBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) } if (_inBitStream.ReadBits(1) != 0) @@ -158,7 +150,7 @@ Byte b; if (literalsOn) { - UInt32 sym = _litDecoder.Decode(&_inBitStream); + const unsigned sym = _litDecoder.Decode(&_inBitStream); // if (sym >= kLitTableSize) break; b = (Byte)sym; } @@ -169,37 +161,37 @@ } else { - UInt32 lowDistBits = _inBitStream.ReadBits(numDistDirectBits); - UInt32 dist = _distDecoder.Decode(&_inBitStream); + const UInt32 lowDistBits = _inBitStream.ReadBits(numDistDirectBits); + UInt32 dist = (UInt32)_distDecoder.Decode(&_inBitStream); // if (dist >= kDistTableSize) break; dist = (dist << numDistDirectBits) + lowDistBits; - UInt32 len = _lenDecoder.Decode(&_inBitStream); + unsigned len = _lenDecoder.Decode(&_inBitStream); // if (len >= kLenTableSize) break; if (len == kLenTableSize - 1) len += _inBitStream.ReadBits(kNumLenDirectBits); len += minMatchLen; - { const UInt64 limit = unPackSize - pos; + // limit != 0 if (len > limit) { moreOut = true; len = (UInt32)limit; } } - - while (dist >= pos && len != 0) + do { + // len != 0 + if (dist < pos) + { + _outWindowStream.CopyBlock(dist, len); + pos += len; + break; + } _outWindowStream.PutByte(0); pos++; - len--; - } - - if (len != 0) - { - _outWindowStream.CopyBlock(dist, len); - pos += len; } + while (--len); } } @@ -222,8 +214,8 @@ } -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } // catch(const CInBufferException &e) { return e.ErrorCode; } @@ -233,7 +225,7 @@ } -STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) { if (size == 0) return E_NOTIMPL; @@ -242,14 +234,14 @@ } -STDMETHODIMP CCoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CCoder::SetFinishMode(UInt32 finishMode)) { _fullStreamMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CCoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inBitStream.GetProcessedSize(); return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.h 2017-01-06 09:57:34.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeDecoder.h 2023-12-22 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ImplodeDecoder.h -#ifndef __COMPRESS_IMPLODE_DECODER_H -#define __COMPRESS_IMPLODE_DECODER_H +#ifndef ZIP7_INC_COMPRESS_IMPLODE_DECODER_H +#define ZIP7_INC_COMPRESS_IMPLODE_DECODER_H #include "../../Common/MyCom.h" @@ -28,17 +28,20 @@ Byte _symbols[kMaxHuffTableSize]; public: bool Build(const Byte *lens, unsigned numSymbols) throw(); - UInt32 Decode(CInBit *inStream) const throw(); + unsigned Decode(CInBit *inStream) const throw(); }; -class CCoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_4( + CCoder + , ICompressCoder + , ICompressSetDecoderProperties2 + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + Byte _flags; + bool _fullStreamMode; + CLzOutWindow _outWindowStream; CInBit _inBitStream; @@ -46,25 +49,10 @@ CHuffmanDecoder _lenDecoder; CHuffmanDecoder _distDecoder; - Byte _flags; - bool _fullStreamMode; - bool BuildHuff(CHuffmanDecoder &table, unsigned numSymbols); HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - public: - MY_UNKNOWN_IMP3( - ICompressSetDecoderProperties2, - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - CCoder(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeHuffmanDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeHuffmanDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ImplodeHuffmanDecoder.h 2017-04-25 10:46:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ImplodeHuffmanDecoder.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ // ImplodeHuffmanDecoder.h -#ifndef __IMPLODE_HUFFMAN_DECODER_H -#define __IMPLODE_HUFFMAN_DECODER_H +#ifndef ZIP7_INC_IMPLODE_HUFFMAN_DECODER_H +#define ZIP7_INC_IMPLODE_HUFFMAN_DECODER_H #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzOutWindow.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzOutWindow.cpp 2014-12-30 09:59:53.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.cpp 2023-03-28 11:00:00.000000000 +0000 @@ -8,7 +8,7 @@ { if (!solid) COutBuffer::Init(); - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzOutWindow.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzOutWindow.h 2018-01-24 16:04:57.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzOutWindow.h 2023-03-28 11:00:00.000000000 +0000 @@ -1,11 +1,11 @@ // LzOutWindow.h -#ifndef __LZ_OUT_WINDOW_H -#define __LZ_OUT_WINDOW_H +#ifndef ZIP7_INC_LZ_OUT_WINDOW_H +#define ZIP7_INC_LZ_OUT_WINDOW_H #include "../Common/OutBuffer.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS typedef COutBufferException CLzOutWindowException; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzfseDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzfseDecoder.cpp 2022-07-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.cpp 2024-01-01 10:00:00.000000000 +0000 @@ -80,7 +80,7 @@ UInt32 cur = unpackSize; if (cur > kBufSize) cur = kBufSize; - UInt32 cur2 = (UInt32)m_InStream.ReadBytes(buf, cur); + const UInt32 cur2 = (UInt32)m_InStream.ReadBytes(buf, cur); m_OutWindowStream.PutBytes(buf, cur2); if (cur != cur2) return S_FALSE; @@ -91,7 +91,7 @@ HRESULT CDecoder::DecodeLzvn(UInt32 unpackSize, UInt32 packSize) { - PRF(printf("\nLZVN %7u %7u", unpackSize, packSize)); + PRF(printf("\nLZVN 0x%07x 0x%07x\n", unpackSize, packSize)); UInt32 D = 0; @@ -241,19 +241,27 @@ return S_FALSE; // LZVN encoder writes 7 additional zero bytes - if (packSize != 7) + if (packSize < 7) return S_FALSE; - do + for (unsigned i = 0; i < 7; i++) { Byte b; if (!m_InStream.ReadByte(b)) return S_FALSE; - packSize--; if (b != 0) return S_FALSE; } - while (packSize != 0); - + packSize -= 7; + if (packSize) + { + PRF(printf("packSize after unused = %u\n", packSize)); + // if (packSize <= 0x100) { Byte buf[0x100]; m_InStream.ReadBytes(buf, packSize); } + /* Lzvn block that is used in HFS can contain junk data + (at least 256 bytes) after payload data. Why? + We ignore that junk data, if it's HFS (LzvnMode) mode. */ + if (!LzvnMode) + return S_FALSE; + } return S_OK; } @@ -293,7 +301,7 @@ } -static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) +static Z7_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) { for (unsigned i = 0;;) { @@ -305,7 +313,7 @@ } -static MY_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) +static Z7_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) { for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++) { @@ -440,7 +448,7 @@ } CBitStream; -static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s, +static Z7_FORCE_INLINE int FseInStream_Init(CBitStream *s, int n, // [-7, 0], (-n == number_of_unused_bits) in last byte const Byte **pbuf) { @@ -448,7 +456,7 @@ s->accum = GetUi32(*pbuf); if (n) { - s->numBits = n + 32; + s->numBits = (unsigned)(n + 32); if ((s->accum >> s->numBits) != 0) return -1; // ERROR, encoder should have zeroed the upper bits } @@ -466,7 +474,7 @@ #define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1)) #define FseInStream_FLUSH \ - { unsigned nbits = (31 - in.numBits) & -8; \ + { const unsigned nbits = (31 - in.numBits) & (unsigned)-8; \ if (nbits) { \ buf -= (nbits >> 3); \ if (buf < buf_check) return S_FALSE; \ @@ -476,10 +484,10 @@ -static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) +static Z7_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) { s->numBits -= numBits; - UInt32 v = s->accum >> s->numBits; + const UInt32 v = s->accum >> s->numBits; s->accum = mask31(s->accum, s->numBits); return v; } @@ -491,7 +499,7 @@ dest = (Byte)(e >> 8); } -static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, +static Z7_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, const CExtraEntry *table, CBitStream *s) { @@ -509,6 +517,7 @@ #define freqs_LIT (freqs_D + NUM_D_SYMBOLS) #define GET_BITS_64(v, offset, num, dest) dest = (UInt32) ((v >> (offset)) & ((1 << (num)) - 1)); +#define GET_BITS_64_Int32(v, offset, num, dest) dest = (Int32)((v >> (offset)) & ((1 << (num)) - 1)); #define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1)); @@ -592,22 +601,22 @@ UInt64 v; v = GetUi64(temp); - GET_BITS_64(v, 0, 20, numLiterals); - GET_BITS_64(v, 20, 20, litPayloadSize); - GET_BITS_64(v, 40, 20, numMatches); - GET_BITS_64(v, 60, 3 + 1, literal_bits); // (NumberOfUsedBits - 1) + GET_BITS_64(v, 0, 20, numLiterals) + GET_BITS_64(v, 20, 20, litPayloadSize) + GET_BITS_64(v, 40, 20, numMatches) + GET_BITS_64_Int32(v, 60, 3 + 1, literal_bits) // (NumberOfUsedBits - 1) literal_bits -= 7; // (-NumberOfUnusedBits) if (literal_bits > 0) return S_FALSE; // GET_BITS_64(v, 63, 1, unused); v = GetUi64(temp + 8); - GET_BITS_64(v, 0, 10, lit_state_0); - GET_BITS_64(v, 10, 10, lit_state_1); - GET_BITS_64(v, 20, 10, lit_state_2); - GET_BITS_64(v, 30, 10, lit_state_3); - GET_BITS_64(v, 40, 20, lmdPayloadSize); - GET_BITS_64(v, 60, 3 + 1, lmd_bits); + GET_BITS_64(v, 0, 10, lit_state_0) + GET_BITS_64(v, 10, 10, lit_state_1) + GET_BITS_64(v, 20, 10, lit_state_2) + GET_BITS_64(v, 30, 10, lit_state_3) + GET_BITS_64(v, 40, 20, lmdPayloadSize) + GET_BITS_64_Int32(v, 60, 3 + 1, lmd_bits) lmd_bits -= 7; if (lmd_bits > 0) return S_FALSE; @@ -618,10 +627,10 @@ // correspond to a field in the uncompressed header version, // but is required; we wouldn't know the size of the // compresssed header otherwise. - GET_BITS_32(v32, 0, 10, l_state); - GET_BITS_32(v32, 10, 10, m_state); - GET_BITS_32(v32, 20, 10 + 2, d_state); - // GET_BITS_64(v, 62, 2, unused); + GET_BITS_32(v32, 0, 10, l_state) + GET_BITS_32(v32, 10, 10, m_state) + GET_BITS_32(v32, 20, 10 + 2, d_state) + // GET_BITS_64(v, 62, 2, unused) headerSize = GetUi32(temp + 16); if (headerSize <= kPreHeaderSize + kHeaderSize) @@ -726,11 +735,11 @@ for (; lit < lit_limit; lit += 4) { FseInStream_FLUSH - DECODE_LIT (lit[0], lit_state_0); - DECODE_LIT (lit[1], lit_state_1); + DECODE_LIT (lit[0], lit_state_0) + DECODE_LIT (lit[1], lit_state_1) FseInStream_FLUSH - DECODE_LIT (lit[2], lit_state_2); - DECODE_LIT (lit[3], lit_state_3); + DECODE_LIT (lit[2], lit_state_2) + DECODE_LIT (lit[3], lit_state_3) } if ((buf_start - buf) * 8 != (int)in.numBits) @@ -821,7 +830,7 @@ // LZFSE encoder writes 8 additional zero bytes before LMD payload // We test it: - if ((buf - buf_start) * 8 + in.numBits != 64) + if ((size_t)(buf - buf_start) * 8 + in.numBits != 64) return S_FALSE; if (GetUi64(buf_start) != 0) return S_FALSE; @@ -830,7 +839,7 @@ } -STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize)); @@ -853,12 +862,14 @@ if (LzvnMode) { + if (!outSize || !inSize) + return E_NOTIMPL; const UInt64 unpackSize = *outSize; const UInt64 packSize = *inSize; if (unpackSize > (UInt32)(Int32)-1 || packSize > (UInt32)(Int32)-1) return S_FALSE; - RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize)); + RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize)) } else for (;;) @@ -868,12 +879,11 @@ if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22))) { - RINOK(progress->SetRatioInfo(&packPos, &pos)); + RINOK(progress->SetRatioInfo(&packPos, &pos)) prevIn = packPos; prevOut = pos; } - const UInt64 rem = *outSize - pos; UInt32 v; RINOK(GetUInt32(v)) if ((v & 0xFFFFFF) != 0x787662) // bvx @@ -884,12 +894,15 @@ break; UInt32 unpackSize; - RINOK(GetUInt32(unpackSize)); - + RINOK(GetUInt32(unpackSize)) + UInt32 cur = unpackSize; - if (cur > rem) - cur = (UInt32)rem; - + if (outSize) + { + const UInt64 rem = *outSize - pos; + if (cur > rem) + cur = (UInt32)rem; + } unpackSize -= cur; HRESULT res; @@ -917,15 +930,15 @@ coderReleaser.NeedFlush = false; HRESULT res = m_OutWindowStream.Flush(); if (res == S_OK) - if (*inSize != m_InStream.GetProcessedSize() - || *outSize != m_OutWindowStream.GetProcessedSize()) + if ((!LzvnMode && inSize && *inSize != m_InStream.GetProcessedSize()) + || (outSize && *outSize != m_OutWindowStream.GetProcessedSize())) res = S_FALSE; return res; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } catch(const CInBufferException &e) { return e.ErrorCode; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzfseDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzfseDecoder.h 2022-07-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzfseDecoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LzfseDecoder.h -#ifndef __LZFSE_DECODER_H -#define __LZFSE_DECODER_H +#ifndef ZIP7_INC_LZFSE_DECODER_H +#define ZIP7_INC_LZFSE_DECODER_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -15,10 +15,10 @@ namespace NCompress { namespace NLzfse { -class CDecoder: - public ICompressCoder, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CDecoder + , ICompressCoder +) CLzOutWindow m_OutWindowStream; CInBuffer m_InStream; CByteBuffer _literals; @@ -44,11 +44,10 @@ HRESULT DecodeLzvn(UInt32 unpackSize, UInt32 packSize); HRESULT DecodeLzfse(UInt32 unpackSize, Byte version); - STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); public: bool LzvnMode; - MY_UNKNOWN_IMP CDecoder(): LzvnMode(false) @@ -57,9 +56,6 @@ // sizes are checked in Code() // UInt64 GetInputProcessedSize() const { return m_InStream.GetProcessedSize(); } // UInt64 GetOutputProcessedSize() const { return m_OutWindowStream.GetProcessedSize(); } - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, - const UInt64 *outSize, ICompressProgressInfo *progress); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzhDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzhDecoder.cpp 2015-09-03 12:04:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -10,29 +10,17 @@ static const UInt32 kWindowSizeMin = 1 << 16; -static bool CheckCodeLens(const Byte *lens, unsigned num) -{ - UInt32 sum = 0; - for (unsigned i = 0; i < num; i++) - { - unsigned len = lens[i]; - if (len != 0) - sum += ((UInt32)1 << (NUM_CODE_BITS - len)); - } - return sum == ((UInt32)1 << NUM_CODE_BITS); -} - bool CCoder::ReadTP(unsigned num, unsigned numBits, int spec) { _symbolT = -1; - UInt32 n = _inBitStream.ReadBits(numBits); + const unsigned n = (unsigned)_inBitStream.ReadBits(numBits); if (n == 0) { - _symbolT = _inBitStream.ReadBits(numBits); - return ((unsigned)_symbolT < num); + const unsigned s = (unsigned)_inBitStream.ReadBits(numBits); + _symbolT = (int)s; + return (s < num); } - if (n > num) return false; @@ -41,37 +29,31 @@ unsigned i; for (i = 0; i < NPT; i++) lens[i] = 0; - i = 0; - do { - UInt32 val = _inBitStream.GetValue(16); + unsigned val = (unsigned)_inBitStream.GetValue(16); unsigned c = val >> 13; - + unsigned mov = 3; if (c == 7) { - UInt32 mask = 1 << 12; - while (mask & val) + while (val & (1 << 12)) { - mask >>= 1; + val += val; c++; } if (c > 16) return false; + mov = c - 3; } - - _inBitStream.MovePos(c < 7 ? 3 : c - 3); lens[i++] = (Byte)c; - - if (i == (unsigned)spec) + _inBitStream.MovePos(mov); + if ((int)i == spec) i += _inBitStream.ReadBits(2); } while (i < n); - if (!CheckCodeLens(lens, NPT)) - return false; - return _decoderT.Build(lens); + return _decoderT.Build(lens, NHuffman::k_BuildMode_Full); } } @@ -81,27 +63,24 @@ { _symbolC = -1; - unsigned n = _inBitStream.ReadBits(NUM_C_BITS); - + const unsigned n = (unsigned)_inBitStream.ReadBits(NUM_C_BITS); if (n == 0) { - _symbolC = _inBitStream.ReadBits(NUM_C_BITS); - return ((unsigned)_symbolC < NC); + const unsigned s = (unsigned)_inBitStream.ReadBits(NUM_C_BITS); + _symbolC = (int)s; + return (s < NC); } - if (n > NC) return false; { Byte lens[NC]; - unsigned i = 0; - do { - UInt32 c = (unsigned)_symbolT; + unsigned c = (unsigned)_symbolT; if (_symbolT < 0) - c = _decoderT.Decode(&_inBitStream); + c = _decoderT.DecodeFull(&_inBitStream); if (c <= 2) { @@ -124,19 +103,13 @@ } while (i < n); - while (i < NC) - lens[i++] = 0; - - if (!CheckCodeLens(lens, NC)) - return false; - return _decoderC.Build(lens); + while (i < NC) lens[i++] = 0; + return _decoderC.Build(lens, /* n, */ NHuffman::k_BuildMode_Full); } } -HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress) +HRESULT CCoder::CodeReal(UInt32 rem, ICompressProgressInfo *progress) { - unsigned pbit = (DictSize <= (1 << 14) ? 4 : 5); - UInt32 blockSize = 0; while (rem != 0) @@ -145,12 +118,11 @@ { if (_inBitStream.ExtraBitsWereRead()) return S_FALSE; - if (progress) { - UInt64 packSize = _inBitStream.GetProcessedSize(); - UInt64 pos = _outWindow.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); + const UInt64 packSize = _inBitStream.GetProcessedSize(); + const UInt64 pos = _outWindow.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) } blockSize = _inBitStream.ReadBits(16); @@ -161,15 +133,16 @@ return S_FALSE; if (!ReadC()) return S_FALSE; + const unsigned pbit = (DictSize <= (1 << 14) ? 4 : 5); if (!ReadTP(NP, pbit, -1)) return S_FALSE; } blockSize--; - UInt32 number = (unsigned)_symbolC; + unsigned number = (unsigned)_symbolC; if (_symbolC < 0) - number = _decoderC.Decode(&_inBitStream); + number = _decoderC.DecodeFull(&_inBitStream); if (number < 256) { @@ -178,11 +151,11 @@ } else { - UInt32 len = number - 256 + kMatchMinLen; + const unsigned len = number - 256 + kMatchMinLen; - UInt32 dist = (unsigned)_symbolT; + UInt32 dist = (UInt32)(unsigned)_symbolT; if (_symbolT < 0) - dist = _decoderT.Decode(&_inBitStream); + dist = (UInt32)_decoderT.DecodeFull(&_inBitStream); if (dist > 1) { @@ -194,7 +167,11 @@ return S_FALSE; if (len > rem) - len = (UInt32)rem; + { + // if (FinishMode) + return S_FALSE; + // len = (unsigned)rem; + } if (!_outWindow.CopyBlock(dist, len)) return S_FALSE; @@ -202,44 +179,37 @@ } } - if (FinishMode) + // if (FinishMode) { if (blockSize != 0) return S_FALSE; if (_inBitStream.ReadAlignBits() != 0) return S_FALSE; } - if (_inBitStream.ExtraBitsWereRead()) return S_FALSE; - return S_OK; } -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt32 outSize, ICompressProgressInfo *progress) { try { - if (!outSize) - return E_INVALIDARG; - if (!_outWindow.Create(DictSize > kWindowSizeMin ? DictSize : kWindowSizeMin)) return E_OUTOFMEMORY; if (!_inBitStream.Create(1 << 17)) return E_OUTOFMEMORY; - _outWindow.SetStream(outStream); _outWindow.Init(false); _inBitStream.SetStream(inStream); _inBitStream.Init(); - - CCoderReleaser coderReleaser(this); - - RINOK(CodeReal(*outSize, progress)); - - coderReleaser.Disable(); + { + CCoderReleaser coderReleaser(this); + RINOK(CodeReal(outSize, progress)) + coderReleaser.Disable(); + } return _outWindow.Flush(); } catch(const CInBufferException &e) { return e.ErrorCode; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzhDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzhDecoder.h 2015-05-11 09:36:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzhDecoder.h 2024-01-07 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LzhDecoder.h -#ifndef __COMPRESS_LZH_DECODER_H -#define __COMPRESS_LZH_DECODER_H +#ifndef ZIP7_INC_COMPRESS_LZH_DECODER_H +#define ZIP7_INC_COMPRESS_LZH_DECODER_H #include "../../Common/MyCom.h" @@ -19,25 +19,25 @@ const unsigned kMatchMinLen = 3; const unsigned kMatchMaxLen = 256; -const unsigned NC = (256 + kMatchMaxLen - kMatchMinLen + 1); +const unsigned NC = 256 + kMatchMaxLen - kMatchMinLen + 1; const unsigned NUM_CODE_BITS = 16; const unsigned NUM_DIC_BITS_MAX = 25; -const unsigned NT = (NUM_CODE_BITS + 3); -const unsigned NP = (NUM_DIC_BITS_MAX + 1); +const unsigned NT = NUM_CODE_BITS + 3; +const unsigned NP = NUM_DIC_BITS_MAX + 1; const unsigned NPT = NP; // Max(NT, NP) -class CCoder: - public ICompressCoder, - public CMyUnknownImp +class CCoder { CLzOutWindow _outWindow; NBitm::CDecoder _inBitStream; int _symbolT; int _symbolC; + UInt32 DictSize; + // bool FinishMode; - NHuffman::CDecoder _decoderT; - NHuffman::CDecoder _decoderC; + NHuffman::CDecoder256 _decoderT; + NHuffman::CDecoder _decoderC; class CCoderReleaser { @@ -52,21 +52,15 @@ bool ReadTP(unsigned num, unsigned numBits, int spec); bool ReadC(); - HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress); + HRESULT CodeReal(UInt32 outSize, ICompressProgressInfo *progress); public: - MY_UNKNOWN_IMP - - UInt32 DictSize; - bool FinishMode; - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - void SetDictSize(unsigned dictSize) { DictSize = dictSize; } - - CCoder(): DictSize(1 << 16), FinishMode(false) {} - + CCoder(): DictSize(1 << 16) + // , FinishMode(true) + {} + void SetDictSize(UInt32 dictSize) { DictSize = dictSize; } UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress); }; }}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.cpp 2018-02-17 15:53:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.cpp 2023-03-28 11:00:00.000000000 +0000 @@ -21,7 +21,7 @@ , _finishMode(false) , _inBufSize(1 << 20) , _outStep(1 << 20) - #ifndef _7ZIP_ST + #ifndef Z7_ST , _tryMt(1) , _numThreads(1) , _memUsage((UInt64)(sizeof(size_t)) << 28) @@ -34,10 +34,10 @@ Lzma2DecMt_Destroy(_dec); } -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) { _outStep = size; return S_OK; } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) { if (size != 1) return E_NOTIMPL; @@ -48,7 +48,7 @@ } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { _finishMode = (finishMode != 0); return S_OK; @@ -56,7 +56,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize) { @@ -81,8 +81,8 @@ #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { _inProcessed = 0; @@ -102,24 +102,24 @@ props.inBufSize_ST = _inBufSize; props.outStep_ST = _outStep; - #ifndef _7ZIP_ST + #ifndef Z7_ST { props.numThreads = 1; UInt32 numThreads = _numThreads; if (_tryMt && numThreads >= 1) { - UInt64 useLimit = _memUsage; - UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop); - UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize); - size_t expectedBlockSize = (size_t)expectedBlockSize64; - size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16; + const UInt64 useLimit = _memUsage; + const UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop); + const UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize); + const size_t expectedBlockSize = (size_t)expectedBlockSize64; + const size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16; if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize) { props.outBlockMax = expectedBlockSize; props.inBlockMax = inBlockMax; const size_t kOverheadSize = props.inBufSize_MT + (1 << 16); - UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize); + const UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize); if (numThreads > okThreads) numThreads = (UInt32)okThreads; if (numThreads == 0) @@ -143,7 +143,7 @@ UInt64 inProcessed = 0; int isMT = False; - #ifndef _7ZIP_ST + #ifndef Z7_ST isMT = _tryMt; #endif @@ -162,7 +162,7 @@ */ - #ifndef _7ZIP_ST + #ifndef Z7_ST /* we reset _tryMt, only if p->props.numThreads was changed */ if (props.numThreads > 1) _tryMt = isMT; @@ -186,22 +186,22 @@ } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inProcessed; return S_OK; } -#ifndef _7ZIP_ST +#ifndef Z7_ST -STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) +Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads)) { _numThreads = numThreads; return S_OK; } -STDMETHODIMP CDecoder::SetMemLimit(UInt64 memUsage) +Z7_COM7F_IMF(CDecoder::SetMemLimit(UInt64 memUsage)) { _memUsage = memUsage; return S_OK; @@ -210,9 +210,9 @@ #endif -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { CLzma2DecMtProps props; Lzma2DecMtProps_Init(&props); @@ -230,7 +230,7 @@ _inWrap.Init(_inStream); - SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt); + const SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt); if (res != SZ_OK) return SResToHRESULT(res); @@ -238,11 +238,13 @@ } -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -250,7 +252,7 @@ size_t size2 = size; UInt64 inProcessed = 0; - SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed); + const SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed); _inProcessed += inProcessed; if (processedSize) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.h 2018-02-08 16:33:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Decoder.h 2023-02-01 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Lzma2Decoder.h -#ifndef __LZMA2_DECODER_H -#define __LZMA2_DECODER_H +#ifndef ZIP7_INC_LZMA2_DECODER_H +#define ZIP7_INC_LZMA2_DECODER_H #include "../../../C/Lzma2DecMt.h" @@ -10,26 +10,55 @@ namespace NCompress { namespace NLzma2 { -class CDecoder: +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, public ICompressSetBufSize, - - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif - - #ifndef _7ZIP_ST + #endif + #ifndef Z7_ST public ICompressSetCoderMt, public ICompressSetMemLimit, - #endif - + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + CLzma2DecMtHandle _dec; UInt64 _inProcessed; Byte _prop; @@ -37,58 +66,20 @@ UInt32 _inBufSize; UInt32 _outStep; -public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit) - #endif - - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - #ifndef _7ZIP_ST -private: + #ifndef Z7_ST int _tryMt; UInt32 _numThreads; UInt64 _memUsage; -public: - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - STDMETHOD(SetMemLimit)(UInt64 memUsage); - #endif + #endif - #ifndef NO_READ_FROM_CODER -private: + #ifndef Z7_NO_READ_FROM_CODER CMyComPtr _inStream; CSeqInStreamWrap _inWrap; -public: - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif + #endif +public: CDecoder(); - virtual ~CDecoder(); + ~CDecoder(); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.cpp 2021-01-22 17:28:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.cpp 2025-06-28 12:00:00.000000000 +0000 @@ -52,36 +52,44 @@ case NCoderPropID::kNumThreads: if (prop.vt != VT_UI4) return E_INVALIDARG; - lzma2Props.numTotalThreads = (int)(prop.ulVal); + lzma2Props.numTotalThreads = (int)prop.ulVal; + break; + case NCoderPropID::kNumThreadGroups: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + // 16-bit value supported by Windows + if (prop.ulVal >= (1u << 16)) + return E_INVALIDARG; + lzma2Props.numThreadGroups = (unsigned)prop.ulVal; break; default: - RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); + RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)) } return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { CLzma2EncProps lzma2Props; Lzma2EncProps_Init(&lzma2Props); for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); + RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)) } return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); } -STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID == NCoderPropID::kExpectedDataSize) if (prop.vt == VT_UI8) Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart); @@ -90,9 +98,9 @@ } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { - Byte prop = Lzma2Enc_WriteProperties(_encoder); + const Byte prop = Lzma2Enc_WriteProperties(_encoder); return WriteStream(outStream, &prop, 1); } @@ -100,8 +108,8 @@ #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { CSeqInStreamWrap inWrap; CSeqOutStreamWrap outWrap; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.h 2017-06-08 09:29:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Encoder.h 2023-03-28 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Lzma2Encoder.h -#ifndef __LZMA2_ENCODER_H -#define __LZMA2_ENCODER_H +#ifndef ZIP7_INC_LZMA2_ENCODER_H +#define ZIP7_INC_LZMA2_ENCODER_H #include "../../../C/Lzma2Enc.h" @@ -12,29 +12,17 @@ namespace NCompress { namespace NLzma2 { -class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public ICompressSetCoderPropertiesOpt, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_4( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties + , ICompressSetCoderPropertiesOpt +) CLzma2EncHandle _encoder; public: - MY_UNKNOWN_IMP4( - ICompressCoder, - ICompressSetCoderProperties, - ICompressWriteCoderProperties, - ICompressSetCoderPropertiesOpt) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - CEncoder(); - virtual ~CEncoder(); + ~CEncoder(); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Register.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Register.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzma2Register.cpp 2016-04-25 10:06:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzma2Register.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -6,7 +6,7 @@ #include "Lzma2Decoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "Lzma2Encoder.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaDecoder.cpp 2020-03-19 12:16:21.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -17,6 +17,7 @@ case SZ_ERROR_PARAM: return E_INVALIDARG; case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; case SZ_ERROR_DATA: return S_FALSE; + default: break; } return E_FAIL; } @@ -25,14 +26,14 @@ namespace NLzma { CDecoder::CDecoder(): - _inBuf(NULL), - _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED), FinishStream(false), _propsWereSet(false), _outSizeDefined(false), _outStep(1 << 20), _inBufSize(0), - _inBufSizeNew(1 << 20) + _inBufSizeNew(1 << 20), + _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED), + _inBuf(NULL) { _inProcessed = 0; _inPos = _inLim = 0; @@ -42,7 +43,7 @@ _alloc.numAlignBits = 7; _alloc.offset = 0; */ - LzmaDec_Construct(&_state); + LzmaDec_CONSTRUCT(&_state) } CDecoder::~CDecoder() @@ -51,8 +52,10 @@ MyFree(_inBuf); } -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) + { _inBufSizeNew = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) + { _outStep = size; return S_OK; } HRESULT CDecoder::CreateInputBuffer() { @@ -69,7 +72,7 @@ } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) { RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt _propsWereSet = true; @@ -90,7 +93,7 @@ } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { _inProcessed = 0; _inPos = _inLim = 0; @@ -99,14 +102,14 @@ } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { FinishStream = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inProcessed; return S_OK; @@ -154,7 +157,7 @@ SizeT inProcessed = _inLim - _inPos; ELzmaStatus status; - SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status); + const SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status); _lzmaStatus = status; _inPos += (UInt32)inProcessed; @@ -163,22 +166,22 @@ _outProcessed += outProcessed; // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0) - bool outFinished = (_outSizeDefined && _outProcessed >= _outSize); + const bool outFinished = (_outSizeDefined && _outProcessed >= _outSize); - bool needStop = (res != 0 + const bool needStop = (res != 0 || (inProcessed == 0 && outProcessed == 0) || status == LZMA_STATUS_FINISHED_WITH_MARK || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)); if (needStop || outProcessed >= size) { - HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos); + const HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos); if (_state.dicPos == _state.dicBufSize) _state.dicPos = 0; wrPos = _state.dicPos; - RINOK(res2); + RINOK(res2) if (needStop) { @@ -207,14 +210,14 @@ if (progress) { const UInt64 inSize = _inProcessed - startInProgress; - RINOK(progress->SetRatioInfo(&inSize, &_outProcessed)); + RINOK(progress->SetRatioInfo(&inSize, &_outProcessed)) } } } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { if (!_inBuf) return E_INVALIDARG; @@ -227,13 +230,14 @@ } -#ifndef NO_READ_FROM_CODER - -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } +#ifndef Z7_NO_READ_FROM_CODER +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -264,7 +268,7 @@ SizeT outProcessed = size; ELzmaStatus status; - SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, + const SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, _inBuf + _inPos, &inProcessed, finishMode, &status); _lzmaStatus = status; @@ -308,7 +312,7 @@ HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize) { - RINOK(CreateInputBuffer()); + RINOK(CreateInputBuffer()) if (processedSize) *processedSize = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaDecoder.h 2018-02-07 16:37:19.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaDecoder.h 2023-03-28 12:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LzmaDecoder.h -#ifndef __LZMA_DECODER_H -#define __LZMA_DECODER_H +#ifndef ZIP7_INC_LZMA_DECODER_H +#define ZIP7_INC_LZMA_DECODER_H // #include "../../../C/Alloc.h" #include "../../../C/LzmaDec.h" @@ -12,39 +12,71 @@ namespace NCompress { namespace NLzma { -class CDecoder: +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, public ICompressSetBufSize, - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif + #endif public CMyUnknownImp { - Byte *_inBuf; - UInt32 _inPos; - UInt32 _inLim; - - ELzmaStatus _lzmaStatus; + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + Z7_IFACE_COM7_IMP(ICompressCoder) public: - bool FinishStream; // set it before decoding, if you need to decode full LZMA stream + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +private: + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + // Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + + #ifndef Z7_NO_READ_FROM_CODER +public: + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif +public: + bool FinishStream; // set it before decoding, if you need to decode full LZMA stream private: bool _propsWereSet; bool _outSizeDefined; - UInt64 _outSize; - UInt64 _inProcessed; - UInt64 _outProcessed; UInt32 _outStep; UInt32 _inBufSize; UInt32 _inBufSizeNew; + ELzmaStatus _lzmaStatus; + UInt32 _inPos; + UInt32 _inLim; + Byte *_inBuf; + + UInt64 _outSize; + UInt64 _inProcessed; + UInt64 _outProcessed; + // CAlignOffsetAlloc _alloc; CLzmaDec _state; @@ -53,53 +85,21 @@ HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); void SetOutStreamSizeResume(const UInt64 *outSize); -public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - #ifndef NO_READ_FROM_CODER - + #ifndef Z7_NO_READ_FROM_CODER private: CMyComPtr _inStream; public: - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize); - - #endif - - UInt64 GetInputProcessedSize() const { return _inProcessed; } + #endif +public: CDecoder(); - virtual ~CDecoder(); + ~CDecoder(); + UInt64 GetInputProcessedSize() const { return _inProcessed; } UInt64 GetOutputProcessedSize() const { return _outProcessed; } - bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; } - bool CheckFinishStatus(bool withEndMark) const { return _lzmaStatus == (withEndMark ? diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaEncoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaEncoder.cpp 2022-02-09 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.cpp 2024-12-19 08:00:00.000000000 +0000 @@ -48,12 +48,12 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) { - wchar_t c = GetLowCharFast(*s++); + const wchar_t c = GetLowCharFast(*s++); if (c == 'h') { if (GetLowCharFast(*s++) != 'c') return 0; - int num = (int)(*s++ - L'0'); + const int num = (int)(*s++ - L'0'); if (num < 4 || num > 5) return 0; if (*s != 0) @@ -68,7 +68,7 @@ { if (GetLowCharFast(*s++) != 't') return 0; - int num = (int)(*s++ - L'0'); + const int num = (int)(*s++ - L'0'); if (num < 2 || num > 5) return 0; if (*s != 0) @@ -101,6 +101,33 @@ return S_OK; } + if (propID == NCoderPropID::kAffinityInGroup) + { + if (prop.vt == VT_UI8) + ep.affinityInGroup = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kThreadGroup) + { + if (prop.vt == VT_UI4) + ep.affinityGroup = (Int32)(UInt32)prop.ulVal; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kHashBits) + { + if (prop.vt == VT_UI4) + ep.numHashOutBits = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; + } + if (propID > NCoderPropID::kReduceSize) return S_OK; @@ -133,7 +160,7 @@ if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = prop.ulVal; + const UInt32 v = prop.ulVal; switch (propID) { case NCoderPropID::kDefaultProp: @@ -155,8 +182,8 @@ return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { CLzmaEncProps props; LzmaEncProps_Init(&props); @@ -164,7 +191,7 @@ for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; switch (propID) { case NCoderPropID::kEndMarker: @@ -173,20 +200,20 @@ props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break; default: - RINOK(SetLzmaProp(propID, prop, props)); + RINOK(SetLzmaProp(propID, prop, props)) } } return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props)); } -STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID == NCoderPropID::kExpectedDataSize) if (prop.vt == VT_UI8) LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); @@ -195,11 +222,11 @@ } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { Byte props[LZMA_PROPS_SIZE]; - size_t size = LZMA_PROPS_SIZE; - RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)); + SizeT size = LZMA_PROPS_SIZE; + RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)) return WriteStream(outStream, props, size); } @@ -293,8 +320,8 @@ -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { CSeqInStreamWrap inWrap; CSeqOutStreamWrap outWrap; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaEncoder.h 2017-06-07 18:36:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaEncoder.h 2023-03-28 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LzmaEncoder.h -#ifndef __LZMA_ENCODER_H -#define __LZMA_ENCODER_H +#ifndef ZIP7_INC_LZMA_ENCODER_H +#define ZIP7_INC_LZMA_ENCODER_H #include "../../../C/LzmaEnc.h" @@ -12,30 +12,29 @@ namespace NCompress { namespace NLzma { -class CEncoder: +class CEncoder Z7_final: public ICompressCoder, public ICompressSetCoderProperties, public ICompressWriteCoderProperties, public ICompressSetCoderPropertiesOpt, public CMyUnknownImp { - CLzmaEncHandle _encoder; - UInt64 _inputProcessed; -public: - MY_UNKNOWN_IMP4( + Z7_COM_UNKNOWN_IMP_4( ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties, ICompressSetCoderPropertiesOpt) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + Z7_IFACE_COM7_IMP(ICompressCoder) +public: + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + + CLzmaEncHandle _encoder; + UInt64 _inputProcessed; CEncoder(); - virtual ~CEncoder(); + ~CEncoder(); UInt64 GetInputProcessedSize() const { return _inputProcessed; } bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmaRegister.cpp 2016-04-25 10:06:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmaRegister.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -6,7 +6,7 @@ #include "LzmaDecoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "LzmaEncoder.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmsDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmsDecoder.cpp 2021-04-01 11:00:17.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.cpp 2024-06-17 12:00:00.000000000 +0000 @@ -10,6 +10,61 @@ namespace NCompress { namespace NLzms { +class CBitDecoder +{ +public: + const Byte *_buf; + unsigned _bitPos; + + void Init(const Byte *buf, size_t size) throw() + { + _buf = buf + size; + _bitPos = 0; + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) const + { + UInt32 v = + ((UInt32)_buf[-1] << 16) | + ((UInt32)_buf[-2] << 8) | + (UInt32)_buf[-3]; + v >>= 24 - numBits - _bitPos; + return v & ((1u << numBits) - 1); + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() + { + return GetUi32(_buf - 4) << _bitPos; + } + + void MovePos(unsigned numBits) + { + _bitPos += numBits; + _buf -= (_bitPos >> 3); + _bitPos &= 7; + } + + UInt32 ReadBits32(unsigned numBits) + { + UInt32 mask = (((UInt32)1 << numBits) - 1); + numBits += _bitPos; + const Byte *buf = _buf; + UInt32 v = GetUi32(buf - 4); + if (numBits > 32) + { + v <<= (numBits - 32); + v |= (UInt32)buf[-5] >> (40 - numBits); + } + else + v >>= (32 - numBits); + _buf = buf - (numBits >> 3); + _bitPos = numBits & 7; + return v & mask; + } +}; + static UInt32 g_PosBases[k_NumPosSyms /* + 1 */]; static Byte g_PosDirectBits[k_NumPosSyms]; @@ -77,7 +132,7 @@ unsigned right = k_NumPosSyms; for (;;) { - unsigned m = (left + right) / 2; + const unsigned m = (left + right) / 2; if (left == m) return m + 1; if (size >= g_PosBases[m]) @@ -91,7 +146,7 @@ static const Int32 k_x86_WindowSize = 65535; static const Int32 k_x86_TransOffset = 1023; -static const size_t k_x86_HistorySize = (1 << 16); +static const size_t k_x86_HistorySize = 1 << 16; static void x86_Filter(Byte *data, UInt32 size, Int32 *history) { @@ -139,31 +194,19 @@ Int32 maxTransOffset = k_x86_TransOffset; - Byte b = p[0]; + const Byte b = p[0]; - if (b == 0x48) + if ((b & 0x80) == 0) // REX (0x48 or 0x4c) { - if (p[1] == 0x8B) + const unsigned b2 = p[2] - 0x5; // [RIP + disp32] + if (b2 & 0x7) + continue; + if (p[1] != 0x8d) // LEA { - if ((p[2] & 0xF7) != 0x5) + if (p[1] != 0x8b || b != 0x48 || (b2 & 0xf7)) continue; // MOV RAX / RCX, [RIP + disp32] } - else if (p[1] == 0x8D) // LEA - { - if ((p[2] & 0x7) != 0x5) - continue; - // LEA R**, [] - } - else - continue; - codeLen = 3; - } - else if (b == 0x4C) - { - if (p[1] != 0x8D || (p[2] & 0x7) != 0x5) - continue; - // LEA R*, [] codeLen = 3; } else if (b == 0xE8) @@ -202,8 +245,8 @@ UInt32 n = GetUi32(p2); if (i - last_x86_pos <= maxTransOffset) { - n -= i; - SetUi32(p2, n); + n = (UInt32)((Int32)n - i); + SetUi32(p2, n) } target = history + (((UInt32)i + n) & 0xFFFF); } @@ -318,8 +361,8 @@ { if (_rc.Decode(&mainState, k_NumMainProbs, mainProbs) == 0) { - UInt32 number; - HUFF_DEC(number, m_LitDecoder); + unsigned number; + HUFF_DEC(number, m_LitDecoder) LIMIT_CHECK _win[_pos++] = (Byte)number; prevType = 0; @@ -330,13 +373,13 @@ if (_rc.Decode(&lzRepStates[0], k_NumRepProbs, lzRepProbs[0]) == 0) { - UInt32 number; - HUFF_DEC(number, m_PosDecoder); + unsigned number; + HUFF_DEC(number, m_PosDecoder) LIMIT_CHECK - unsigned numDirectBits = g_PosDirectBits[number]; + const unsigned numDirectBits = g_PosDirectBits[number]; distance = g_PosBases[number]; - READ_BITS_CHECK(numDirectBits); + READ_BITS_CHECK(numDirectBits) distance += _bs.ReadBits32(numDirectBits); // LIMIT_CHECK _reps[3] = _reps[2]; @@ -393,14 +436,14 @@ } } - UInt32 lenSlot; - HUFF_DEC(lenSlot, m_LenDecoder); + unsigned lenSlot; + HUFF_DEC(lenSlot, m_LenDecoder) LIMIT_CHECK UInt32 len = g_LenBases[lenSlot]; { - unsigned numDirectBits = k_LenDirectBits[lenSlot]; - READ_BITS_CHECK(numDirectBits); + const unsigned numDirectBits = k_LenDirectBits[lenSlot]; + READ_BITS_CHECK(numDirectBits) len += _bs.ReadBits32(numDirectBits); } // LIMIT_CHECK @@ -424,21 +467,21 @@ { UInt64 distance; - UInt32 power; + unsigned power; UInt32 distance32; if (_rc.Decode(&deltaRepStates[0], k_NumRepProbs, deltaRepProbs[0]) == 0) { - HUFF_DEC(power, m_PowerDecoder); + HUFF_DEC(power, m_PowerDecoder) LIMIT_CHECK - UInt32 number; - HUFF_DEC(number, m_DeltaDecoder); + unsigned number; + HUFF_DEC(number, m_DeltaDecoder) LIMIT_CHECK - unsigned numDirectBits = g_PosDirectBits[number]; + const unsigned numDirectBits = g_PosDirectBits[number]; distance32 = g_PosBases[number]; - READ_BITS_CHECK(numDirectBits); + READ_BITS_CHECK(numDirectBits) distance32 += _bs.ReadBits32(numDirectBits); // LIMIT_CHECK @@ -500,16 +543,16 @@ power = (UInt32)(_deltaReps[0] >> 32); } - UInt32 dist = (distance32 << power); + const UInt32 dist = (distance32 << power); - UInt32 lenSlot; - HUFF_DEC(lenSlot, m_LenDecoder); + unsigned lenSlot; + HUFF_DEC(lenSlot, m_LenDecoder) LIMIT_CHECK UInt32 len = g_LenBases[lenSlot]; { - unsigned numDirectBits = k_LenDirectBits[lenSlot]; - READ_BITS_CHECK(numDirectBits); + const unsigned numDirectBits = k_LenDirectBits[lenSlot]; + READ_BITS_CHECK(numDirectBits) len += _bs.ReadBits32(numDirectBits); } // LIMIT_CHECK diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzmsDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzmsDecoder.h 2020-09-29 16:00:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzmsDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,77 +1,17 @@ // LzmsDecoder.h // The code is based on LZMS description from wimlib code -#ifndef __LZMS_DECODER_H -#define __LZMS_DECODER_H - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#define PRF(x) x -#else -// #define PRF(x) -#endif +#ifndef ZIP7_INC_LZMS_DECODER_H +#define ZIP7_INC_LZMS_DECODER_H #include "../../../C/CpuArch.h" #include "../../../C/HuffEnc.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - #include "HuffmanDecoder.h" namespace NCompress { namespace NLzms { -class CBitDecoder -{ -public: - const Byte *_buf; - unsigned _bitPos; - - void Init(const Byte *buf, size_t size) throw() - { - _buf = buf + size; - _bitPos = 0; - } - - UInt32 GetValue(unsigned numBits) const - { - UInt32 v = ((UInt32)_buf[-1] << 16) | ((UInt32)_buf[-2] << 8) | (UInt32)_buf[-3]; - v >>= (24 - numBits - _bitPos); - return v & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - _bitPos += numBits; - _buf -= (_bitPos >> 3); - _bitPos &= 7; - } - - UInt32 ReadBits32(unsigned numBits) - { - UInt32 mask = (((UInt32)1 << numBits) - 1); - numBits += _bitPos; - const Byte *buf = _buf; - UInt32 v = GetUi32(buf - 4); - if (numBits > 32) - { - v <<= (numBits - 32); - v |= (UInt32)buf[-5] >> (40 - numBits); - } - else - v >>= (32 - numBits); - _buf = buf - (numBits >> 3); - _bitPos = numBits & 7; - return v & mask; - } -}; - - const unsigned k_NumLitSyms = 256; const unsigned k_NumLenSyms = 54; const unsigned k_NumPosSyms = 799; @@ -106,18 +46,17 @@ // We need to check that our algorithm is OK, when optimal Huffman tree uses more than 15 levels !!! Huffman_Generate(Freqs, vals, levels, NumSyms, k_NumHuffmanBits); - /* for (UInt32 i = NumSyms; i < m_NumSyms; i++) levels[i] = 0; - */ - this->BuildFull(levels, NumSyms); + + this->Build(levels, /* NumSyms, */ NHuffman::k_BuildMode_Full); } void Rebuild() throw() { Generate(); RebuildRem = m_RebuildFreq; - UInt32 num = NumSyms; + const UInt32 num = NumSyms; for (UInt32 i = 0; i < num; i++) Freqs[i] = (Freqs[i] >> 1) + 1; } @@ -158,7 +97,7 @@ void Update(unsigned bit) throw() { - Prob += (Int32)(Hist >> (k_ProbLimit - 1)) - (Int32)bit; + Prob += (UInt32)((Int32)(Hist >> (k_ProbLimit - 1)) - (Int32)bit); Hist = (Hist << 1) | bit; } }; @@ -197,7 +136,7 @@ CProbEntry *entry = &probs[st]; st = (st << 1) & (numStates - 1); - UInt32 prob = entry->GetProb(); + const UInt32 prob = entry->GetProb(); if (range <= 0xFFFF) { @@ -208,7 +147,7 @@ cur += 2; } - UInt32 bound = (range >> k_NumProbBits) * prob; + const UInt32 bound = (range >> k_NumProbBits) * prob; if (code < bound) { @@ -232,7 +171,6 @@ class CDecoder { // CRangeDecoder _rc; - // CBitDecoder _bs; size_t _pos; UInt32 _reps[k_NumReps + 1]; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Lzx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzx.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/Lzx.h 2015-08-30 06:08:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Lzx.h 2023-09-17 08:00:00.000000000 +0000 @@ -1,7 +1,9 @@ // Lzx.h -#ifndef __COMPRESS_LZX_H -#define __COMPRESS_LZX_H +#ifndef ZIP7_INC_COMPRESS_LZX_H +#define ZIP7_INC_COMPRESS_LZX_H + +#include "../../Common/MyTypes.h" namespace NCompress { namespace NLzx { @@ -50,7 +52,9 @@ const UInt32 kDictSize_Max = (UInt32)1 << kNumDictBits_Max; const unsigned kNumLinearPosSlotBits = 17; -const unsigned kNumPowerPosSlots = 38; +// const unsigned kNumPowerPosSlots = 38; +// const unsigned kNumPowerPosSlots = (kNumLinearPosSlotBits + 1) * 2; // non-including two first linear slots. +const unsigned kNumPowerPosSlots = (kNumLinearPosSlotBits + 2) * 2; // including two first linear slots. }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzxDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzxDecoder.cpp 2021-01-25 18:43:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.cpp 2024-01-07 16:00:00.000000000 +0000 @@ -3,6 +3,7 @@ #include "StdAfx.h" #include +// #include // #define SHOW_DEBUG_INFO @@ -14,448 +15,1433 @@ #endif #include "../../../C/Alloc.h" +#include "../../../C/RotateDefs.h" +#include "../../../C/CpuArch.h" #include "LzxDecoder.h" + +#ifdef MY_CPU_X86_OR_AMD64 +#if defined(MY_CPU_AMD64) \ + || defined(__SSE2__) \ + || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || 0 && defined(_MSC_VER) && (_MSC_VER >= 1400) // set (1 &&) for debug + +#if defined(__clang__) && (__clang_major__ >= 2) \ + || defined(__GNUC__) && (__GNUC__ >= 4) \ + || defined(_MSC_VER) && (_MSC_VER >= 1400) +#define Z7_LZX_X86_FILTER_USE_SSE2 +#endif +#endif +#endif + + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2 +// #ifdef MY_CPU_X86_OR_AMD64 +#include // SSE2 +// #endif + #if defined(__clang__) || defined(__GNUC__) + typedef int ctz_type; + #define MY_CTZ(dest, mask) dest = __builtin_ctz((UInt32)(mask)) + #else // #if defined(_MSC_VER) + #if (_MSC_VER >= 1600) + // #include + #endif + typedef unsigned long ctz_type; + #define MY_CTZ(dest, mask) _BitScanForward(&dest, (mask)); + #endif // _MSC_VER +#endif + +// when window buffer is filled, we must wrap position to zero, +// and we want to wrap at same points where original-lzx must wrap. +// But the wrapping is possible in point where chunk is finished. +// Usually (chunk_size == 32KB), but (chunk_size != 32KB) also is allowed. +// So we don't use additional buffer space over required (winSize). +// And we can't use large overwrite after (len) in CopyLzMatch(). +// But we are allowed to write 3 bytes after (len), because +// (delta <= _winSize - 3). + +// #define k_Lz_OverwriteSize 0 // for debug : to disable overwrite +#define k_Lz_OverwriteSize 3 // = kNumReps +#if k_Lz_OverwriteSize > 0 +// (k_Lz_OutBufSize_Add >= k_Lz_OverwriteSize) is required +// we use value 4 to simplify memset() code. +#define k_Lz_OutBufSize_Add (k_Lz_OverwriteSize + 1) // == 4 +#else +#define k_Lz_OutBufSize_Add 0 +#endif + +// (len != 0) +// (0 < delta <= _winSize - 3) +Z7_FORCE_INLINE +void CopyLzMatch(Byte *dest, const Byte *src, UInt32 len, UInt32 delta) +{ + if (delta >= 4) + { +#if k_Lz_OverwriteSize >= 3 + // optimized code with overwrite to reduce the number of branches + #ifdef MY_CPU_LE_UNALIGN + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + #else + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; + #endif + len--; + src++; + dest++; + { +#else + // no overwrite in out buffer + dest[0] = src[0]; + { + const unsigned m = (unsigned)len & 1; + src += m; + dest += m; + } + if (len &= ~(unsigned)1) + { + dest[0] = src[0]; + dest[1] = src[1]; +#endif + // len == 0 is allowed here + { + const unsigned m = (unsigned)len & 3; + src += m; + dest += m; + } + if (len &= ~(unsigned)3) + { +#ifdef MY_CPU_LE_UNALIGN + #if 1 + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + { + const unsigned m = (unsigned)len & 7; + dest += m; + src += m; + } + if (len &= ~(unsigned)7) + do + { + *(UInt32 *)(void *)(dest ) = *(const UInt32 *)(const void *)(src); + *(UInt32 *)(void *)(dest + 4) = *(const UInt32 *)(const void *)(src + 4); + src += 8; + dest += 8; + } + while (len -= 8); + #else + // gcc-11 -O3 for x64 generates incorrect code here + do + { + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + src += 4; + dest += 4; + } + while (len -= 4); + #endif +#else + do + { + const Byte b0 = src[0]; + const Byte b1 = src[1]; + dest[0] = b0; + dest[1] = b1; + const Byte b2 = src[2]; + const Byte b3 = src[3]; + dest[2] = b2; + dest[3] = b3; + src += 4; + dest += 4; + } + while (len -= 4); +#endif + } + } + } + else // (delta < 4) + { + const unsigned b0 = *src; + *dest = (Byte)b0; + if (len >= 2) + { + if (delta < 2) + { + dest += (unsigned)len & 1; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += (unsigned)len & 2; + if (len &= ~(unsigned)3) + { +#ifdef MY_CPU_LE_UNALIGN + #ifdef MY_CPU_64BIT + const UInt64 a = (UInt64)b0 * 0x101010101010101; + *(UInt32 *)(void *)dest = (UInt32)a; + dest += (unsigned)len & 7; + if (len &= ~(unsigned)7) + { + // *(UInt64 *)(void *)dest = a; + // dest += 8; + // len -= 8; + // if (len) + { + // const ptrdiff_t delta = (ptrdiff_t)dest & 7; + // dest -= delta; + do + { + *(UInt64 *)(void *)dest = a; + dest += 8; + } + while (len -= 8); + // dest += delta - 8; + // *(UInt64 *)(void *)dest = a; + } + } + #else + const UInt32 a = (UInt32)b0 * 0x1010101; + do + { + *(UInt32 *)(void *)dest = a; + dest += 4; + } + while (len -= 4); + #endif +#else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest[2] = (Byte)b0; + dest[3] = (Byte)b0; + dest += 4; + } + while (len -= 4); +#endif + } + } + else if (delta == 2) + { + const unsigned m = (unsigned)len & 1; + len &= ~(unsigned)1; + src += m; + dest += m; + { + const Byte a0 = src[0]; + const Byte a1 = src[1]; + do + { + dest[0] = a0; + dest[1] = a1; + dest += 2; + } + while (len -= 2); + } + } + else /* if (delta == 3) */ + { + const unsigned b1 = src[1]; + dest[1] = (Byte)b1; + if (len -= 2) + { + const unsigned b2 = src[2]; + dest += 2; + do + { + dest[0] = (Byte)b2; if (--len == 0) break; + dest[1] = (Byte)b0; if (--len == 0) break; + dest[2] = (Byte)b1; + dest += 3; + } + while (--len); + } + } + } + } +} + +// #define Z7_LZX_SHOW_STAT +#ifdef Z7_LZX_SHOW_STAT +#include +#endif + namespace NCompress { namespace NLzx { -static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 translationSize) +// #define Z7_LZX_SHOW_STAT +#ifdef Z7_LZX_SHOW_STAT +static UInt32 g_stats_Num_x86[3]; +static UInt32 g_stats_NumTables; +static UInt32 g_stats_NumLits; +static UInt32 g_stats_NumAlign; +static UInt32 g_stats_main[kMainTableSize]; +static UInt32 g_stats_len[kNumLenSymbols]; +static UInt32 g_stats_main_levels[kNumHuffmanBits + 1]; +static UInt32 g_stats_len_levels[kNumHuffmanBits + 1]; +#define UPDATE_STAT(a) a +static void PrintVal(UInt32 v) { - const UInt32 kResidue = 10; + printf("\n : %9u", v); +} +static void PrintStat(const char *name, const UInt32 *a, size_t num) +{ + printf("\n\n==== %s:", name); + UInt32 sum = 0; + size_t i; + for (i = 0; i < num; i++) + sum += a[i]; + PrintVal(sum); + if (sum != 0) + { + for (i = 0; i < num; i++) + { + if (i % 8 == 0) + printf("\n"); + printf("\n%3x : %9u : %5.2f", (unsigned)i, (unsigned)a[i], (double)a[i] * 100 / sum); + } + } + printf("\n"); +} + +static struct CStat +{ + ~CStat() + { + PrintStat("x86_filter", g_stats_Num_x86, Z7_ARRAY_SIZE(g_stats_Num_x86)); + printf("\nTables:"); PrintVal(g_stats_NumTables); + printf("\nLits:"); PrintVal(g_stats_NumLits); + printf("\nAlign:"); PrintVal(g_stats_NumAlign); + PrintStat("Main", g_stats_main, Z7_ARRAY_SIZE(g_stats_main)); + PrintStat("Len", g_stats_len, Z7_ARRAY_SIZE(g_stats_len)); + PrintStat("Main Levels", g_stats_main_levels, Z7_ARRAY_SIZE(g_stats_main_levels)); + PrintStat("Len Levels", g_stats_len_levels, Z7_ARRAY_SIZE(g_stats_len_levels)); + } +} g_stat; +#else +#define UPDATE_STAT(a) +#endif + + + +/* +3 p015 : ivb- : or r32,r32 / add r32,r32 +4 p0156 : hsw+ +5 p0156b: adl+ +2 p0_5 : ivb- : shl r32,i8 +2 p0__6 : hsw+ +1 p5 : ivb- : jb +2 p0__6 : hsw+ +2 p0_5 : wsm- : SSE2 : pcmpeqb : _mm_cmpeq_epi8 +2 p_15 : snb-bdw +2 p01 : skl+ +1 p0 : SSE2 : pmovmskb : _mm_movemask_epi8 +*/ +/* + v24.00: the code was fixed for more compatibility with original-ms-cab-decoder. + for ((Int32)translationSize >= 0) : LZX specification shows the code with signed Int32. + for ((Int32)translationSize < 0) : no specification for that case, but we support that case. + We suppose our code now is compatible with original-ms-cab-decoder. + + Starting byte of data stream (real_pos == 0) is special corner case, + where we don't need any conversion (as in original-ms-cab-decoder). + Our optimization: we use unsigned (UInt32 pos) (pos = -1 - real_pos). + So (pos) is always negative: ((Int32)pos < 0). + It allows us to use simple comparison (v > pos) instead of more complex comparisons. +*/ +// (p) will point 5 bytes after 0xe8 byte: +// pos == -1 - (p - 5 - data_start) == 4 + data_start - p +// (FILTER_PROCESSED_SIZE_DELTA == 4) is optimized value for better speed in some compilers: +#define FILTER_PROCESSED_SIZE_DELTA 4 + +#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_OR_ARM64) + // optimized branch: + // size_t must be at least 32-bit for this branch. + #if 1 // use 1 for simpler code + // use integer (low 32 bits of pointer) instead of pointer + #define X86_FILTER_PREPARE processedSize4 = (UInt32)(size_t)(ptrdiff_t)data + \ + (UInt32)(4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = processedSize4 - (UInt32)(size_t)(ptrdiff_t)p; + #else + // note: (dataStart) pointer can point out of array ranges: + #define X86_FILTER_PREPARE const Byte *dataStart = data + \ + (4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = (UInt32)(size_t)(dataStart - p); + #endif +#else + // non-optimized branch for unusual platforms (16-bit size_t or unusual size_t): + #define X86_FILTER_PREPARE processedSize4 = \ + (UInt32)(4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = processedSize4 - (UInt32)(size_t)(p - data); +#endif + +#define X86_TRANSLATE_PRE(p) \ + UInt32 v = GetUi32((p) - 4); + +#define X86_TRANSLATE_POST(p) \ + { \ + X86_FILTER_CALC_pos(p) \ + if (v < translationSize) { \ + UPDATE_STAT(g_stats_Num_x86[0]++;) \ + v += pos + 1; \ + SetUi32((p) - 4, v) \ + } \ + else if (v > pos) { \ + UPDATE_STAT(g_stats_Num_x86[1]++;) \ + v += translationSize; \ + SetUi32((p) - 4, v) \ + } else { UPDATE_STAT(g_stats_Num_x86[2]++;) } \ + } + + +/* + if ( defined(Z7_LZX_X86_FILTER_USE_SSE2) + && defined(Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED)) + the function can read up to aligned_for_32_up_from(size) bytes in (data). +*/ +// processedSize < (1 << 30) +Z7_NO_INLINE +static void x86_Filter4(Byte *data, size_t size, UInt32 processedSize4, UInt32 translationSize) +{ + const size_t kResidue = 10; if (size <= kResidue) return; - size -= kResidue; - - Byte save = data[(size_t)size + 4]; - data[(size_t)size + 4] = 0xE8; - - for (UInt32 i = 0;;) + Byte * const lim = data + size - kResidue + 4; + const Byte save = lim[0]; + lim[0] = 0xe8; + X86_FILTER_PREPARE + Byte *p = data; + +#define FILTER_RETURN_IF_LIM(_p_) if (_p_ > lim) { lim[0] = save; return; } + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2 + +// sse2-aligned/sse2-unaligned provide same speed on real data. +// but the code is smaller for sse2-unaligned version. +// for debug : define it to get alternative version with aligned 128-bit reads: +// #define Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + +#define FILTER_MASK_INT UInt32 +#define FILTER_NUM_VECTORS_IN_CHUNK 2 +#define FILTER_CHUNK_BYTES_OFFSET (16 * FILTER_NUM_VECTORS_IN_CHUNK - 5) + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + // aligned version doesn't uses additional space if buf size is aligned for 32 + #define k_Filter_OutBufSize_Add 0 + #define k_Filter_OutBufSize_AlignMask (16 * FILTER_NUM_VECTORS_IN_CHUNK - 1) + #define FILTER_LOAD_128(p) _mm_load_si128 ((const __m128i *)(const void *)(p)) +#else + #define k_Filter_OutBufSize_Add (16 * FILTER_NUM_VECTORS_IN_CHUNK) + #define k_Filter_OutBufSize_AlignMask 0 + #define FILTER_LOAD_128(p) _mm_loadu_si128((const __m128i *)(const void *)(p)) +#endif + +#define GET_E8_MASK(dest, dest1, p) \ +{ \ + __m128i v0 = FILTER_LOAD_128(p); \ + __m128i v1 = FILTER_LOAD_128(p + 16); \ + p += 16 * FILTER_NUM_VECTORS_IN_CHUNK; \ + v0 = _mm_cmpeq_epi8(v0, k_e8_Vector); \ + v1 = _mm_cmpeq_epi8(v1, k_e8_Vector); \ + dest = (unsigned)_mm_movemask_epi8(v0); \ + dest1 = (unsigned)_mm_movemask_epi8(v1); \ +} + + const __m128i k_e8_Vector = _mm_set1_epi32((Int32)(UInt32)0xe8e8e8e8); + for (;;) { - Byte *p = data + i; + // for debug: define it for smaller code: + // #define Z7_LZX_X86_FILTER_CALC_IN_LOOP + // without Z7_LZX_X86_FILTER_CALC_IN_LOOP, we can get faster and simpler loop + FILTER_MASK_INT mask; + { + FILTER_MASK_INT mask1; + do + { + GET_E8_MASK(mask, mask1, p) + #ifndef Z7_LZX_X86_FILTER_CALC_IN_LOOP + mask += mask1; + #else + mask |= mask1 << 16; + #endif + } + while (!mask); + + #ifndef Z7_LZX_X86_FILTER_CALC_IN_LOOP + mask -= mask1; + mask |= mask1 << 16; + #endif + } + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED for (;;) { - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; + ctz_type index; + typedef + #ifdef MY_CPU_64BIT + UInt64 + #else + UInt32 + #endif + SUPER_MASK_INT; + SUPER_MASK_INT superMask; + { + MY_CTZ(index, mask); + Byte *p2 = p - FILTER_CHUNK_BYTES_OFFSET + (unsigned)index; + X86_TRANSLATE_PRE(p2) + superMask = ~(SUPER_MASK_INT)0x1f << index; + FILTER_RETURN_IF_LIM(p2) + X86_TRANSLATE_POST(p2) + mask &= (UInt32)superMask; + } + if (mask) + continue; + if (index <= FILTER_CHUNK_BYTES_OFFSET) + break; + { + FILTER_MASK_INT mask1; + GET_E8_MASK(mask, mask1, p) + mask &= + #ifdef MY_CPU_64BIT + (UInt32)(superMask >> 32); + #else + ((FILTER_MASK_INT)0 - 1) << ((int)index - FILTER_CHUNK_BYTES_OFFSET); + #endif + mask |= mask1 << 16; + } + if (!mask) + break; } - - i = (UInt32)(p - data); - - if (i > size) - break; +#else // ! Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED { - Int32 v = (Int32)GetUi32(p); - Int32 pos = (Int32)((Int32)1 - (Int32)(processedSize + i)); - i += 4; - if (v >= pos && v < (Int32)translationSize) + // we use simplest version without loop: + // for (;;) { - v += (v >= 0 ? pos : (Int32)translationSize); - SetUi32(p, (UInt32)v); + ctz_type index; + MY_CTZ(index, mask); + /* + printf("\np=%p, mask=%8x, index = %2d, p + index = %x\n", + (p - 16 * FILTER_NUM_VECTORS_IN_CHUNK), (unsigned)mask, + (unsigned)index, (unsigned)((unsigned)(ptrdiff_t)(p - 16 * FILTER_NUM_VECTORS_IN_CHUNK) + index)); + */ + p += (size_t)(unsigned)index - FILTER_CHUNK_BYTES_OFFSET; + FILTER_RETURN_IF_LIM(p) + // mask &= ~(FILTER_MASK_INT)0x1f << index; mask >>= index; + X86_TRANSLATE_PRE(p) + X86_TRANSLATE_POST(p) + // if (!mask) break; // p += 16 * FILTER_NUM_VECTORS_IN_CHUNK; } } +#endif // ! Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED } - data[(size_t)size + 4] = save; +#else // ! Z7_LZX_X86_FILTER_USE_SSE2 + +#define k_Filter_OutBufSize_Add 0 +#define k_Filter_OutBufSize_AlignMask 0 + + + for (;;) + { + for (;;) + { + if (p[0] == 0xe8) { p += 5; break; } + if (p[1] == 0xe8) { p += 6; break; } + if (p[2] == 0xe8) { p += 7; break; } + p += 4; + if (p[-1] == 0xe8) { p += 4; break; } + } + FILTER_RETURN_IF_LIM(p) + X86_TRANSLATE_PRE(p) + X86_TRANSLATE_POST(p) + } + +#endif // ! Z7_LZX_X86_FILTER_USE_SSE2 } -CDecoder::CDecoder(bool wimMode): +CDecoder::CDecoder() throw(): _win(NULL), + _isUncompressedBlock(false), _skipByte(false), - _unpackBlockSize(0), - KeepHistoryForNext(true), - NeedAlloc(true), _keepHistory(false), - _wimMode(wimMode), + _keepHistoryForNext(true), + _needAlloc(true), + _wimMode(false), _numDictBits(15), - _x86_buf(NULL), + _unpackBlockSize(0), _x86_translationSize(0), + _x86_buf(NULL), _unpackedData(NULL) { + { + // it's better to get empty virtual entries, if mispredicted value can be used: + memset(_reps, 0, kPosSlotOffset * sizeof(_reps[0])); + memset(_extra, 0, kPosSlotOffset); +#define SET_NUM_BITS(i) i // #define NUM_BITS_DELTA 31 + _extra[kPosSlotOffset + 0] = SET_NUM_BITS(0); + _extra[kPosSlotOffset + 1] = SET_NUM_BITS(0); + // reps[0] = 0 - (kNumReps - 1); + // reps[1] = 1 - (kNumReps - 1); + UInt32 a = 2 - (kNumReps - 1); + UInt32 delta = 1; + unsigned i; + for (i = 0; i < kNumLinearPosSlotBits; i++) + { + _extra[(size_t)i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _extra[(size_t)i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _reps [(size_t)i * 2 + 2 + kPosSlotOffset] = a; a += delta; + _reps [(size_t)i * 2 + 3 + kPosSlotOffset] = a; a += delta; + delta += delta; + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + { + _extra[(size_t)i + kPosSlotOffset] = SET_NUM_BITS(kNumLinearPosSlotBits); + _reps [(size_t)i + kPosSlotOffset] = a; + a += (UInt32)1 << kNumLinearPosSlotBits; + } + } } -CDecoder::~CDecoder() +CDecoder::~CDecoder() throw() { - if (NeedAlloc) - ::MidFree(_win); - ::MidFree(_x86_buf); + if (_needAlloc) + // BigFree + z7_AlignedFree + (_win); + z7_AlignedFree(_x86_buf); } -HRESULT CDecoder::Flush() +HRESULT CDecoder::Flush() throw() { + // UInt32 t = _x86_processedSize; for (int y = 0; y < 50; y++) { _x86_processedSize = t; // benchmark: (branch predicted) if (_x86_translationSize != 0) { Byte *destData = _win + _writePos; - UInt32 curSize = _pos - _writePos; - if (KeepHistoryForNext) + const UInt32 curSize = _pos - _writePos; + if (_keepHistoryForNext) { + const size_t kChunkSize = (size_t)1 << 15; + if (curSize > kChunkSize) + return E_NOTIMPL; if (!_x86_buf) { - // we must change it to support another chunk sizes - const size_t kChunkSize = (size_t)1 << 15; - if (curSize > kChunkSize) - return E_NOTIMPL; - _x86_buf = (Byte *)::MidAlloc(kChunkSize); + // (kChunkSize % 32 == 0) is required in some cases, because + // the filter can read data by 32-bytes chunks in some cases. + // if (chunk_size > (1 << 15)) is possible, then we must the code: + const size_t kAllocSize = kChunkSize + k_Filter_OutBufSize_Add; + _x86_buf = (Byte *)z7_AlignedAlloc(kAllocSize); if (!_x86_buf) return E_OUTOFMEMORY; + #if 0 != k_Filter_OutBufSize_Add || \ + 0 != k_Filter_OutBufSize_AlignMask + // x86_Filter4() can read after curSize. + // So we set all data to zero to prevent reading of uninitialized data: + memset(_x86_buf, 0, kAllocSize); // optional + #endif } + // for (int yy = 0; yy < 1; yy++) // for debug memcpy(_x86_buf, destData, curSize); _unpackedData = _x86_buf; destData = _x86_buf; } - x86_Filter(destData, (UInt32)curSize, _x86_processedSize, _x86_translationSize); + else + { + // x86_Filter4() can overread after (curSize), + // so we can do memset() after (curSize): + // k_Filter_OutBufSize_AlignMask also can be used + // if (!_overDict) memset(destData + curSize, 0, k_Filter_OutBufSize_Add); + } + x86_Filter4(destData, curSize, _x86_processedSize - FILTER_PROCESSED_SIZE_DELTA, _x86_translationSize); _x86_processedSize += (UInt32)curSize; if (_x86_processedSize >= ((UInt32)1 << 30)) _x86_translationSize = 0; } - + // } return S_OK; } -UInt32 CDecoder::ReadBits(unsigned numBits) { return _bitStream.ReadBitsSmall(numBits); } + +// (NUM_DELTA_BYTES == 2) reduces the code in main loop. +#if 1 + #define NUM_DELTA_BYTES 2 +#else + #define NUM_DELTA_BYTES 0 +#endif + +#define NUM_DELTA_BIT_OFFSET_BITS (NUM_DELTA_BYTES * 8) + +#if NUM_DELTA_BIT_OFFSET_BITS > 0 + #define DECODE_ERROR_CODE 0 + #define IS_OVERFLOW_bitOffset(bo) ((bo) >= 0) + // ( >= 0) comparison after bitOffset change gives simpler commands than ( > 0) comparison +#else + #define DECODE_ERROR_CODE 1 + #define IS_OVERFLOW_bitOffset(bo) ((bo) > 0) +#endif + +// (numBits != 0) +#define GET_VAL_BASE(numBits) (_value >> (32 - (numBits))) + +#define Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, check_op, error_op) \ + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huff, kNumHuffmanBits, kNumTableBits, \ + _value, check_op, error_op, move_pos_op, NORMALIZE, bs) + +#define Z7_LZX_HUFF_DECODE_CHECK_YES(sym, huff, kNumTableBits, move_pos_op) \ + Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, { return DECODE_ERROR_CODE; }) + +#define Z7_LZX_HUFF_DECODE_CHECK_NO( sym, huff, kNumTableBits, move_pos_op) \ + Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {}) + +#define NORMALIZE \ +{ \ + const Byte *ptr = _buf + (_bitOffset >> 4) * 2; \ + /* _value = (((UInt32)GetUi16(ptr) << 16) | GetUi16(ptr + 2)) << (_bitOffset & 15); */ \ + const UInt32 v = GetUi32(ptr); \ + _value = rotlFixed (v, ((int)_bitOffset & 15) + 16); \ +} + +#define MOVE_POS(bs, numBits) \ +{ \ + _bitOffset += numBits; \ +} + +#define MOVE_POS_STAT(bs, numBits) \ +{ \ + UPDATE_STAT(g_stats_len_levels[numBits]++;) \ + MOVE_POS(bs, numBits); \ +} + +#define MOVE_POS_CHECK(bs, numBits) \ +{ \ + if (IS_OVERFLOW_bitOffset(_bitOffset += numBits)) return DECODE_ERROR_CODE; \ +} + +#define MOVE_POS_CHECK_STAT(bs, numBits) \ +{ \ + UPDATE_STAT(g_stats_main_levels[numBits]++;) \ + MOVE_POS_CHECK(bs, numBits) \ +} + + +// (numBits == 0) is supported + +#ifdef Z7_HUFF_USE_64BIT_LIMIT + +#define MACRO_ReadBitsBig_pre(numBits) \ +{ \ + _bitOffset += (numBits); \ + _value >>= 32 - (numBits); \ +} + +#else + +#define MACRO_ReadBitsBig_pre(numBits) \ +{ \ + _bitOffset += (numBits); \ + _value = (UInt32)((UInt32)_value >> 1 >> (31 ^ (numBits))); \ +} + +#endif + + +#define MACRO_ReadBitsBig_add(dest) \ + { dest += (UInt32)_value; } + +#define MACRO_ReadBitsBig_add3(dest) \ + { dest += (UInt32)(_value) << 3; } + + +// (numBits != 0) +#define MACRO_ReadBits_NonZero(val, numBits) \ +{ \ + val = (UInt32)(_value >> (32 - (numBits))); \ + MOVE_POS(bs, numBits); \ + NORMALIZE \ +} + + +struct CBitDecoder +{ + ptrdiff_t _bitOffset; + const Byte *_buf; + + Z7_FORCE_INLINE + UInt32 GetVal() const + { + const Byte *ptr = _buf + (_bitOffset >> 4) * 2; + const UInt32 v = GetUi32(ptr); + return rotlFixed (v, ((int)_bitOffset & 15) + 16); + } + + Z7_FORCE_INLINE + bool IsOverRead() const + { + return _bitOffset > (int)(0 - NUM_DELTA_BIT_OFFSET_BITS); + } + + + Z7_FORCE_INLINE + bool WasBitStreamFinishedOK() const + { + // we check that all 0-15 unused bits are zeros: + if (_bitOffset == 0 - NUM_DELTA_BIT_OFFSET_BITS) + return true; + if ((_bitOffset + NUM_DELTA_BIT_OFFSET_BITS + 15) & ~(ptrdiff_t)15) + return false; + const Byte *ptr = _buf - NUM_DELTA_BYTES - 2; + if ((UInt16)(GetUi16(ptr) << (_bitOffset & 15))) + return false; + return true; + } + + // (numBits != 0) + Z7_FORCE_INLINE + UInt32 ReadBits_NonZero(unsigned numBits) throw() + { + const UInt32 val = GetVal() >> (32 - numBits); + _bitOffset += numBits; + return val; + } +}; + + +class CBitByteDecoder: public CBitDecoder +{ + size_t _size; +public: + + Z7_FORCE_INLINE + void Init_ByteMode(const Byte *data, size_t size) + { + _buf = data; + _size = size; + } + + Z7_FORCE_INLINE + void Init_BitMode(const Byte *data, size_t size) + { + _size = size & 1; + size &= ~(size_t)1; + _buf = data + size + NUM_DELTA_BYTES; + _bitOffset = 0 - (ptrdiff_t)(size * 8) - NUM_DELTA_BIT_OFFSET_BITS; + } + + Z7_FORCE_INLINE + void Switch_To_BitMode() + { + Init_BitMode(_buf, _size); + } + + Z7_FORCE_INLINE + bool Switch_To_ByteMode() + { + /* here we check that unused bits in high 16-bits word are zeros. + If high word is full (all 16-bits are unused), + we check that all 16-bits are zeros. + So we check and skip (1-16 bits) unused bits */ + if ((GetVal() >> (16 + (_bitOffset & 15))) != 0) + return false; + _bitOffset += 16; + _bitOffset &= ~(ptrdiff_t)15; + if (_bitOffset > 0 - NUM_DELTA_BIT_OFFSET_BITS) + return false; + const ptrdiff_t delta = _bitOffset >> 3; + _size = (size_t)((ptrdiff_t)(_size) - delta - NUM_DELTA_BYTES); + _buf += delta; + // _bitOffset = 0; // optional + return true; + } + + Z7_FORCE_INLINE + size_t GetRem() const { return _size; } + + Z7_FORCE_INLINE + UInt32 ReadUInt32() + { + const Byte *ptr = _buf; + const UInt32 v = GetUi32(ptr); + _buf += 4; + _size -= 4; + return v; + } + + Z7_FORCE_INLINE + void CopyTo(Byte *dest, size_t size) + { + memcpy(dest, _buf, size); + _buf += size; + _size -= size; + } + + Z7_FORCE_INLINE + bool IsOneDirectByteLeft() const + { + return GetRem() == 1; + } + + Z7_FORCE_INLINE + Byte DirectReadByte() + { + _size--; + return *_buf++; + } +}; + + +// numBits != 0 +// Z7_FORCE_INLINE +Z7_NO_INLINE +static +UInt32 ReadBits(CBitDecoder &_bitStream, unsigned numBits) +{ + return _bitStream.ReadBits_NonZero(numBits); +} #define RIF(x) { if (!(x)) return false; } -bool CDecoder::ReadTable(Byte *levels, unsigned numSymbols) + +/* +MSVC compiler adds extra move operation, + if we access array with 32-bit index + array[calc_index_32_bit(32-bit_var)] + where calc_index_32_bit operations are: ((unsigned)a>>cnt), &, ^, | + clang is also affected for ((unsigned)a>>cnt) in byte array. +*/ + +// it can overread input buffer for 7-17 bytes. +// (levels != levelsEnd) +Z7_NO_INLINE +static ptrdiff_t ReadTable(ptrdiff_t _bitOffset, const Byte *_buf, Byte *levels, const Byte *levelsEnd) { + const unsigned kNumTableBits_Level = 7; + NHuffman::CDecoder256 _levelDecoder; + NHuffman::CValueInt _value; + // optional check to reduce size of overread zone: + if (_bitOffset > (int)0 - (int)NUM_DELTA_BIT_OFFSET_BITS - (int)(kLevelTableSize * kNumLevelBits)) + return DECODE_ERROR_CODE; + NORMALIZE { - Byte levels2[kLevelTableSize]; - for (unsigned i = 0; i < kLevelTableSize; i++) - levels2[i] = (Byte)ReadBits(kNumLevelBits); - RIF(_levelDecoder.Build(levels2)); + Byte levels2[kLevelTableSize / 4 * 4]; + for (size_t i = 0; i < kLevelTableSize / 4 * 4; i += 4) + { + UInt32 val; + MACRO_ReadBits_NonZero(val, kNumLevelBits * 4) + levels2[i + 0] = (Byte)((val >> (3 * kNumLevelBits))); + levels2[i + 1] = (Byte)((val >> (2 * kNumLevelBits)) & ((1u << kNumLevelBits) - 1)); + levels2[i + 2] = (Byte)((Byte)val >> (1 * kNumLevelBits)); + levels2[i + 3] = (Byte)((val) & ((1u << kNumLevelBits) - 1)); + } + RIF(_levelDecoder.Build(levels2, NHuffman::k_BuildMode_Full)) } - unsigned i = 0; do { - UInt32 sym = _levelDecoder.Decode(&_bitStream); + unsigned sym; + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, &_levelDecoder, kNumTableBits_Level, MOVE_POS_CHECK) + // Z7_HUFF_DECODE_CHECK(sym, &_levelDecoder, kNumHuffmanBits, kNumTableBits_Level, &bitStream, return false) + // sym = _levelDecoder.Decode(&bitStream); + // if (!_levelDecoder.Decode_SymCheck_MovePosCheck(&bitStream, sym)) return false; + if (sym <= kNumHuffmanBits) { - int delta = (int)levels[i] - (int)sym; - delta += (delta < 0) ? (kNumHuffmanBits + 1) : 0; - levels[i++] = (Byte)delta; + int delta = (int)*levels - (int)sym; + delta += delta < 0 ? kNumHuffmanBits + 1 : 0; + *levels++ = (Byte)delta; continue; } unsigned num; - Byte symbol; + int symbol; if (sym < kLevelSym_Same) { - sym -= kLevelSym_Zero1; - num = kLevelSym_Zero1_Start + ((unsigned)sym << kLevelSym_Zero1_NumBits) + - (unsigned)ReadBits(kLevelSym_Zero1_NumBits + sym); + // sym -= kLevelSym_Zero1; + MACRO_ReadBits_NonZero(num, kLevelSym_Zero1_NumBits + (sym - kLevelSym_Zero1)) + num += (sym << kLevelSym_Zero1_NumBits) - (kLevelSym_Zero1 << kLevelSym_Zero1_NumBits) + kLevelSym_Zero1_Start; symbol = 0; } - else if (sym == kLevelSym_Same) + // else if (sym != kLevelSym_Same) return DECODE_ERROR_CODE; + else // (sym == kLevelSym_Same) { - num = kLevelSym_Same_Start + (unsigned)ReadBits(kLevelSym_Same_NumBits); - sym = _levelDecoder.Decode(&_bitStream); - if (sym > kNumHuffmanBits) - return false; - int delta = (int)levels[i] - (int)sym; - delta += (delta < 0) ? (kNumHuffmanBits + 1) : 0; - symbol = (Byte)delta; + MACRO_ReadBits_NonZero(num, kLevelSym_Same_NumBits) + num += kLevelSym_Same_Start; + // + (unsigned)bitStream.ReadBitsSmall(kLevelSym_Same_NumBits); + // Z7_HUFF_DECODE_CHECK(sym, &_levelDecoder, kNumHuffmanBits, kNumTableBits_Level, &bitStream, return DECODE_ERROR_CODE) + // if (!_levelDecoder.Decode2(&bitStream, sym)) return DECODE_ERROR_CODE; + // sym = _levelDecoder.Decode(&bitStream); + + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, &_levelDecoder, kNumTableBits_Level, MOVE_POS) + + if (sym > kNumHuffmanBits) return DECODE_ERROR_CODE; + symbol = *levels - (int)sym; + symbol += symbol < 0 ? kNumHuffmanBits + 1 : 0; } - else - return false; - unsigned limit = i + num; - if (limit > numSymbols) + if (num > (size_t)(levelsEnd - levels)) return false; - + const Byte *limit = levels + num; do - levels[i++] = symbol; - while (i < limit); + *levels++ = (Byte)symbol; + while (levels != limit); } - while (i < numSymbols); + while (levels != levelsEnd); - return true; + return _bitOffset; } -bool CDecoder::ReadTables(void) -{ - { - if (_skipByte) - { - if (_bitStream.DirectReadByte() != 0) - return false; - } +static const unsigned kPosSlotDelta = 256 / kNumLenSlots - kPosSlotOffset; - _bitStream.NormalizeBig(); - unsigned blockType = (unsigned)ReadBits(kBlockType_NumBits); - if (blockType > kBlockType_Uncompressed) +#define READ_TABLE(_bitStream, levels, levelsEnd) \ +{ \ + _bitStream._bitOffset = ReadTable(_bitStream._bitOffset, _bitStream._buf, levels, levelsEnd); \ + if (_bitStream.IsOverRead()) return false; \ +} + +// can over-read input buffer for less than 32 bytes +bool CDecoder::ReadTables(CBitByteDecoder &_bitStream) throw() +{ + UPDATE_STAT(g_stats_NumTables++;) + { + const unsigned blockType = (unsigned)ReadBits(_bitStream, kBlockType_NumBits); + // if (blockType > kBlockType_Uncompressed || blockType == 0) + if ((unsigned)(blockType - 1) > kBlockType_Uncompressed - 1) return false; - - _unpackBlockSize = (1 << 15); - if (!_wimMode || ReadBits(1) == 0) + _unpackBlockSize = 1u << 15; + if (!_wimMode || ReadBits(_bitStream, 1) == 0) { - _unpackBlockSize = ReadBits(16); + _unpackBlockSize = ReadBits(_bitStream, 16); // wimlib supports chunks larger than 32KB (unsupported my MS wim). if (!_wimMode || _numDictBits >= 16) { _unpackBlockSize <<= 8; - _unpackBlockSize |= ReadBits(8); + _unpackBlockSize |= ReadBits(_bitStream, 8); } } PRF(printf("\nBlockSize = %6d %s ", _unpackBlockSize, (_pos & 1) ? "@@@" : " ")); _isUncompressedBlock = (blockType == kBlockType_Uncompressed); - _skipByte = false; if (_isUncompressedBlock) { _skipByte = ((_unpackBlockSize & 1) != 0); - - PRF(printf(" UncompressedBlock ")); - if (_unpackBlockSize & 1) - { - PRF(printf(" ######### ")); - } - - if (!_bitStream.PrepareUncompressed()) + // printf("\n UncompressedBlock %d", _unpackBlockSize); + PRF(printf(" UncompressedBlock ");) + // if (_unpackBlockSize & 1) { PRF(printf(" ######### ")); } + if (!_bitStream.Switch_To_ByteMode()) return false; if (_bitStream.GetRem() < kNumReps * 4) return false; - for (unsigned i = 0; i < kNumReps; i++) { - UInt32 rep = _bitStream.ReadUInt32(); - if (rep > _winSize) + const UInt32 rep = _bitStream.ReadUInt32(); + // here we allow only such values for (rep) that can be set also by LZ code: + if (rep == 0 || rep > _winSize - kNumReps) return false; - _reps[i] = rep; + _reps[(size_t)i + kPosSlotOffset] = rep; } - + // printf("\n"); return true; } - - _numAlignBits = 64; - + + // _numAlignBits = 64; + // const UInt32 k_numAlignBits_PosSlots_MAX = 64 + kPosSlotDelta; + // _numAlignBits_PosSlots = k_numAlignBits_PosSlots_MAX; + const UInt32 k_numAlignBits_Dist_MAX = (UInt32)(Int32)-1; + _numAlignBits_Dist = k_numAlignBits_Dist_MAX; if (blockType == kBlockType_Aligned) { Byte levels[kAlignTableSize]; - _numAlignBits = kNumAlignBits; + // unsigned not0 = 0; + unsigned not3 = 0; for (unsigned i = 0; i < kAlignTableSize; i++) - levels[i] = (Byte)ReadBits(kNumAlignLevelBits); - RIF(_alignDecoder.Build(levels)); + { + const unsigned val = ReadBits(_bitStream, kNumAlignLevelBits); + levels[i] = (Byte)val; + // not0 |= val; + not3 |= (val ^ 3); + } + // static unsigned number = 0, all = 0; all++; + // if (!not0) return false; // Build(true) will test this case + if (not3) + { + // _numAlignBits_PosSlots = (kNumAlignBits + 1) * 2 + kPosSlotDelta; + // _numAlignBits = kNumAlignBits; + _numAlignBits_Dist = (1u << (kNumAlignBits + 1)) - (kNumReps - 1); + RIF(_alignDecoder.Build(levels, true)) // full + } + // else { number++; if (number % 4 == 0) printf("\nnumber= %u : %u%%", number, number * 100 / all); } + } + // if (_numAlignBits_PosSlots == k_numAlignBits_PosSlots_MAX) + if (_numAlignBits_Dist == k_numAlignBits_Dist_MAX) + { + size_t i; + for (i = 3; i < kNumLinearPosSlotBits; i++) + { + _extra[i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _extra[i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + _extra[i + kPosSlotOffset] = (Byte)SET_NUM_BITS(kNumLinearPosSlotBits); + } + else + { + size_t i; + for (i = 3; i < kNumLinearPosSlotBits; i++) + { + _extra[i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i) - 3); + _extra[i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i) - 3); + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + _extra[i + kPosSlotOffset] = (Byte)(SET_NUM_BITS(kNumLinearPosSlotBits) - 3); } } - RIF(ReadTable(_mainLevels, 256)); - RIF(ReadTable(_mainLevels + 256, _numPosLenSlots)); - unsigned end = 256 + _numPosLenSlots; + READ_TABLE(_bitStream, _mainLevels, _mainLevels + 256) + READ_TABLE(_bitStream, _mainLevels + 256, _mainLevels + 256 + _numPosLenSlots) + const unsigned end = 256 + _numPosLenSlots; memset(_mainLevels + end, 0, kMainTableSize - end); - RIF(_mainDecoder.Build(_mainLevels)); - RIF(ReadTable(_lenLevels, kNumLenSymbols)); - return _lenDecoder.Build(_lenLevels); + // #define NUM_CYC 1 + // unsigned j; for (j = 0; j < NUM_CYC; j++) + RIF(_mainDecoder.Build(_mainLevels, NHuffman::k_BuildMode_Full)) + // if (kNumLenSymols_Big_Start) + memset(_lenLevels, 0, kNumLenSymols_Big_Start); + READ_TABLE(_bitStream, + _lenLevels + kNumLenSymols_Big_Start, + _lenLevels + kNumLenSymols_Big_Start + kNumLenSymbols) + // for (j = 0; j < NUM_CYC; j++) + RIF(_lenDecoder.Build(_lenLevels, NHuffman::k_BuildMode_Full_or_Empty)) + return true; } -HRESULT CDecoder::CodeSpec(UInt32 curSize) + +static ptrdiff_t CodeLz(CDecoder *dec, size_t next, ptrdiff_t _bitOffset, const Byte *_buf) throw() { - if (!_keepHistory || !_isUncompressedBlock) - _bitStream.NormalizeBig(); + { + Byte *const win = dec->_win; + const UInt32 winSize = dec->_winSize; + Byte *pos = win + dec->_pos; + const Byte * const posEnd = pos + next; + NHuffman::CValueInt _value; + + NORMALIZE + +#if 1 + #define HUFF_DEC_PREFIX dec-> +#else + const NHuffman::CDecoder _mainDecoder = dec->_mainDecoder; + const NHuffman::CDecoder256 _lenDecoder = dec->_lenDecoder; + const NHuffman::CDecoder7b _alignDecoder = dec->_alignDecoder; + #define HUFF_DEC_PREFIX +#endif + + do + { + unsigned sym; + // printf("\npos = %6u", pos - win); + { + const NHuffman::CDecoder + *mainDecoder = & HUFF_DEC_PREFIX _mainDecoder; + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, mainDecoder, kNumTableBits_Main, MOVE_POS_CHECK_STAT) + } + // if (!_mainDecoder.Decode_SymCheck_MovePosCheck(&bitStream, sym)) return DECODE_ERROR_CODE; + // sym = _mainDecoder.Decode(&bitStream); + // if (bitStream.WasExtraReadError_Fast()) return DECODE_ERROR_CODE; + + // printf(" sym = %3x", sym); + UPDATE_STAT(g_stats_main[sym]++;) + + if (sym < 256) + { + UPDATE_STAT(g_stats_NumLits++;) + *pos++ = (Byte)sym; + } + else + { + // sym -= 256; + // if (sym >= _numPosLenSlots) return DECODE_ERROR_CODE; + const unsigned posSlot = sym / kNumLenSlots; + unsigned len = sym % kNumLenSlots + kMatchMinLen; + if (len == kNumLenSlots - 1 + kMatchMinLen) + { + const NHuffman::CDecoder256 + *lenDecoder = & HUFF_DEC_PREFIX _lenDecoder; + Z7_LZX_HUFF_DECODE_CHECK_YES(len, lenDecoder, kNumTableBits_Len, MOVE_POS_STAT) + // if (!_lenDecoder.Decode2(&bitStream, len)) return DECODE_ERROR_CODE; + // len = _lenDecoder.Decode(&bitStream); + // if (len >= kNumLenSymbols) return DECODE_ERROR_CODE; + UPDATE_STAT(g_stats_len[len - kNumLenSymols_Big_Start]++;) + len += kNumLenSlots - 1 + kMatchMinLen - kNumLenSymols_Big_Start; + } + /* + if ((next -= len) < 0) + return DECODE_ERROR_CODE; + */ + UInt32 dist; + + dist = dec->_reps[(size_t)posSlot - kPosSlotDelta]; + if (posSlot < kNumReps + 256 / kNumLenSlots) + { + // if (posSlot != kNumReps + kPosSlotDelta) + // if (posSlot - (kNumReps + kPosSlotDelta + 1) < 2) + dec->_reps[(size_t)posSlot - kPosSlotDelta] = dec->_reps[kPosSlotOffset]; + /* + if (posSlot != kPosSlotDelta) + { + UInt32 temp = dist; + if (posSlot == kPosSlotDelta + 1) + { + dist = reps[1]; + reps[1] = temp; + } + else + { + dist = reps[2]; + reps[2] = temp; + } + // dist = reps[(size_t)(posSlot) - kPosSlotDelta]; + // reps[(size_t)(posSlot) - kPosSlotDelta] = reps[0]; + // reps[(size_t)(posSlot) - kPosSlotDelta] = temp; + } + */ + } + else // if (posSlot != kNumReps + kPosSlotDelta) + { + unsigned numDirectBits; +#if 0 + if (posSlot < kNumPowerPosSlots + kPosSlotDelta) + { + numDirectBits = (posSlot - 2 - kPosSlotDelta) >> 1; + dist = (UInt32)(2 | (posSlot & 1)) << numDirectBits; + } + else + { + numDirectBits = kNumLinearPosSlotBits; + dist = (UInt32)(posSlot - 0x22 - kPosSlotDelta) << kNumLinearPosSlotBits; + } + dist -= kNumReps - 1; +#else + numDirectBits = dec->_extra[(size_t)posSlot - kPosSlotDelta]; + // dist = reps[(size_t)(posSlot) - kPosSlotDelta]; +#endif + dec->_reps[kPosSlotOffset + 2] = + dec->_reps[kPosSlotOffset + 1]; + dec->_reps[kPosSlotOffset + 1] = + dec->_reps[kPosSlotOffset + 0]; + + // dist += val; dist += bitStream.ReadBitsBig(numDirectBits); + // if (posSlot >= _numAlignBits_PosSlots) + // if (numDirectBits >= _numAlignBits) + // if (val >= _numAlignBits_Dist) + // UInt32 val; MACRO_ReadBitsBig(val , numDirectBits) + // dist += val; + // dist += (UInt32)((UInt32)_value >> 1 >> (/* 31 ^ */ (numDirectBits))); + // MOVE_POS((numDirectBits ^ 31)) + MACRO_ReadBitsBig_pre(numDirectBits) + // dist += (UInt32)_value; + if (dist >= dec->_numAlignBits_Dist) + { + // if (numDirectBits != _numAlignBits) + { + // UInt32 val; + // dist -= (UInt32)_value; + MACRO_ReadBitsBig_add3(dist) + NORMALIZE + // dist += (val << kNumAlignBits); + // dist += bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits; + } + { + // const unsigned alignTemp = _alignDecoder.Decode(&bitStream); + const NHuffman::CDecoder7b *alignDecoder = & HUFF_DEC_PREFIX _alignDecoder; + unsigned alignTemp; + UPDATE_STAT(g_stats_NumAlign++;) + Z7_HUFF_DECODER_7B_DECODE(alignTemp, alignDecoder, GET_VAL_BASE, MOVE_POS, bs) + // NORMALIZE + // if (alignTemp >= kAlignTableSize) return DECODE_ERROR_CODE; + dist += alignTemp; + } + } + else + { + { + MACRO_ReadBitsBig_add(dist) + // dist += bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits; + } + } + NORMALIZE + /* + else + { + UInt32 val; + MACRO_ReadBitsBig(val, numDirectBits) + dist += val; + // dist += bitStream.ReadBitsBig(numDirectBits); + } + */ + } + dec->_reps[kPosSlotOffset + 0] = dist; + + Byte *dest = pos; + if (len > (size_t)(posEnd - pos)) + return DECODE_ERROR_CODE; + Int32 srcPos = (Int32)(pos - win); + pos += len; + srcPos -= (Int32)dist; + if (srcPos < 0) // fast version + { + if (!dec->_overDict) + return DECODE_ERROR_CODE; + srcPos &= winSize - 1; + UInt32 rem = winSize - (UInt32)srcPos; + if (len > rem) + { + len -= rem; + const Byte *src = win + (UInt32)srcPos; + do + *dest++ = *src++; + while (--rem); + srcPos = 0; + } + } + CopyLzMatch(dest, win + (UInt32)srcPos, len, dist); + } + } + while (pos != posEnd); + + return _bitOffset; + } +} + + + + +// inSize != 0 +// outSize != 0 ??? +HRESULT CDecoder::CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) throw() +{ + // ((inSize & 1) != 0) case is possible, if current call will be finished with Uncompressed Block. + CBitByteDecoder _bitStream; + if (_keepHistory && _isUncompressedBlock) + _bitStream.Init_ByteMode(inData, inSize); + else + _bitStream.Init_BitMode(inData, inSize); if (!_keepHistory) { + _isUncompressedBlock = false; _skipByte = false; _unpackBlockSize = 0; - - memset(_mainLevels, 0, kMainTableSize); - memset(_lenLevels, 0, kNumLenSymbols); - + memset(_mainLevels, 0, sizeof(_mainLevels)); + memset(_lenLevels, 0, sizeof(_lenLevels)); { _x86_translationSize = 12000000; if (!_wimMode) { _x86_translationSize = 0; - if (ReadBits(1) != 0) + if (ReadBits(_bitStream, 1) != 0) { - UInt32 v = ReadBits(16) << 16; - v |= ReadBits(16); + UInt32 v = ReadBits(_bitStream, 16) << 16; + v |= ReadBits(_bitStream, 16); _x86_translationSize = v; } } - _x86_processedSize = 0; } - - _reps[0] = 1; - _reps[1] = 1; - _reps[2] = 1; + _reps[0 + kPosSlotOffset] = 1; + _reps[1 + kPosSlotOffset] = 1; + _reps[2 + kPosSlotOffset] = 1; } - while (curSize > 0) + while (outSize) { + /* + // check it for bit mode only: if (_bitStream.WasExtraReadError_Fast()) return S_FALSE; - + */ if (_unpackBlockSize == 0) { - if (!ReadTables()) + if (_skipByte) + { + if (_bitStream.GetRem() < 1) + return S_FALSE; + if (_bitStream.DirectReadByte() != 0) + return S_FALSE; + } + if (_isUncompressedBlock) + _bitStream.Switch_To_BitMode(); + if (!ReadTables(_bitStream)) return S_FALSE; continue; } + // _unpackBlockSize != 0 UInt32 next = _unpackBlockSize; - if (next > curSize) - next = curSize; + if (next > outSize) + next = outSize; + // next != 0 + + // PRF(printf("\nnext = %d", (unsigned)next);) if (_isUncompressedBlock) { - size_t rem = _bitStream.GetRem(); - if (rem == 0) + if (_bitStream.GetRem() < next) return S_FALSE; - if (next > rem) - next = (UInt32)rem; _bitStream.CopyTo(_win + _pos, next); _pos += next; - curSize -= next; _unpackBlockSize -= next; - - /* we don't know where skipByte can be placed, if it's end of chunk: - 1) in current chunk - there are such cab archives, if chunk is last - 2) in next chunk - are there such archives ? */ - - if (_skipByte - && _unpackBlockSize == 0 - && curSize == 0 - && _bitStream.IsOneDirectByteLeft()) - { - _skipByte = false; - if (_bitStream.DirectReadByte() != 0) - return S_FALSE; - } - - continue; } - - curSize -= next; - _unpackBlockSize -= next; - - Byte *win = _win; - - while (next > 0) + else { - if (_bitStream.WasExtraReadError_Fast()) + _unpackBlockSize -= next; + _bitStream._bitOffset = CodeLz(this, next, _bitStream._bitOffset, _bitStream._buf); + if (_bitStream.IsOverRead()) return S_FALSE; + _pos += next; + } + outSize -= next; + } - UInt32 sym = _mainDecoder.Decode(&_bitStream); - - if (sym < 256) - { - win[_pos++] = (Byte)sym; - next--; - continue; - } - { - sym -= 256; - if (sym >= _numPosLenSlots) - return S_FALSE; - UInt32 posSlot = sym / kNumLenSlots; - UInt32 lenSlot = sym % kNumLenSlots; - UInt32 len = kMatchMinLen + lenSlot; - - if (lenSlot == kNumLenSlots - 1) - { - UInt32 lenTemp = _lenDecoder.Decode(&_bitStream); - if (lenTemp >= kNumLenSymbols) - return S_FALSE; - len = kMatchMinLen + kNumLenSlots - 1 + lenTemp; - } - - UInt32 dist; - - if (posSlot < kNumReps) - { - dist = _reps[posSlot]; - _reps[posSlot] = _reps[0]; - _reps[0] = dist; - } - else - { - unsigned numDirectBits; - - if (posSlot < kNumPowerPosSlots) - { - numDirectBits = (unsigned)(posSlot >> 1) - 1; - dist = ((2 | (posSlot & 1)) << numDirectBits); - } - else - { - numDirectBits = kNumLinearPosSlotBits; - dist = ((posSlot - 0x22) << kNumLinearPosSlotBits); - } - - if (numDirectBits >= _numAlignBits) - { - dist += (_bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits); - UInt32 alignTemp = _alignDecoder.Decode(&_bitStream); - if (alignTemp >= kAlignTableSize) - return S_FALSE; - dist += alignTemp; - } - else - dist += _bitStream.ReadBitsBig(numDirectBits); - - dist -= kNumReps - 1; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = dist; - } - - if (len > next) - return S_FALSE; - - if (dist > _pos && !_overDict) - return S_FALSE; - - Byte *dest = win + _pos; - const UInt32 mask = (_winSize - 1); - UInt32 srcPos = (_pos - dist) & mask; + // outSize == 0 - next -= len; - - if (len > _winSize - srcPos) - { - _pos += len; - do - { - *dest++ = win[srcPos++]; - srcPos &= mask; - } - while (--len); - } - else - { - ptrdiff_t src = (ptrdiff_t)srcPos - (ptrdiff_t)_pos; - _pos += len; - const Byte *lim = dest + len; - *(dest) = *(dest + src); - dest++; - do - *(dest) = *(dest + src); - while (++dest != lim); - } - } + if (_isUncompressedBlock) + { + /* we don't know where skipByte can be placed, if it's end of chunk: + 1) in current chunk - there are such cab archives, if chunk is last + 2) in next chunk - are there such archives ? */ + if (_unpackBlockSize == 0 + && _skipByte + // && outSize == 0 + && _bitStream.IsOneDirectByteLeft()) + { + _skipByte = false; + if (_bitStream.DirectReadByte() != 0) + return S_FALSE; } } - if (!_bitStream.WasFinishedOK()) + if (_bitStream.GetRem() != 0) return S_FALSE; - + if (!_isUncompressedBlock) + if (!_bitStream.WasBitStreamFinishedOK()) + return S_FALSE; return S_OK; } -HRESULT CDecoder::Code(const Byte *inData, size_t inSize, UInt32 outSize) +#if k_Filter_OutBufSize_Add > k_Lz_OutBufSize_Add + #define k_OutBufSize_Add k_Filter_OutBufSize_Add +#else + #define k_OutBufSize_Add k_Lz_OutBufSize_Add +#endif + +HRESULT CDecoder::Code_WithExceedReadWrite(const Byte *inData, size_t inSize, UInt32 outSize) throw() { if (!_keepHistory) { @@ -466,63 +1452,65 @@ { _pos = 0; _overDict = true; +#if k_OutBufSize_Add > 0 + // data after (_winSize) can be used, because we can use overwrite. + // memset(_win + _winSize, 0, k_OutBufSize_Add); +#endif } - _writePos = _pos; _unpackedData = _win + _pos; - + if (outSize > _winSize - _pos) return S_FALSE; + + PRF(printf("\ninSize = %d", (unsigned)inSize);) + PRF(if ((inSize & 1) != 0) printf("---------");) - PRF(printf("\ninSize = %d", inSize)); - if ((inSize & 1) != 0) - { - PRF(printf(" ---------")); - } - - if (inSize < 1) + if (inSize == 0) return S_FALSE; - - _bitStream.Init(inData, inSize); - - HRESULT res = CodeSpec(outSize); - HRESULT res2 = Flush(); + const HRESULT res = CodeSpec(inData, inSize, outSize); + const HRESULT res2 = Flush(); return (res == S_OK ? res2 : res); } -HRESULT CDecoder::SetParams2(unsigned numDictBits) +HRESULT CDecoder::SetParams2(unsigned numDictBits) throw() { - _numDictBits = numDictBits; - if (numDictBits < kNumDictBits_Min || numDictBits > kNumDictBits_Max) + if (numDictBits < kNumDictBits_Min || + numDictBits > kNumDictBits_Max) return E_INVALIDARG; - unsigned numPosSlots = (numDictBits < 20) ? - numDictBits * 2 : - 34 + ((unsigned)1 << (numDictBits - 17)); - _numPosLenSlots = numPosSlots * kNumLenSlots; + _numDictBits = (Byte)numDictBits; + const unsigned numPosSlots2 = (numDictBits < 20) ? + numDictBits : 17 + (1u << (numDictBits - 18)); + _numPosLenSlots = numPosSlots2 * (kNumLenSlots * 2); return S_OK; } -HRESULT CDecoder::SetParams_and_Alloc(unsigned numDictBits) +HRESULT CDecoder::Set_DictBits_and_Alloc(unsigned numDictBits) throw() { - RINOK(SetParams2(numDictBits)); - - UInt32 newWinSize = (UInt32)1 << numDictBits; - - if (NeedAlloc) + RINOK(SetParams2(numDictBits)) + const UInt32 newWinSize = (UInt32)1 << numDictBits; + if (_needAlloc) { if (!_win || newWinSize != _winSize) { - ::MidFree(_win); + // BigFree + z7_AlignedFree + (_win); _winSize = 0; - _win = (Byte *)::MidAlloc(newWinSize); + const size_t alloc_size = newWinSize + k_OutBufSize_Add; + _win = (Byte *) + // BigAlloc + z7_AlignedAlloc + (alloc_size); if (!_win) return E_OUTOFMEMORY; + // optional: + memset(_win, 0, alloc_size); } } - - _winSize = (UInt32)newWinSize; + _winSize = newWinSize; return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/LzxDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/LzxDecoder.h 2021-01-25 15:08:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/LzxDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,11 +1,7 @@ // LzxDecoder.h -#ifndef __LZX_DECODER_H -#define __LZX_DECODER_H - -#include "../../../C/CpuArch.h" - -#include "../../Common/MyCom.h" +#ifndef ZIP7_INC_LZX_DECODER_H +#define ZIP7_INC_LZX_DECODER_H #include "HuffmanDecoder.h" #include "Lzx.h" @@ -13,232 +9,96 @@ namespace NCompress { namespace NLzx { -class CBitDecoder -{ - unsigned _bitPos; - UInt32 _value; - const Byte *_buf; - const Byte *_bufLim; - UInt32 _extraSize; -public: - - void Init(const Byte *data, size_t size) - { - _buf = data; - _bufLim = data + size - 1; - _bitPos = 0; - _extraSize = 0; - } - - size_t GetRem() const { return (size_t)(_bufLim + 1 - _buf); } - bool WasExtraReadError_Fast() const { return _extraSize > 4; } - - bool WasFinishedOK() const - { - if (_buf != _bufLim + 1) - return false; - if ((_bitPos >> 4) * 2 != _extraSize) - return false; - unsigned numBits = _bitPos & 15; - return (((_value >> (_bitPos - numBits)) & (((UInt32)1 << numBits) - 1)) == 0); - } - - void NormalizeSmall() - { - if (_bitPos <= 16) - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - } - - void NormalizeBig() - { - if (_bitPos <= 16) - { - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - if (_bitPos <= 16) - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - } - } - - UInt32 GetValue(unsigned numBits) const - { - return (_value >> (_bitPos - numBits)) & (((UInt32)1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - _bitPos -= numBits; - NormalizeSmall(); - } - - UInt32 ReadBitsSmall(unsigned numBits) - { - _bitPos -= numBits; - UInt32 val = (_value >> _bitPos) & (((UInt32)1 << numBits) - 1); - NormalizeSmall(); - return val; - } +const unsigned kAdditionalOutputBufSize = 32 * 2; - UInt32 ReadBitsBig(unsigned numBits) - { - _bitPos -= numBits; - UInt32 val = (_value >> _bitPos) & (((UInt32)1 << numBits) - 1); - NormalizeBig(); - return val; - } +const unsigned kNumTableBits_Main = 11; +const unsigned kNumTableBits_Len = 8; - bool PrepareUncompressed() - { - if (_extraSize != 0) - return false; - unsigned numBits = _bitPos - 16; - if (((_value >> 16) & (((UInt32)1 << numBits) - 1)) != 0) - return false; - _buf -= 2; - _bitPos = 0; - return true; - } +// if (kNumLenSymols_Big <= 256) we can use NHuffman::CDecoder256 +// if (kNumLenSymols_Big > 256) we must use NHuffman::CDecoder +// const unsigned kNumLenSymols_Big_Start = kNumLenSlots - 1 + kMatchMinLen; // 8 - 1 + 2 +const unsigned kNumLenSymols_Big_Start = 0; +// const unsigned kNumLenSymols_Big_Start = 0; +const unsigned kNumLenSymols_Big = kNumLenSymols_Big_Start + kNumLenSymbols; + +#if 1 + // for smallest structure size: + const unsigned kPosSlotOffset = 0; +#else + // use virtual entries for mispredicted branches: + const unsigned kPosSlotOffset = 256 / kNumLenSlots; +#endif - UInt32 ReadUInt32() - { - UInt32 v = GetUi32(_buf); - _buf += 4; - return v; - } +class CBitByteDecoder; - void CopyTo(Byte *dest, size_t size) - { - memcpy(dest, _buf, size); - _buf += size; - } - - bool IsOneDirectByteLeft() const { return _buf == _bufLim && _extraSize == 0; } - - Byte DirectReadByte() - { - if (_buf > _bufLim) - { - _extraSize++; - return 0xFF; - } - return *_buf++; - } -}; - - -class CDecoder: - public IUnknown, - public CMyUnknownImp +class CDecoder { - CBitDecoder _bitStream; - Byte *_win; +public: UInt32 _pos; UInt32 _winSize; + Byte *_win; bool _overDict; bool _isUncompressedBlock; bool _skipByte; - unsigned _numAlignBits; + bool _keepHistory; + bool _keepHistoryForNext; + bool _needAlloc; + bool _wimMode; + Byte _numDictBits; - UInt32 _reps[kNumReps]; - UInt32 _numPosLenSlots; + // unsigned _numAlignBits_PosSlots; + // unsigned _numAlignBits; + UInt32 _numAlignBits_Dist; +private: + unsigned _numPosLenSlots; UInt32 _unpackBlockSize; -public: - bool KeepHistoryForNext; - bool NeedAlloc; -private: - bool _keepHistory; - bool _wimMode; - unsigned _numDictBits; UInt32 _writePos; - Byte *_x86_buf; UInt32 _x86_translationSize; UInt32 _x86_processedSize; + Byte *_x86_buf; Byte *_unpackedData; - - NHuffman::CDecoder _mainDecoder; - NHuffman::CDecoder _lenDecoder; - NHuffman::CDecoder7b _alignDecoder; - NHuffman::CDecoder _levelDecoder; +public: + Byte _extra[kPosSlotOffset + kNumPosSlots]; + UInt32 _reps[kPosSlotOffset + kNumPosSlots]; + NHuffman::CDecoder _mainDecoder; + NHuffman::CDecoder256 _lenDecoder; + NHuffman::CDecoder7b _alignDecoder; +private: Byte _mainLevels[kMainTableSize]; - Byte _lenLevels[kNumLenSymbols]; + Byte _lenLevels[kNumLenSymols_Big]; - HRESULT Flush(); + HRESULT Flush() throw(); + bool ReadTables(CBitByteDecoder &_bitStream) throw(); - UInt32 ReadBits(unsigned numBits); - bool ReadTable(Byte *levels, unsigned numSymbols); - bool ReadTables(); - - HRESULT CodeSpec(UInt32 size); - HRESULT SetParams2(unsigned numDictBits); + HRESULT CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) throw(); + HRESULT SetParams2(unsigned numDictBits) throw(); public: - CDecoder(bool wimMode = false); - ~CDecoder(); - - MY_UNKNOWN_IMP + CDecoder() throw(); + ~CDecoder() throw(); + + void Set_WimMode(bool wimMode) { _wimMode = wimMode; } + void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + void Set_KeepHistoryForNext(bool keepHistoryForNext) { _keepHistoryForNext = keepHistoryForNext; } - HRESULT SetExternalWindow(Byte *win, unsigned numDictBits) + HRESULT Set_ExternalWindow_DictBits(Byte *win, unsigned numDictBits) { - NeedAlloc = false; + _needAlloc = false; _win = win; _winSize = (UInt32)1 << numDictBits; return SetParams2(numDictBits); } + HRESULT Set_DictBits_and_Alloc(unsigned numDictBits) throw(); - void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } - - HRESULT SetParams_and_Alloc(unsigned numDictBits); - - HRESULT Code(const Byte *inData, size_t inSize, UInt32 outSize); + HRESULT Code_WithExceedReadWrite(const Byte *inData, size_t inSize, UInt32 outSize) throw(); - bool WasBlockFinished() const { return _unpackBlockSize == 0; } + bool WasBlockFinished() const { return _unpackBlockSize == 0; } const Byte *GetUnpackData() const { return _unpackedData; } - UInt32 GetUnpackSize() const { return _pos - _writePos; } + UInt32 GetUnpackSize() const { return _pos - _writePos; } }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/Mtf8.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Mtf8.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/Mtf8.h 2017-04-10 13:16:54.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/Mtf8.h 2024-12-17 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Mtf8.h -#ifndef __COMPRESS_MTF8_H -#define __COMPRESS_MTF8_H +#ifndef ZIP7_INC_COMPRESS_MTF8_H +#define ZIP7_INC_COMPRESS_MTF8_H #include "../../../C/CpuArch.h" @@ -13,9 +13,21 @@ unsigned FindAndMove(Byte v) throw() { +#if 1 + Byte b = Buf[0]; + if (v == b) + return 0; + Buf[0] = v; + for (unsigned pos = 0;;) + { + Byte a; + a = Buf[++pos]; Buf[pos] = b; if (v == a) return pos; + b = Buf[++pos]; Buf[pos] = a; if (v == b) return pos; + } +#else size_t pos; for (pos = 0; Buf[pos] != v; pos++); - unsigned resPos = (unsigned)pos; + const unsigned resPos = (unsigned)pos; for (; pos >= 8; pos -= 8) { Buf[pos] = Buf[pos - 1]; @@ -31,6 +43,7 @@ Buf[pos] = Buf[pos - 1]; Buf[0] = v; return resPos; +#endif } }; @@ -66,28 +79,28 @@ #ifdef MY_CPU_64BIT typedef UInt64 CMtfVar; - #define MTF_MOVS 3 + #define Z7_MTF_MOVS 3 #else typedef UInt32 CMtfVar; - #define MTF_MOVS 2 + #define Z7_MTF_MOVS 2 #endif -#define MTF_MASK ((1 << MTF_MOVS) - 1) +#define Z7_MTF_MASK ((1 << Z7_MTF_MOVS) - 1) struct CMtf8Decoder { - CMtfVar Buf[256 >> MTF_MOVS]; + CMtfVar Buf[256 >> Z7_MTF_MOVS]; void StartInit() { memset(Buf, 0, sizeof(Buf)); } - void Add(unsigned pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } + void Add(unsigned pos, Byte val) { Buf[pos >> Z7_MTF_MOVS] |= ((CMtfVar)val << ((pos & Z7_MTF_MASK) << 3)); } Byte GetHead() const { return (Byte)Buf[0]; } - MY_FORCE_INLINE + Z7_FORCE_INLINE Byte GetAndMove(unsigned pos) throw() { - UInt32 lim = ((UInt32)pos >> MTF_MOVS); - pos = (pos & MTF_MASK) << 3; + const UInt32 lim = ((UInt32)pos >> Z7_MTF_MOVS); + pos = (pos & Z7_MTF_MASK) << 3; CMtfVar prev = (Buf[lim] >> pos) & 0xFF; UInt32 i = 0; @@ -98,7 +111,7 @@ { CMtfVar next = Buf[0]; Buf[0] = (next << 8) | prev; - prev = (next >> (MTF_MASK << 3)); + prev = (next >> (Z7_MTF_MASK << 3)); i = 1; lim -= 1; } @@ -107,21 +120,21 @@ CMtfVar n0 = Buf[i]; CMtfVar n1 = Buf[i + 1]; Buf[i ] = (n0 << 8) | prev; - Buf[i + 1] = (n1 << 8) | (n0 >> (MTF_MASK << 3)); - prev = (n1 >> (MTF_MASK << 3)); + Buf[i + 1] = (n1 << 8) | (n0 >> (Z7_MTF_MASK << 3)); + prev = (n1 >> (Z7_MTF_MASK << 3)); } */ for (; i < lim; i++) { - CMtfVar n0 = Buf[i]; + const CMtfVar n0 = Buf[i]; Buf[i ] = (n0 << 8) | prev; - prev = (n0 >> (MTF_MASK << 3)); + prev = (n0 >> (Z7_MTF_MASK << 3)); } - CMtfVar next = Buf[i]; - CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); + const CMtfVar next = Buf[i]; + const CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); Buf[i] = (next & ~mask) | (((next << 8) | prev) & mask); return (Byte)Buf[0]; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdDecoder.cpp 2021-01-25 18:44:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,5 +1,4 @@ // PpmdDecoder.cpp -// 2020-07-03 : Igor Pavlov : Public domain #include "StdAfx.h" @@ -29,14 +28,13 @@ Ppmd7_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) { if (size < 5) return E_INVALIDARG; _order = props[0]; - UInt32 memSize = GetUi32(props + 1); - if ( - // _order < PPMD7_MIN_ORDER || + const UInt32 memSize = GetUi32(props + 1); + if (_order < PPMD7_MIN_ORDER || _order > PPMD7_MAX_ORDER || memSize < PPMD7_MIN_MEM_SIZE || memSize > PPMD7_MAX_MEM_SIZE) @@ -48,7 +46,7 @@ return S_OK; } -#define _rangeDec _ppmd.rc.dec +#define MY_rangeDec _ppmd.rc.dec #define CHECK_EXTRA_ERROR \ if (_inStream.Extra) { \ @@ -67,7 +65,7 @@ case kStatus_Error: return S_FALSE; case kStatus_NeedInit: _inStream.Init(); - if (!Ppmd7z_RangeDec_Init(&_rangeDec)) + if (!Ppmd7z_RangeDec_Init(&MY_rangeDec)) { _status = kStatus_Error; return (_res = S_FALSE); @@ -76,6 +74,7 @@ _status = kStatus_Normal; Ppmd7_Init(&_ppmd, _order); break; + default: break; } if (_outSizeDefined) @@ -110,7 +109,7 @@ if (!FinishStream || !_outSizeDefined || _outSize != _processedSize - || _rangeDec.Code == 0) + || MY_rangeDec.Code == 0) return S_OK; /* // We can decode additional End Marker here: @@ -119,7 +118,7 @@ */ } - if (sym != PPMD7_SYM_END || _rangeDec.Code != 0) + if (sym != PPMD7_SYM_END || MY_rangeDec.Code != 0) { _status = kStatus_Error; return (_res = S_FALSE); @@ -131,8 +130,8 @@ -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { if (!_outBuf) { @@ -147,16 +146,16 @@ do { const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec(_outBuf, kBufSize); - size_t processed = (size_t)(_processedSize - startPos); - RINOK(WriteStream(outStream, _outBuf, processed)); - RINOK(res); + const HRESULT res = CodeSpec(_outBuf, kBufSize); + const size_t processed = (size_t)(_processedSize - startPos); + RINOK(WriteStream(outStream, _outBuf, processed)) + RINOK(res) if (_status == kStatus_Finished_With_Mark) break; if (progress) { const UInt64 inProcessed = _inStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&inProcessed, &_processedSize)); + RINOK(progress->SetRatioInfo(&inProcessed, &_processedSize)) } } while (!_outSizeDefined || _processedSize < _outSize); @@ -168,7 +167,7 @@ } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { _outSizeDefined = (outSize != NULL); if (_outSizeDefined) @@ -179,37 +178,37 @@ return S_OK; } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { FinishStream = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inStream.GetProcessed(); return S_OK; } -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) { InSeqStream = inStream; _inStream.Stream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) { InSeqStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec((Byte *)data, size); + const HRESULT res = CodeSpec((Byte *)data, size); if (processedSize) *processedSize = (UInt32)(_processedSize - startPos); return res; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdDecoder.h 2020-07-03 09:56:31.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdDecoder.h 2023-03-28 13:00:00.000000000 +0000 @@ -1,8 +1,7 @@ // PpmdDecoder.h -// 2020-07-03 : Igor Pavlov : Public domain -#ifndef __COMPRESS_PPMD_DECODER_H -#define __COMPRESS_PPMD_DECODER_H +#ifndef ZIP7_INC_COMPRESS_PPMD_DECODER_H +#define ZIP7_INC_COMPRESS_PPMD_DECODER_H #include "../../../C/Ppmd7.h" @@ -15,18 +14,42 @@ namespace NCompress { namespace NPpmd { -class CDecoder : +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif + Byte *_outBuf; CByteInBufWrap _inStream; CPpmd7 _ppmd; @@ -43,36 +66,9 @@ public: - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER CMyComPtr InSeqStream; - #endif - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif + #endif CDecoder(): _outBuf(NULL), diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdEncoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdEncoder.cpp 2021-05-29 06:49:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.cpp 2023-03-28 13:00:00.000000000 +0000 @@ -24,7 +24,7 @@ const unsigned kMult = 16; if (MemSize / kMult > ReduceSize) { - for (unsigned i = 16; i <= 31; i++) + for (unsigned i = 16; i < 32; i++) { UInt32 m = (UInt32)1 << i; if (ReduceSize <= m / kMult) @@ -52,7 +52,7 @@ Ppmd7_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { int level = -1; CEncProps props; @@ -109,7 +109,7 @@ if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; + const UInt32 v = (UInt32)prop.ulVal; switch (propID) { case NCoderPropID::kOrder: @@ -127,17 +127,17 @@ return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { const UInt32 kPropSize = 5; Byte props[kPropSize]; props[0] = (Byte)_props.Order; - SetUi32(props + 1, _props.MemSize); + SetUi32(props + 1, _props.MemSize) return WriteStream(outStream, props, kPropSize); } -HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { if (!_inBuf) { @@ -160,7 +160,7 @@ for (;;) { UInt32 size; - RINOK(inStream->Read(_inBuf, kBufSize, &size)); + RINOK(inStream->Read(_inBuf, kBufSize, &size)) if (size == 0) { // We don't write EndMark in PPMD-7z. @@ -179,13 +179,13 @@ */ Ppmd7z_EncodeSymbols(&_ppmd, buf, lim); - RINOK(_outStream.Res); + RINOK(_outStream.Res) processed += size; if (progress) { const UInt64 outSize = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outSize)); + RINOK(progress->SetRatioInfo(&processed, &outSize)) } } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdEncoder.h 2020-04-14 11:33:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // PpmdEncoder.h -#ifndef __COMPRESS_PPMD_ENCODER_H -#define __COMPRESS_PPMD_ENCODER_H +#ifndef ZIP7_INC_COMPRESS_PPMD_ENCODER_H +#define ZIP7_INC_COMPRESS_PPMD_ENCODER_H #include "../../../C/Ppmd7.h" @@ -29,25 +29,17 @@ void Normalize(int level); }; -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) Byte *_inBuf; CByteOutBufWrap _outStream; CPpmd7 _ppmd; CEncProps _props; public: - MY_UNKNOWN_IMP3( - ICompressCoder, - ICompressSetCoderProperties, - ICompressWriteCoderProperties) - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); CEncoder(); ~CEncoder(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdRegister.cpp 2016-04-25 10:06:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdRegister.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -6,7 +6,7 @@ #include "PpmdDecoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "PpmdEncoder.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdZip.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdZip.cpp 2021-01-25 18:47:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.cpp 2023-12-20 13:00:00.000000000 +0000 @@ -12,6 +12,15 @@ namespace NCompress { namespace NPpmdZip { +static const UInt32 kBufSize = 1 << 20; + +bool CBuf::Alloc() +{ + if (!Buf) + Buf = (Byte *)::MidAlloc(kBufSize); + return (Buf != NULL); +} + CDecoder::CDecoder(bool fullFileMode): _fullFileMode(fullFileMode) { @@ -24,8 +33,8 @@ Ppmd8_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { // try { @@ -44,10 +53,10 @@ if (_inStream.Extra) return S_FALSE; - UInt32 val = GetUi16(buf); - unsigned order = (val & 0xF) + 1; - UInt32 mem = ((val >> 4) & 0xFF) + 1; - unsigned restor = (val >> 12); + const UInt32 val = GetUi16(buf); + const unsigned order = (val & 0xF) + 1; + const UInt32 mem = ((val >> 4) & 0xFF) + 1; + const unsigned restor = (val >> 12); if (order < 2 || restor > 2) return S_FALSE; @@ -94,12 +103,12 @@ } while (buf != lim); - size_t cur = (size_t)(buf - _outStream.Buf); + const size_t cur = (size_t)(buf - _outStream.Buf); processedSize += cur; - RINOK(WriteStream(outStream, _outStream.Buf, cur)); + RINOK(WriteStream(outStream, _outStream.Buf, cur)) - RINOK(_inStream.Res); + RINOK(_inStream.Res) if (_inStream.Extra) return S_FALSE; @@ -114,18 +123,18 @@ if (progress) { const UInt64 inProccessed = _inStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&inProccessed, &processedSize)); + RINOK(progress->SetRatioInfo(&inProccessed, &processedSize)) } } - RINOK(_inStream.Res); + RINOK(_inStream.Res) if (_fullFileMode) { if (!wasFinished) { - int res = Ppmd8_DecodeSymbol(&_ppmd); - RINOK(_inStream.Res); + const int res = Ppmd8_DecodeSymbol(&_ppmd); + RINOK(_inStream.Res) if (_inStream.Extra || res != -1) return S_FALSE; } @@ -142,13 +151,13 @@ } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { _fullFileMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inStream.GetProcessed(); return S_OK; @@ -184,14 +193,14 @@ Ppmd8_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { int level = -1; CEncProps props; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID > NCoderPropID::kReduceSize) continue; if (propID == NCoderPropID::kReduceSize) @@ -203,7 +212,7 @@ } if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; + const UInt32 v = (UInt32)prop.ulVal; switch (propID) { case NCoderPropID::kUsedMemorySize: @@ -238,8 +247,8 @@ Ppmd8_Construct(&_ppmd); } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { if (!_inStream.Alloc()) return E_OUTOFMEMORY; @@ -251,21 +260,24 @@ _outStream.Stream = outStream; _outStream.Init(); - Ppmd8_Init_RangeEnc(&_ppmd); + Ppmd8_Init_RangeEnc(&_ppmd) Ppmd8_Init(&_ppmd, (unsigned)_props.Order, (unsigned)_props.Restor); { - UInt32 val = (UInt32)(((unsigned)_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + ((unsigned)_props.Restor << 12)); + const unsigned val = + ((unsigned)_props.Order - 1) + + (((unsigned)_props.MemSizeMB - 1) << 4) + + ((unsigned)_props.Restor << 12); _outStream.WriteByte((Byte)(val & 0xFF)); _outStream.WriteByte((Byte)(val >> 8)); } - RINOK(_outStream.Res); + RINOK(_outStream.Res) UInt64 processed = 0; for (;;) { UInt32 size; - RINOK(inStream->Read(_inStream.Buf, kBufSize, &size)); + RINOK(inStream->Read(_inStream.Buf, kBufSize, &size)) if (size == 0) { Ppmd8_EncodeSymbol(&_ppmd, -1); @@ -284,17 +296,14 @@ } while (++buf != lim); - RINOK(_outStream.Res); + RINOK(_outStream.Res) if (progress) { const UInt64 outProccessed = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outProccessed)); + RINOK(progress->SetRatioInfo(&processed, &outProccessed)) } } } - - - }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdZip.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/PpmdZip.h 2020-04-13 14:02:23.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/PpmdZip.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // PpmdZip.h -#ifndef __COMPRESS_PPMD_ZIP_H -#define __COMPRESS_PPMD_ZIP_H +#ifndef ZIP7_INC_COMPRESS_PPMD_ZIP_H +#define ZIP7_INC_COMPRESS_PPMD_ZIP_H #include "../../../C/Alloc.h" #include "../../../C/Ppmd8.h" @@ -15,43 +15,27 @@ namespace NCompress { namespace NPpmdZip { -static const UInt32 kBufSize = (1 << 20); - struct CBuf { Byte *Buf; CBuf(): Buf(NULL) {} ~CBuf() { ::MidFree(Buf); } - bool Alloc() - { - if (!Buf) - Buf = (Byte *)::MidAlloc(kBufSize); - return (Buf != 0); - } + bool Alloc(); }; -class CDecoder : - public ICompressCoder, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_3( + CDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + bool _fullFileMode; CByteInBufWrap _inStream; CBuf _outStream; CPpmd8 _ppmd; - bool _fullFileMode; public: - MY_UNKNOWN_IMP2( - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - CDecoder(bool fullFileMode = true); ~CDecoder(); }; @@ -74,20 +58,17 @@ void Normalize(int level); }; -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_2( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties +) CByteOutBufWrap _outStream; CBuf _inStream; CPpmd8 _ppmd; CEncProps _props; public: - MY_UNKNOWN_IMP1(ICompressSetCoderProperties) - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); CEncoder(); ~CEncoder(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/QuantumDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/QuantumDecoder.cpp 2021-04-01 09:50:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.cpp 2024-02-24 15:00:00.000000000 +0000 @@ -2,6 +2,11 @@ #include "StdAfx.h" +// #include + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + #include "../../Common/Defs.h" #include "QuantumDecoder.h" @@ -11,184 +16,339 @@ static const unsigned kNumLenSymbols = 27; static const unsigned kMatchMinLen = 3; -static const unsigned kNumSimplePosSlots = 4; static const unsigned kNumSimpleLenSlots = 6; -static const UInt16 kUpdateStep = 8; -static const UInt16 kFreqSumMax = 3800; -static const unsigned kReorderCountStart = 4; +static const unsigned kUpdateStep = 8; +static const unsigned kFreqSumMax = 3800; +static const unsigned kReorderCount_Start = 4; static const unsigned kReorderCount = 50; -void CModelDecoder::Init(unsigned numItems) + +class CRangeDecoder { - NumItems = numItems; - ReorderCount = kReorderCountStart; - for (unsigned i = 0; i < numItems; i++) + UInt32 Low; + UInt32 Range; + UInt32 Code; + + unsigned _bitOffset; + const Byte *_buf; + const Byte *_bufLim; + +public: + + Z7_FORCE_INLINE + void Init(const Byte *inData, size_t inSize) { - Freqs[i] = (UInt16)(numItems - i); - Vals[i] = (Byte)i; + Code = ((UInt32)*inData << 8) | inData[1]; + _buf = inData + 2; + _bufLim = inData + inSize; + _bitOffset = 0; + Low = 0; + Range = 0x10000; } - Freqs[numItems] = 0; -} + Z7_FORCE_INLINE + bool WasExtraRead() const + { + return _buf > _bufLim; + } + + Z7_FORCE_INLINE + UInt32 ReadBits(unsigned numBits) // numBits > 0 + { + unsigned bitOffset = _bitOffset; + const Byte *buf = _buf; + const UInt32 res = GetBe32(buf) << bitOffset; + bitOffset += numBits; + _buf = buf + (bitOffset >> 3); + _bitOffset = bitOffset & 7; + return res >> (32 - numBits); + } + + // ---------- Range Decoder functions ---------- + + Z7_FORCE_INLINE + bool Finish() + { + const unsigned numBits = 2 + ((16 - 2 - _bitOffset) & 7); + if (ReadBits(numBits) != 0) + return false; + return _buf == _bufLim; + } + + Z7_FORCE_INLINE + UInt32 GetThreshold(UInt32 total) const + { + return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; + } + + Z7_FORCE_INLINE + void Decode(UInt32 start, UInt32 end, UInt32 total) + { + // UInt32 hi = ~(Low + end * Range / total - 1); + UInt32 hi = 0 - (Low + end * Range / total); + const UInt32 offset = start * Range / total; + UInt32 lo = Low + offset; + Code -= offset; + UInt32 numBits = 0; + lo ^= hi; + while (lo & (1u << 15)) + { + lo <<= 1; + hi <<= 1; + numBits++; + } + lo ^= hi; + UInt32 an = lo & hi; + while (an & (1u << 14)) + { + an <<= 1; + lo <<= 1; + hi <<= 1; + numBits++; + } + Low = lo; + Range = ((~hi - lo) & 0xffff) + 1; + if (numBits) + Code = (Code << numBits) + ReadBits(numBits); + } +}; + + +// Z7_FORCE_INLINE +Z7_NO_INLINE unsigned CModelDecoder::Decode(CRangeDecoder *rc) +// Z7_NO_INLINE void CModelDecoder::Normalize() { - UInt32 threshold = rc->GetThreshold(Freqs[0]); - unsigned i; - for (i = 1; Freqs[i] > threshold; i++); - - rc->Decode(Freqs[i], Freqs[(size_t)i - 1], Freqs[0]); - unsigned res = Vals[--i]; - - do - Freqs[i] = (UInt16)(Freqs[i] + kUpdateStep); - while (i--); - if (Freqs[0] > kFreqSumMax) { if (--ReorderCount == 0) { ReorderCount = kReorderCount; - for (i = 0; i < NumItems; i++) - Freqs[i] = (UInt16)(((Freqs[i] - Freqs[(size_t)i + 1]) + 1) >> 1); - for (i = 0; i < NumItems - 1; i++) - for (unsigned j = i + 1; j < NumItems; j++) - if (Freqs[i] < Freqs[j]) - { - UInt16 tmpFreq = Freqs[i]; - Byte tmpVal = Vals[i]; - Freqs[i] = Freqs[j]; - Vals[i] = Vals[j]; - Freqs[j] = tmpFreq; - Vals[j] = tmpVal; - } - + { + unsigned i = NumItems; + unsigned next = 0; + UInt16 *freqs = &Freqs[i]; + do + { + const unsigned freq = *--freqs; + *freqs = (UInt16)((freq - next + 1) >> 1); + next = freq; + } + while (--i); + } + { + for (unsigned i = 0; i < NumItems - 1; i++) + { + UInt16 freq = Freqs[i]; + for (unsigned k = i + 1; k < NumItems; k++) + if (freq < Freqs[k]) + { + const UInt16 freq2 = Freqs[k]; + Freqs[k] = freq; + Freqs[i] = freq2; + freq = freq2; + const Byte val = Vals[i]; + Vals[i] = Vals[k]; + Vals[k] = val; + } + } + } + unsigned i = NumItems; + unsigned freq = 0; + UInt16 *freqs = &Freqs[i]; do - Freqs[i] = (UInt16)(Freqs[i] + Freqs[(size_t)i + 1]); - while (i--); + { + freq += *--freqs; + *freqs = (UInt16)freq; + } + while (--i); } else { - i = NumItems - 1; + unsigned i = NumItems; + unsigned next = 1; + UInt16 *freqs = &Freqs[i]; do { - Freqs[i] = (UInt16)(Freqs[i] >> 1); - if (Freqs[i] <= Freqs[(size_t)i + 1]) - Freqs[i] = (UInt16)(Freqs[(size_t)i + 1] + 1); + unsigned freq = *--freqs >> 1; + if (freq < next) + freq = next; + *freqs = (UInt16)freq; + next = freq + 1; } - while (i--); + while (--i); } } - + unsigned res; + { + const unsigned freq0 = Freqs[0]; + Freqs[0] = (UInt16)(freq0 + kUpdateStep); + const unsigned threshold = rc->GetThreshold(freq0); + UInt16 *freqs = &Freqs[1]; + unsigned freq = *freqs; + while (freq > threshold) + { + *freqs++ = (UInt16)(freq + kUpdateStep); + freq = *freqs; + } + res = Vals[freqs - Freqs - 1]; + rc->Decode(freq, freqs[-1] - kUpdateStep, freq0); + } return res; } -void CDecoder::Init() +Z7_NO_INLINE +void CModelDecoder::Init(unsigned numItems, unsigned startVal) { - m_Selector.Init(kNumSelectors); - unsigned i; - for (i = 0; i < kNumLitSelectors; i++) - m_Literals[i].Init(kNumLitSymbols); - unsigned numItems = (_numDictBits == 0 ? 1 : (_numDictBits << 1)); - const unsigned kNumPosSymbolsMax[kNumMatchSelectors] = { 24, 36, 42 }; - for (i = 0; i < kNumMatchSelectors; i++) - m_PosSlot[i].Init(MyMin(numItems, kNumPosSymbolsMax[i])); - m_LenSlot.Init(kNumLenSymbols); + NumItems = numItems; + ReorderCount = kReorderCount_Start; + UInt16 *freqs = Freqs; + freqs[numItems] = 0; + Byte *vals = Vals; + do + { + *freqs++ = (UInt16)numItems; + *vals++ = (Byte)startVal; + startVal++; + } + while (--numItems); } -HRESULT CDecoder::CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) +HRESULT CDecoder::Code(const Byte *inData, size_t inSize, UInt32 outSize, bool keepHistory) { if (inSize < 2) return S_FALSE; + if (!keepHistory) + { + _winPos = 0; + m_Selector.Init(kNumSelectors, 0); + unsigned i; + for (i = 0; i < kNumLitSelectors; i++) + m_Literals[i].Init(kNumLitSymbols, i * kNumLitSymbols); + const unsigned numItems = (_numDictBits == 0 ? 1 : (_numDictBits << 1)); + // const unsigned kNumPosSymbolsMax[kNumMatchSelectors] = { 24, 36, 42 }; + for (i = 0; i < kNumMatchSelectors; i++) + { + const unsigned num = 24 + i * 6 + ((i + 1) & 2) * 3; + m_PosSlot[i].Init(MyMin(numItems, num), 0); + } + m_LenSlot.Init(kNumLenSymbols, kMatchMinLen + kNumMatchSelectors - 1); + } CRangeDecoder rc; - rc.Stream.SetStreamAndInit(inData, inSize); - rc.Init(); + rc.Init(inData, inSize); + const UInt32 winSize = _winSize; + Byte *pos; + { + UInt32 winPos = _winPos; + if (winPos == winSize) + { + winPos = 0; + _winPos = winPos; + _overWin = true; + } + if (outSize > winSize - winPos) + return S_FALSE; + pos = _win + winPos; + } while (outSize != 0) { - if (rc.Stream.WasExtraRead()) + if (rc.WasExtraRead()) return S_FALSE; - unsigned selector = m_Selector.Decode(&rc); + const unsigned selector = m_Selector.Decode(&rc); if (selector < kNumLitSelectors) { - Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&rc)); - _outWindow.PutByte(b); - outSize--; + const unsigned b = m_Literals[selector].Decode(&rc); + *pos++ = (Byte)b; + --outSize; + // if (--outSize == 0) break; } else { - selector -= kNumLitSelectors; - unsigned len = selector + kMatchMinLen; + unsigned len = selector - kNumLitSelectors + kMatchMinLen; - if (selector == 2) + if (selector == kNumLitSelectors + kNumMatchSelectors - 1) { - unsigned lenSlot = m_LenSlot.Decode(&rc); - if (lenSlot >= kNumSimpleLenSlots) + len = m_LenSlot.Decode(&rc); + if (len >= kNumSimpleLenSlots + kMatchMinLen + kNumMatchSelectors - 1) { - lenSlot -= 2; - unsigned numDirectBits = (unsigned)(lenSlot >> 2); - len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; + len -= kNumSimpleLenSlots - 4 + kMatchMinLen + kNumMatchSelectors - 1; + const unsigned numDirectBits = (unsigned)(len >> 2); + len = ((4 | (len & 3)) << numDirectBits) - (4 << 1) + + kNumSimpleLenSlots + + kMatchMinLen + kNumMatchSelectors - 1; if (numDirectBits < 6) - len += rc.Stream.ReadBits(numDirectBits); + len += rc.ReadBits(numDirectBits); } - else - len += lenSlot; } - UInt32 dist = m_PosSlot[selector].Decode(&rc); + UInt32 dist = m_PosSlot[(size_t)selector - kNumLitSelectors].Decode(&rc); - if (dist >= kNumSimplePosSlots) + if (dist >= 4) { - unsigned numDirectBits = (unsigned)((dist >> 1) - 1); - dist = ((2 | (dist & 1)) << numDirectBits) + rc.Stream.ReadBits(numDirectBits); + const unsigned numDirectBits = (unsigned)((dist >> 1) - 1); + dist = ((2 | (dist & 1)) << numDirectBits) + rc.ReadBits(numDirectBits); } - unsigned locLen = len; - if (len > outSize) - locLen = (unsigned)outSize; - if (!_outWindow.CopyBlock(dist, locLen)) - return S_FALSE; - outSize -= locLen; - len -= locLen; - if (len != 0) + if ((Int32)(outSize -= len) < 0) return S_FALSE; + + ptrdiff_t srcPos = (ptrdiff_t)(Int32)((pos - _win) - (ptrdiff_t)dist - 1); + if (srcPos < 0) + { + if (!_overWin) + return S_FALSE; + UInt32 rem = (UInt32)-srcPos; + srcPos += winSize; + if (rem < len) + { + const Byte *src = _win + srcPos; + len -= rem; + do + *pos++ = *src++; + while (--rem); + srcPos = 0; + } + } + const Byte *src = _win + srcPos; + do + *pos++ = *src++; + while (--len); + // if (outSize == 0) break; } } + _winPos = (UInt32)(size_t)(pos - _win); return rc.Finish() ? S_OK : S_FALSE; } -HRESULT CDecoder::Code(const Byte *inData, size_t inSize, - ISequentialOutStream *outStream, UInt32 outSize, - bool keepHistory) -{ - try - { - _outWindow.SetStream(outStream); - _outWindow.Init(keepHistory); - if (!keepHistory) - Init(); - - HRESULT res = CodeSpec(inData, inSize, outSize); - HRESULT res2 = _outWindow.Flush(); - return res != S_OK ? res : res2; - } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} HRESULT CDecoder::SetParams(unsigned numDictBits) { if (numDictBits > 21) return E_INVALIDARG; _numDictBits = numDictBits; - if (!_outWindow.Create((UInt32)1 << _numDictBits)) - return E_OUTOFMEMORY; + _winPos = 0; + _overWin = false; + + if (numDictBits < 15) + numDictBits = 15; + _winSize = (UInt32)1 << numDictBits; + if (!_win || _winSize > _winSize_allocated) + { + MidFree(_win); + _win = NULL; + _win = (Byte *)MidAlloc(_winSize); + if (!_win) + return E_OUTOFMEMORY; + _winSize_allocated = _winSize; + } return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/QuantumDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/QuantumDecoder.h 2015-08-29 10:53:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/QuantumDecoder.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,152 +1,43 @@ // QuantumDecoder.h -#ifndef __COMPRESS_QUANTUM_DECODER_H -#define __COMPRESS_QUANTUM_DECODER_H +#ifndef ZIP7_INC_COMPRESS_QUANTUM_DECODER_H +#define ZIP7_INC_COMPRESS_QUANTUM_DECODER_H -#include "../../Common/MyCom.h" - -#include "LzOutWindow.h" +#include "../../Common/MyTypes.h" namespace NCompress { namespace NQuantum { -class CBitDecoder -{ - UInt32 Value; - bool _extra; - const Byte *_buf; - const Byte *_bufLim; -public: - void SetStreamAndInit(const Byte *inData, size_t inSize) - { - _buf = inData; - _bufLim = inData + inSize; - Value = 0x10000; - _extra = false; - } - - bool WasExtraRead() const { return _extra; } - - bool WasFinishedOK() const - { - return !_extra && _buf == _bufLim; - } - - UInt32 ReadBit() - { - if (Value >= 0x10000) - { - Byte b; - if (_buf >= _bufLim) - { - b = 0xFF; - _extra = true; - } - else - b = *_buf++; - Value = 0x100 | b; - } - UInt32 res = (Value >> 7) & 1; - Value <<= 1; - return res; - } - - UInt32 ReadStart16Bits() - { - // we use check for extra read in another code. - UInt32 val = ((UInt32)*_buf << 8) | _buf[1]; - _buf += 2; - return val; - } - - UInt32 ReadBits(unsigned numBits) // numBits > 0 - { - UInt32 res = 0; - do - res = (res << 1) | ReadBit(); - while (--numBits); - return res; - } -}; - - -class CRangeDecoder -{ - UInt32 Low; - UInt32 Range; - UInt32 Code; -public: - CBitDecoder Stream; - - void Init() - { - Low = 0; - Range = 0x10000; - Code = Stream.ReadStart16Bits(); - } - - bool Finish() - { - // do all streams use these two bits at end? - if (Stream.ReadBit() != 0) return false; - if (Stream.ReadBit() != 0) return false; - return Stream.WasFinishedOK(); - } - - UInt32 GetThreshold(UInt32 total) const - { - return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; - } - - void Decode(UInt32 start, UInt32 end, UInt32 total) - { - UInt32 high = Low + end * Range / total - 1; - UInt32 offset = start * Range / total; - Code -= offset; - Low += offset; - for (;;) - { - if ((Low & 0x8000) != (high & 0x8000)) - { - if ((Low & 0x4000) == 0 || (high & 0x4000) != 0) - break; - Low &= 0x3FFF; - high |= 0x4000; - } - Low = (Low << 1) & 0xFFFF; - high = ((high << 1) | 1) & 0xFFFF; - Code = ((Code << 1) | Stream.ReadBit()); - } - Range = high - Low + 1; - } -}; - - const unsigned kNumLitSelectorBits = 2; -const unsigned kNumLitSelectors = (1 << kNumLitSelectorBits); +const unsigned kNumLitSelectors = 1 << kNumLitSelectorBits; const unsigned kNumLitSymbols = 1 << (8 - kNumLitSelectorBits); const unsigned kNumMatchSelectors = 3; const unsigned kNumSelectors = kNumLitSelectors + kNumMatchSelectors; const unsigned kNumSymbolsMax = kNumLitSymbols; // 64 +class CRangeDecoder; class CModelDecoder { unsigned NumItems; unsigned ReorderCount; - UInt16 Freqs[kNumSymbolsMax + 1]; Byte Vals[kNumSymbolsMax]; + UInt16 Freqs[kNumSymbolsMax + 1]; public: - void Init(unsigned numItems); + Byte _pad[64 - 10]; // for structure size alignment + + void Init(unsigned numItems, unsigned startVal); unsigned Decode(CRangeDecoder *rc); }; -class CDecoder: - public IUnknown, - public CMyUnknownImp +class CDecoder { - CLzOutWindow _outWindow; + UInt32 _winSize; + UInt32 _winPos; + UInt32 _winSize_allocated; + bool _overWin; + Byte *_win; unsigned _numDictBits; CModelDecoder m_Selector; @@ -157,17 +48,11 @@ void Init(); HRESULT CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize); public: - - MY_UNKNOWN_IMP - - HRESULT Code(const Byte *inData, size_t inSize, - ISequentialOutStream *outStream, UInt32 outSize, - bool keepHistory); - + HRESULT Code(const Byte *inData, size_t inSize, UInt32 outSize, bool keepHistory); HRESULT SetParams(unsigned numDictBits); - - CDecoder(): _numDictBits(0) {} - virtual ~CDecoder() {} + + CDecoder(): _win(NULL), _numDictBits(0) {} + const Byte * GetDataPtr() const { return _win + _winPos; } }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.cpp 2021-01-25 18:48:21.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -198,7 +198,7 @@ while (i); } - RINOK(outBuffer.Flush()); + RINOK(outBuffer.Flush()) if (res == S_OK) if (_fullStreamMode) @@ -216,8 +216,8 @@ } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } // catch(const CInBufferException &e) { return e.ErrorCode; } @@ -227,14 +227,14 @@ } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { _fullStreamMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = _inProcessed; return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.h 2017-12-29 16:06:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ShrinkDecoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ShrinkDecoder.h -#ifndef __COMPRESS_SHRINK_DECODER_H -#define __COMPRESS_SHRINK_DECODER_H +#ifndef ZIP7_INC_COMPRESS_SHRINK_DECODER_H +#define ZIP7_INC_COMPRESS_SHRINK_DECODER_H #include "../../Common/MyCom.h" @@ -13,12 +13,12 @@ const unsigned kNumMaxBits = 13; const unsigned kNumItems = 1 << kNumMaxBits; -class CDecoder : - public ICompressCoder, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_3( + CDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) bool _fullStreamMode; UInt64 _inProcessed; @@ -28,16 +28,6 @@ HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - -public: - MY_UNKNOWN_IMP2( - ICompressSetFinishMode, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/StdAfx.h 2013-11-13 06:35:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XpressDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/XpressDecoder.cpp 2021-01-22 20:15:57.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -2,47 +2,301 @@ #include "StdAfx.h" -// #include - #include "../../../C/CpuArch.h" +#include "../../../C/RotateDefs.h" #include "HuffmanDecoder.h" #include "XpressDecoder.h" -namespace NCompress { -namespace NXpress { +#ifdef MY_CPU_LE_UNALIGN + #define Z7_XPRESS_DEC_USE_UNALIGNED_COPY +#endif + +#ifdef Z7_XPRESS_DEC_USE_UNALIGNED_COPY + + #define COPY_CHUNK_SIZE 16 + + #define COPY_CHUNK_4_2(dest, src) \ + { \ + ((UInt32 *)(void *)dest)[0] = ((const UInt32 *)(const void *)src)[0]; \ + ((UInt32 *)(void *)dest)[1] = ((const UInt32 *)(const void *)src)[1]; \ + src += 4 * 2; \ + dest += 4 * 2; \ + } + + /* sse2 doesn't help here in GCC and CLANG. + so we disabled sse2 here */ +#if 0 + #if defined(MY_CPU_AMD64) + #define Z7_XPRESS_DEC_USE_SSE2 + #elif defined(MY_CPU_X86) + #if defined(_MSC_VER) && _MSC_VER >= 1300 && defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || defined(__SSE2__) \ + // || 1 == 1 // for debug only + #define Z7_XPRESS_DEC_USE_SSE2 + #endif + #endif +#endif + + #if defined(MY_CPU_ARM64) + #include + #define COPY_OFFSET_MIN 16 + #define COPY_CHUNK1(dest, src) \ + { \ + vst1q_u8((uint8_t *)(void *)dest, \ + vld1q_u8((const uint8_t *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= dest_lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(Z7_XPRESS_DEC_USE_SSE2) + #include // sse2 + #define COPY_OFFSET_MIN 16 + + #define COPY_CHUNK1(dest, src) \ + { \ + _mm_storeu_si128((__m128i *)(void *)dest, \ + _mm_loadu_si128((const __m128i *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= dest_lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(MY_CPU_64BIT) + #define COPY_OFFSET_MIN 8 + + #define COPY_CHUNK(dest, src) \ + { \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + ((UInt64 *)(void *)dest)[1] = ((const UInt64 *)(const void *)src)[1]; \ + src += 8 * 2; \ + dest += 8 * 2; \ + } + + #else + #define COPY_OFFSET_MIN 4 + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_4_2(dest, src); \ + COPY_CHUNK_4_2(dest, src); \ + } + + #endif +#endif + + +#ifndef COPY_CHUNK_SIZE + #define COPY_OFFSET_MIN 4 + #define COPY_CHUNK_SIZE 8 + #define COPY_CHUNK_2(dest, src) \ + { \ + const Byte a0 = src[0]; \ + const Byte a1 = src[1]; \ + dest[0] = a0; \ + dest[1] = a1; \ + src += 2; \ + dest += 2; \ + } + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + } +#endif -struct CBitStream + +#define COPY_CHUNKS \ +{ \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do { COPY_CHUNK(dest, src) } \ + while (dest < dest_lim); \ +} + + +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch_1(Byte *dest, const Byte *dest_lim) { - UInt32 Value; - unsigned BitPos; + const unsigned b0 = dest[-1]; + { +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) && (COPY_CHUNK_SIZE == 16) + #if defined(MY_CPU_64BIT) + { + const UInt64 v64 = (UInt64)b0 * 0x0101010101010101; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + ((UInt64 *)(void *)dest)[0] = v64; + ((UInt64 *)(void *)dest)[1] = v64; + dest += 16; + } + while (dest < dest_lim); + } + #else + { + UInt32 v = b0; + v |= v << 8; + v |= v << 16; + do + { + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + } + while (dest < dest_lim); + } + #endif +#else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + } + while (dest < dest_lim); +#endif + } +} - UInt32 GetValue(unsigned numBits) const - { - return (Value >> (BitPos - numBits)) & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) + +// (offset != 1) +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch_Non1(Byte *dest, size_t offset, const Byte *dest_lim) +{ + const Byte *src = dest - offset; { - BitPos -= numBits; + // (COPY_OFFSET_MIN >= 4) + if (offset >= COPY_OFFSET_MIN) + { + COPY_CHUNKS + // return; + } + else +#if (COPY_OFFSET_MIN > 4) + #if COPY_CHUNK_SIZE < 8 + #error Stop_Compiling_Bad_COPY_CHUNK_SIZE + #endif + if (offset >= 4) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + COPY_CHUNK_4_2(dest, src) + #if COPY_CHUNK_SIZE != 16 + if (dest >= dest_lim) break; + #endif + COPY_CHUNK_4_2(dest, src) + } + while (dest < dest_lim); + // return; + } + else +#endif + { + // (offset < 4) + if (offset == 2) + { +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) + UInt32 w0 = GetUi16(src); + w0 += w0 << 16; + do + { + SetUi32(dest, w0) + dest += 4; + } + while (dest < dest_lim); +#else + const unsigned b0 = src[0]; + const Byte b1 = src[1]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest += 2; + } + while (dest < dest_lim); +#endif + } + else // (offset == 3) + { + const unsigned b0 = src[0]; +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) + const unsigned w1 = GetUi16(src + 1); + do + { + dest[0] = (Byte)b0; + SetUi16(dest + 1, (UInt16)w1) + dest += 3; + } + while (dest < dest_lim); +#else + const Byte b1 = src[1]; + const Byte b2 = src[2]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest[2] = b2; + dest += 3; + } + while (dest < dest_lim); +#endif + } + } } -}; +} + + +namespace NCompress { +namespace NXpress { #define BIT_STREAM_NORMALIZE \ - if (bs.BitPos < 16) { \ + if (BitPos > 16) { \ if (in >= lim) return S_FALSE; \ - bs.Value = (bs.Value << 16) | GetUi16(in); \ - in += 2; bs.BitPos += 16; } - + BitPos -= 16; \ + Value |= (UInt32)GetUi16(in) << BitPos; \ + in += 2; } + +#define MOVE_POS(bs, numBits) \ + BitPos += (unsigned)numBits; \ + Value <<= numBits; \ + + static const unsigned kNumHuffBits = 15; +static const unsigned kNumTableBits = 10; static const unsigned kNumLenBits = 4; static const unsigned kLenMask = (1 << kNumLenBits) - 1; static const unsigned kNumPosSlots = 16; static const unsigned kNumSyms = 256 + (kNumPosSlots << kNumLenBits); -HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) +HRESULT Decode_WithExceedWrite(const Byte *in, size_t inSize, Byte *out, size_t outSize) { - NCompress::NHuffman::CDecoder huff; + NCompress::NHuffman::CDecoder huff; if (inSize < kNumSyms / 2 + 4) return S_FALSE; @@ -50,50 +304,57 @@ Byte levels[kNumSyms]; for (unsigned i = 0; i < kNumSyms / 2; i++) { - Byte b = in[i]; - levels[(size_t)i * 2] = (Byte)(b & 0xF); + const unsigned b = in[i]; + levels[(size_t)i * 2 ] = (Byte)(b & 0xf); levels[(size_t)i * 2 + 1] = (Byte)(b >> 4); } - if (!huff.BuildFull(levels)) + if (!huff.Build(levels, NHuffman::k_BuildMode_Full)) return S_FALSE; } + UInt32 Value; + unsigned BitPos; // how many bits in (Value) were processed - CBitStream bs; - - const Byte *lim = in + inSize - 1; - + const Byte *lim = in + inSize - 1; // points to last byte in += kNumSyms / 2; - bs.Value = (GetUi16(in) << 16) | GetUi16(in + 2); +#ifdef MY_CPU_LE_UNALIGN + Value = GetUi32(in); + Value = rotlFixed(Value, 16); +#else + Value = ((UInt32)GetUi16(in) << 16) | GetUi16(in + 2); +#endif + in += 4; - bs.BitPos = 32; - - size_t pos = 0; + BitPos = 0; + Byte *dest = out; + const Byte *outLim = out + outSize; for (;;) { - // printf("\n%d", pos); - UInt32 sym = huff.DecodeFull(&bs); - // printf(" sym = %d", sym); + unsigned sym; + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, &huff, kNumHuffBits, kNumTableBits, + Value, Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {}, MOVE_POS, {}, bs) + // 0 < BitPos <= 31 BIT_STREAM_NORMALIZE + // 0 < BitPos <= 16 - if (pos >= outSize) - return (sym == 256 && in == lim + 1) ? S_OK : S_FALSE; + if (dest >= outLim) + return (sym == 256 && Value == 0 && in == lim + 1) ? S_OK : S_FALSE; if (sym < 256) - out[pos++] = (Byte)sym; + *dest++ = (Byte)sym; else { - sym -= 256; - UInt32 dist = sym >> kNumLenBits; - UInt32 len = sym & kLenMask; + const unsigned distBits = (unsigned)(Byte)sym >> kNumLenBits; // (sym - 256) >> kNumLenBits; + UInt32 len = (UInt32)(sym & kLenMask); if (len == kLenMask) { if (in > lim) return S_FALSE; + // here we read input bytes in out-of-order related to main input stream (bits in Value): len = *in++; - if (len == 0xFF) + if (len == 0xff) { if (in >= lim) return S_FALSE; @@ -104,26 +365,33 @@ len += kLenMask; } - bs.BitPos -= dist; - dist = (UInt32)1 << dist; - dist += ((bs.Value >> bs.BitPos) & (dist - 1)); - - BIT_STREAM_NORMALIZE - - if (len + 3 > outSize - pos) - return S_FALSE; - if (dist > pos) + len += 3; + if (len > (size_t)(outLim - dest)) return S_FALSE; - Byte *dest = out + pos; - const Byte *src = dest - dist; - pos += len + 3; - len += 1; - *dest++ = *src++; - *dest++ = *src++; - do - *dest++ = *src++; - while (--len); + if (distBits == 0) + { + // d == 1 + if (dest == out) + return S_FALSE; + Byte *destTemp = dest; + dest += len; + CopyMatch_1(destTemp, dest); + } + else + { + unsigned d = (unsigned)(Value >> (32 - distBits)); + MOVE_POS(bs, distBits) + d += 1u << distBits; + // 0 < BitPos <= 31 + BIT_STREAM_NORMALIZE + // 0 < BitPos <= 16 + if (d > (size_t)(dest - out)) + return S_FALSE; + Byte *destTemp = dest; + dest += len; + CopyMatch_Non1(destTemp, d, dest); + } } } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XpressDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/XpressDecoder.h 2015-08-26 11:24:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XpressDecoder.h 2024-01-01 10:00:00.000000000 +0000 @@ -1,12 +1,17 @@ // XpressDecoder.h -#ifndef __XPRESS_DECODER_H -#define __XPRESS_DECODER_H +#ifndef ZIP7_INC_XPRESS_DECODER_H +#define ZIP7_INC_XPRESS_DECODER_H + +#include "../../Common/MyTypes.h" namespace NCompress { namespace NXpress { -HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize); +// (out) buffer size must be larger than (outSize) for the following value: +const unsigned kAdditionalOutputBufSize = 32; + +HRESULT Decode_WithExceedWrite(const Byte *in, size_t inSize, Byte *out, size_t outSize); }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XzDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/XzDecoder.cpp 2020-03-07 17:59:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -26,6 +26,7 @@ case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + default: break; } return S_FALSE; } @@ -50,10 +51,10 @@ int isMT = False; - #ifndef _7ZIP_ST + #ifndef Z7_ST { props.numThreads = 1; - UInt32 numThreads = _numThreads; + const UInt32 numThreads = _numThreads; if (_tryMt && numThreads > 1) { @@ -87,7 +88,7 @@ MainDecodeSRes = res; - #ifndef _7ZIP_ST + #ifndef Z7_ST // _tryMt = isMT; #endif @@ -113,33 +114,33 @@ } -HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { return Decode(inStream, outStream, outSize, _finishStream, progress); } -STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CComDecoder::SetFinishMode(UInt32 finishMode)) { _finishStream = (finishMode != 0); return S_OK; } -STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize(UInt64 *value)) { *value = Stat.InSize; return S_OK; } -#ifndef _7ZIP_ST +#ifndef Z7_ST -STDMETHODIMP CComDecoder::SetNumberOfThreads(UInt32 numThreads) +Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads(UInt32 numThreads)) { _numThreads = numThreads; return S_OK; } -STDMETHODIMP CComDecoder::SetMemLimit(UInt64 memUsage) +Z7_COM7F_IMF(CComDecoder::SetMemLimit(UInt64 memUsage)) { _memUsage = memUsage; return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XzDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/XzDecoder.h 2020-03-04 13:44:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzDecoder.h 2023-02-01 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // XzDecoder.h -#ifndef __XZ_DECODER_H -#define __XZ_DECODER_H +#ifndef ZIP7_INC_XZ_DECODER_H +#define ZIP7_INC_XZ_DECODER_H #include "../../../C/Xz.h" @@ -46,45 +46,38 @@ }; -class CComDecoder: +class CComDecoder Z7_final: public ICompressCoder, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, - - #ifndef _7ZIP_ST + #ifndef Z7_ST public ICompressSetCoderMt, public ICompressSetMemLimit, - #endif - + #endif public CMyUnknownImp, public CDecoder { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + bool _finishStream; public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit) - #endif - - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - - #ifndef _7ZIP_ST - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - STDMETHOD(SetMemLimit)(UInt64 memUsage); - #endif - CComDecoder(): _finishStream(false) {} }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XzEncoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/XzEncoder.cpp 2021-01-25 11:20:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.cpp 2024-01-01 18:00:00.000000000 +0000 @@ -15,9 +15,7 @@ namespace NCompress { namespace NLzma2 { - HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); - } namespace NXz { @@ -63,7 +61,7 @@ static int FilterIdFromName(const wchar_t *name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) { const CMethodNamePair &pair = g_NamePairs[i]; if (StringsAreEqualNoCase_Ascii(name, pair.Name)) @@ -130,7 +128,7 @@ { if (prop.vt == VT_UI4) { - UInt32 id32 = prop.ulVal; + const UInt32 id32 = prop.ulVal; if (id32 == XZ_ID_Delta) return E_INVALIDARG; xzProps.filterProps.id = prop.ulVal; @@ -156,20 +154,20 @@ } else { - int filterId = FilterIdFromName(prop.bstrVal); + const int filterId = FilterIdFromName(prop.bstrVal); if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */) return E_INVALIDARG; - id32 = (unsigned)filterId; + id32 = (UInt32)(unsigned)filterId; } } if (id32 == XZ_ID_Delta) { - wchar_t c = *name; + const wchar_t c = *name; if (c != '-' && c != ':') return E_INVALIDARG; name++; - UInt32 delta = ConvertStringToUInt32(name, &end); + const UInt32 delta = ConvertStringToUInt32(name, &end); if (end == name || *end != 0 || delta == 0 || delta > 256) return E_INVALIDARG; xzProps.filterProps.delta = delta; @@ -185,14 +183,14 @@ } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { XzProps_Init(&xzProps); for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetCoderProp(propIDs[i], coderProps[i])); + RINOK(SetCoderProp(propIDs[i], coderProps[i])) } return S_OK; @@ -200,13 +198,13 @@ } -STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID == NCoderPropID::kExpectedDataSize) if (prop.vt == VT_UI8) XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); @@ -218,8 +216,8 @@ #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { CSeqInStreamWrap inWrap; CSeqOutStreamWrap outWrap; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/XzEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/XzEncoder.h 2017-07-27 08:34:57.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/XzEncoder.h 2023-03-28 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // XzEncoder.h -#ifndef __XZ_ENCODER_H -#define __XZ_ENCODER_H +#ifndef ZIP7_INC_XZ_ENCODER_H +#define ZIP7_INC_XZ_ENCODER_H #include "../../../C/XzEnc.h" @@ -12,33 +12,22 @@ namespace NCompress { namespace NXz { - -class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressSetCoderPropertiesOpt, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressSetCoderPropertiesOpt +) CXzEncHandle _encoder; public: CXzProps xzProps; - MY_UNKNOWN_IMP3( - ICompressCoder, - ICompressSetCoderProperties, - ICompressSetCoderPropertiesOpt) - void InitCoderProps(); HRESULT SetCheckSize(UInt32 checkSizeInBytes); HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); CEncoder(); - virtual ~CEncoder(); + ~CEncoder(); }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZDecoder.cpp 2017-01-24 09:17:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -14,7 +14,7 @@ namespace NCompress { namespace NZ { -static const UInt32 kBufferSize = (1 << 20); +static const size_t kBufferSize = 1 << 20; static const Byte kNumBitsMask = 0x1F; static const Byte kBlockModeMask = 0x80; static const unsigned kNumMinBits = 9; @@ -22,21 +22,22 @@ void CDecoder::Free() { - MyFree(_parents); _parents = 0; - MyFree(_suffixes); _suffixes = 0; - MyFree(_stack); _stack = 0; + MyFree(_parents); _parents = NULL; + MyFree(_suffixes); _suffixes = NULL; + MyFree(_stack); _stack = NULL; } CDecoder::~CDecoder() { Free(); } -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + ICompressProgressInfo *progress) { + try { + // PackSize = 0; + CInBuffer inBuffer; COutBuffer outBuffer; - PackSize = 0; - if (!inBuffer.Create(kBufferSize)) return E_OUTOFMEMORY; inBuffer.SetStream(inStream); @@ -52,29 +53,29 @@ if (inBuffer.ReadBytes(buf, 3) < 3) return S_FALSE; if (buf[0] != 0x1F || buf[1] != 0x9D) - return S_FALSE;; + return S_FALSE; } - Byte prop = buf[2]; + const Byte prop = buf[2]; if ((prop & 0x60) != 0) return S_FALSE; - unsigned maxbits = prop & kNumBitsMask; + const unsigned maxbits = prop & kNumBitsMask; if (maxbits < kNumMinBits || maxbits > kNumMaxBits) return S_FALSE; - UInt32 numItems = 1 << maxbits; + const UInt32 numItems = (UInt32)1 << maxbits; // Speed optimization: blockSymbol can contain unused velue. - if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0) + if (maxbits != _numMaxBits || !_parents || !_suffixes || !_stack) { Free(); - _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); if (_parents == 0) return E_OUTOFMEMORY; - _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (_suffixes == 0) return E_OUTOFMEMORY; - _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (_stack == 0) return E_OUTOFMEMORY; + _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); if (!_parents) return E_OUTOFMEMORY; + _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (!_suffixes) return E_OUTOFMEMORY; + _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (!_stack) return E_OUTOFMEMORY; _numMaxBits = maxbits; } UInt64 prevPos = 0; - UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + const UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); unsigned numBits = kNumMinBits; UInt32 head = (blockSymbol == 256) ? 257 : 256; bool needPrev = false; @@ -91,18 +92,18 @@ { numBufBits = (unsigned)inBuffer.ReadBytes(buf, numBits) * 8; bitPos = 0; - UInt64 nowPos = outBuffer.GetProcessedSize(); + const UInt64 nowPos = outBuffer.GetProcessedSize(); if (progress && nowPos - prevPos >= (1 << 13)) { prevPos = nowPos; - UInt64 packSize = inBuffer.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + const UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)) } } - unsigned bytePos = bitPos >> 3; + const unsigned bytePos = bitPos >> 3; UInt32 symbol = buf[bytePos] | ((UInt32)buf[(size_t)bytePos + 1] << 8) | ((UInt32)buf[(size_t)bytePos + 2] << 16); symbol >>= (bitPos & 7); - symbol &= (1 << numBits) - 1; + symbol &= ((UInt32)1 << numBits) - 1; bitPos += numBits; if (bitPos > numBufBits) break; @@ -152,34 +153,31 @@ else needPrev = false; } - PackSize = inBuffer.GetProcessedSize(); - HRESULT res2 = outBuffer.Flush(); + // PackSize = inBuffer.GetProcessedSize(); + const HRESULT res2 = outBuffer.Flush(); return (res == S_OK) ? res2 : res; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + + } catch(const CInBufferException &e) { return e.ErrorCode; } catch(const COutBufferException &e) { return e.ErrorCode; } catch(...) { return S_FALSE; } } + bool CheckStream(const Byte *data, size_t size) { if (size < 3) return false; if (data[0] != 0x1F || data[1] != 0x9D) return false; - Byte prop = data[2]; + const Byte prop = data[2]; if ((prop & 0x60) != 0) return false; - unsigned maxbits = prop & kNumBitsMask; + const unsigned maxbits = prop & kNumBitsMask; if (maxbits < kNumMinBits || maxbits > kNumMaxBits) return false; - UInt32 numItems = 1 << maxbits; - UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + const UInt32 numItems = (UInt32)1 << maxbits; + const UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); unsigned numBits = kNumMinBits; UInt32 head = (blockSymbol == 256) ? 257 : 256; unsigned bitPos = 0; @@ -192,17 +190,17 @@ { if (numBufBits == bitPos) { - unsigned num = (numBits < size) ? numBits : (unsigned)size; + const unsigned num = (numBits < size) ? numBits : (unsigned)size; memcpy(buf, data, num); data += num; size -= num; numBufBits = num * 8; bitPos = 0; } - unsigned bytePos = bitPos >> 3; + const unsigned bytePos = bitPos >> 3; UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16); symbol >>= (bitPos & 7); - symbol &= (1 << numBits) - 1; + symbol &= ((UInt32)1 << numBits) - 1; bitPos += numBits; if (bitPos > numBufBits) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZDecoder.h 2013-04-08 03:24:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZDecoder.h 2023-12-19 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZDecoder.h -#ifndef __COMPRESS_Z_DECODER_H -#define __COMPRESS_Z_DECODER_H +#ifndef ZIP7_INC_COMPRESS_Z_DECODER_H +#define ZIP7_INC_COMPRESS_Z_DECODER_H #include "../../Common/MyCom.h" @@ -12,9 +12,7 @@ // Z decoder decodes Z data stream, including 3 bytes of header. -class CDecoder: - public ICompressCoder, - public CMyUnknownImp +class CDecoder { UInt16 *_parents; Byte *_suffixes; @@ -22,18 +20,13 @@ unsigned _numMaxBits; public: - CDecoder(): _parents(0), _suffixes(0), _stack(0), /* _prop(0), */ _numMaxBits(0) {}; + CDecoder(): _parents(NULL), _suffixes(NULL), _stack(NULL), /* _prop(0), */ _numMaxBits(0) {} ~CDecoder(); void Free(); - UInt64 PackSize; + // UInt64 PackSize; - MY_UNKNOWN_IMP1(ICompressCoder) - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + ICompressProgressInfo *progress); }; /* diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibDecoder.cpp 2021-01-22 20:23:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.cpp 2023-12-20 13:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../C/CpuArch.h" + #include "../Common/StreamUtils.h" #include "ZlibDecoder.h" @@ -15,29 +17,45 @@ #define ADLER_MOD 65521 #define ADLER_LOOP_MAX 5550 -UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size); -UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size) +UInt32 Adler32_Update(UInt32 adler, const Byte *data, size_t size); +UInt32 Adler32_Update(UInt32 adler, const Byte *data, size_t size) { - UInt32 a = adler & 0xFFFF; - UInt32 b = (adler >> 16) & 0xFFFF; - while (size > 0) + if (size == 0) + return adler; + UInt32 a = adler & 0xffff; + UInt32 b = adler >> 16; + do { - unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size; - unsigned i; - for (i = 0; i < curSize; i++) + size_t cur = size; + if (cur > ADLER_LOOP_MAX) + cur = ADLER_LOOP_MAX; + size -= cur; + const Byte *lim = data + cur; + if (cur >= 4) { - a += buf[i]; - b += a; + lim -= 4 - 1; + do + { + a += data[0]; b += a; + a += data[1]; b += a; + a += data[2]; b += a; + a += data[3]; b += a; + data += 4; + } + while (data < lim); + lim += 4 - 1; } - buf += curSize; - size -= curSize; + if (data != lim) { a += *data++; b += a; + if (data != lim) { a += *data++; b += a; + if (data != lim) { a += *data++; b += a; }}} a %= ADLER_MOD; b %= ADLER_MOD; } + while (size); return (b << 16) + a; } -STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -49,42 +67,67 @@ return result; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { DEFLATE_TRY_BEGIN - if (!AdlerStream) - AdlerStream = AdlerSpec = new COutStreamWithAdler; - if (!DeflateDecoder) - { - DeflateDecoderSpec = new NDeflate::NDecoder::CCOMCoder; - DeflateDecoderSpec->ZlibMode = true; - DeflateDecoder = DeflateDecoderSpec; - } + _inputProcessedSize_Additional = 0; + AdlerStream.Create_if_Empty(); + DeflateDecoder.Create_if_Empty(); + DeflateDecoder->Set_NeedFinishInput(true); if (inSize && *inSize < 2) return S_FALSE; - Byte buf[2]; - RINOK(ReadStream_FALSE(inStream, buf, 2)); - if (!IsZlib(buf)) - return S_FALSE; - - AdlerSpec->SetStream(outStream); - AdlerSpec->Init(); - + { + Byte buf[2]; + RINOK(ReadStream_FALSE(inStream, buf, 2)) + if (!IsZlib(buf)) + return S_FALSE; + } + _inputProcessedSize_Additional = 2; + AdlerStream->SetStream(outStream); + AdlerStream->Init(); + // NDeflate::NDecoder::Code() ignores inSize + /* UInt64 inSize2 = 0; if (inSize) inSize2 = *inSize - 2; - - HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize ? &inSize2 : NULL, outSize, progress); - AdlerSpec->ReleaseStream(); + */ + const HRESULT res = DeflateDecoder.Interface()->Code(inStream, AdlerStream, + /* inSize ? &inSize2 : */ NULL, outSize, progress); + AdlerStream->ReleaseStream(); if (res == S_OK) { - const Byte *p = DeflateDecoderSpec->ZlibFooter; - UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3]; - if (adler != AdlerSpec->GetAdler()) - return S_FALSE; + UInt32 footer32[1]; + UInt32 processedSize; + RINOK(DeflateDecoder->ReadUnusedFromInBuf(footer32, 4, &processedSize)) + if (processedSize != 4) + { + size_t processedSize2 = 4 - processedSize; + RINOK(ReadStream(inStream, (Byte *)(void *)footer32 + processedSize, &processedSize2)) + _inputProcessedSize_Additional += (Int32)processedSize2; + processedSize += (UInt32)processedSize2; + } + + if (processedSize == 4) + { + const UInt32 adler = GetBe32a(footer32); + if (adler != AdlerStream->GetAdler()) + return S_FALSE; // adler error + } + else if (!IsAdlerOptional) + return S_FALSE; // unexpeced end of stream (can't read adler) + else + { + // IsAdlerOptional == true + if (processedSize != 0) + { + // we exclude adler bytes from processed size: + _inputProcessedSize_Additional -= (Int32)processedSize; + return S_FALSE; + } + } } return res; DEFLATE_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibDecoder.h 2013-09-17 05:50:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibDecoder.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZlibDecoder.h -#ifndef __ZLIB_DECODER_H -#define __ZLIB_DECODER_H +#ifndef ZIP7_INC_ZLIB_DECODER_H +#define ZIP7_INC_ZLIB_DECODER_H #include "DeflateDecoder.h" @@ -10,16 +10,14 @@ const UInt32 ADLER_INIT_VAL = 1; -class COutStreamWithAdler: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithAdler + , ISequentialOutStream +) UInt32 _adler; + CMyComPtr _stream; UInt64 _size; public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init() { _adler = ADLER_INIT_VAL; _size = 0; } @@ -27,23 +25,24 @@ UInt64 GetSize() const { return _size; } }; -class CDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - COutStreamWithAdler *AdlerSpec; - CMyComPtr AdlerStream; - - NCompress::NDeflate::NDecoder::CCOMCoder *DeflateDecoderSpec; - CMyComPtr DeflateDecoder; +Z7_CLASS_IMP_NOQIB_1( + CDecoder + , ICompressCoder +) + CMyComPtr2 AdlerStream; + CMyComPtr2 DeflateDecoder; + Int32 _inputProcessedSize_Additional; public: - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - UInt64 GetInputProcessedSize() const { return DeflateDecoderSpec->GetInputProcessedSize() + 2; } - UInt64 GetOutputProcessedSize() const { return AdlerSpec->GetSize(); } - - MY_UNKNOWN_IMP + bool IsAdlerOptional; + + CDecoder(): IsAdlerOptional(false) {} + UInt64 GetInputProcessedSize() const + { + return (UInt64)( + (Int64)DeflateDecoder->GetInputProcessedSize() + + (Int64)_inputProcessedSize_Additional); + } + UInt64 GetOutputProcessedSize() const { return AdlerStream->GetSize(); } }; static bool inline IsZlib(const Byte *p) @@ -65,8 +64,8 @@ { if (!IsZlib(p)) return false; - unsigned val = p[2]; - unsigned blockType = (val >> 1) & 0x3; + const unsigned val = p[2]; + const unsigned blockType = (val >> 1) & 0x3; if (blockType == 3) // unsupported block type for deflate return false; if (blockType == NCompress::NDeflate::NBlockType::kStored && (val >> 3) != 0) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibEncoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibEncoder.cpp 2009-06-21 13:30:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.cpp 2023-03-28 19:00:00.000000000 +0000 @@ -14,12 +14,12 @@ UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size); -STDMETHODIMP CInStreamWithAdler::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInStreamWithAdler::Read(void *data, UInt32 size, UInt32 *processedSize)) { - HRESULT result = _stream->Read(data, size, &size); + const HRESULT result = _stream->Read(data, size, &size); _adler = Adler32_Update(_adler, (const Byte *)data, size); _size += size; - if (processedSize != NULL) + if (processedSize) *processedSize = size; return result; } @@ -30,8 +30,8 @@ DeflateEncoder = DeflateEncoderSpec = new NDeflate::NEncoder::CCOMCoder; } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { DEFLATE_TRY_BEGIN if (!AdlerStream) @@ -40,19 +40,19 @@ { Byte buf[2] = { 0x78, 0xDA }; - RINOK(WriteStream(outStream, buf, 2)); + RINOK(WriteStream(outStream, buf, 2)) } AdlerSpec->SetStream(inStream); AdlerSpec->Init(); - HRESULT res = DeflateEncoder->Code(AdlerStream, outStream, inSize, NULL, progress); + const HRESULT res = DeflateEncoder->Code(AdlerStream, outStream, inSize, NULL, progress); AdlerSpec->ReleaseStream(); - RINOK(res); + RINOK(res) { - UInt32 a = AdlerSpec->GetAdler(); - Byte buf[4] = { (Byte)(a >> 24), (Byte)(a >> 16), (Byte)(a >> 8), (Byte)(a) }; + const UInt32 a = AdlerSpec->GetAdler(); + const Byte buf[4] = { (Byte)(a >> 24), (Byte)(a >> 16), (Byte)(a >> 8), (Byte)(a) }; return WriteStream(outStream, buf, 4); } DEFLATE_TRY_END diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibEncoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZlibEncoder.h 2009-06-21 13:32:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZlibEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,23 +1,21 @@ // ZlibEncoder.h -#ifndef __ZLIB_ENCODER_H -#define __ZLIB_ENCODER_H +#ifndef ZIP7_INC_ZLIB_ENCODER_H +#define ZIP7_INC_ZLIB_ENCODER_H #include "DeflateEncoder.h" namespace NCompress { namespace NZlib { -class CInStreamWithAdler: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithAdler + , ISequentialInStream +) CMyComPtr _stream; UInt32 _adler; UInt64 _size; public: - MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialInStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init() { _adler = 1; _size = 0; } // ADLER_INIT_VAL @@ -25,10 +23,10 @@ UInt64 GetSize() const { return _size; } }; -class CEncoder: - public ICompressCoder, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CEncoder + , ICompressCoder +) CInStreamWithAdler *AdlerSpec; CMyComPtr AdlerStream; CMyComPtr DeflateEncoder; @@ -36,11 +34,7 @@ NCompress::NDeflate::NEncoder::CCOMCoder *DeflateEncoderSpec; void Create(); - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); UInt64 GetInputProcessedSize() const { return AdlerSpec->GetSize(); } - - MY_UNKNOWN_IMP }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZstdDecoder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.cpp --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZstdDecoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.cpp 2023-08-15 14:00:00.000000000 +0000 @@ -0,0 +1,437 @@ +// ZstdDecoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "ZstdDecoder.h" + +namespace NCompress { +namespace NZstd { + +static const size_t k_Zstd_BlockSizeMax = 1 << 17; +/* + we set _outStepMask as (k_Zstd_BlockSizeMax - 1), because: + - cycSize in zstd decoder for isCyclicMode is aligned for (1 << 17) only. + So some write sizes will be multiple of ((1 << 17) * n). + - Also it can be optimal to flush data after each block decoding. +*/ + +CDecoder::CDecoder(): + _outStepMask(k_Zstd_BlockSizeMax - 1) // must be = (1 << x) - 1 + , _dec(NULL) + , _inProcessed(0) + , _inBufSize(1u << 19) // larger value will reduce the number of memcpy() calls in CZstdDec code + , _inBuf(NULL) + , FinishMode(false) + , DisableHash(False) + // , DisableHash(True) // for debug : fast decoding without hash calculation +{ + // ZstdDecInfo_Clear(&ResInfo); +} + +CDecoder::~CDecoder() +{ + if (_dec) + ZstdDec_Destroy(_dec); + MidFree(_inBuf); +} + + +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) + { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) +{ + // we round it down: + size >>= 1; + size |= size >> (1 << 0); + size |= size >> (1 << 1); + size |= size >> (1 << 2); + size |= size >> (1 << 3); + size |= size >> (1 << 4); + _outStepMask = size; // it's (1 << x) - 1 now + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte * /* prop */, UInt32 /* size */)) +{ + // if (size != 3 && size != 5) return E_NOTIMPL; + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishMode = (finishMode != 0); + // FinishMode = false; // for debug + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t cur = ZstdDec_ReadUnusedFromInBuf(_dec, _afterDecoding_tempPos, data, size); + _afterDecoding_tempPos += cur; + size -= (UInt32)cur; + if (size) + { + const size_t rem = _state.inLim - _state.inPos; + if (size > rem) + size = (UInt32)rem; + if (size) + { + memcpy((Byte *)data + cur, _state.inBuf + _state.inPos, size); + _state.inPos += size; + cur += size; + } + } + *processedSize = (UInt32)cur; + return S_OK; +} + + + +HRESULT CDecoder::Prepare(const UInt64 *outSize) +{ + _inProcessed = 0; + _afterDecoding_tempPos = 0; + ZstdDecState_Clear(&_state); + ZstdDecInfo_CLEAR(&ResInfo) + // _state.outStep = _outStepMask + 1; // must be = (1 << x) + _state.disableHash = DisableHash; + if (outSize) + { + _state.outSize_Defined = True; + _state.outSize = *outSize; + // _state.outSize = 0; // for debug + } + if (!_dec) + { + _dec = ZstdDec_Create(&g_AlignedAlloc, &g_BigAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } + if (!_inBuf || _inBufSize != _inBufSize_Allocated) + { + MidFree(_inBuf); + _inBuf = NULL; + _inBufSize_Allocated = 0; + _inBuf = (Byte *)MidAlloc(_inBufSize); + if (!_inBuf) + return E_OUTOFMEMORY; + _inBufSize_Allocated = _inBufSize; + } + _state.inBuf = _inBuf; + ZstdDec_Init(_dec); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + RINOK(Prepare(outSize)) + + UInt64 inPrev = 0; + UInt64 outPrev = 0; + UInt64 writtenSize = 0; + bool readWasFinished = false; + SRes sres = SZ_OK; + HRESULT hres = S_OK; + HRESULT hres_Read = S_OK; + + for (;;) + { + if (_state.inPos == _state.inLim && !readWasFinished) + { + _state.inPos = 0; + _state.inLim = _inBufSize; + hres_Read = ReadStream(inStream, _inBuf, &_state.inLim); + // _state.inLim -= 5; readWasFinished = True; // for debug + if (_state.inLim != _inBufSize || hres_Read != S_OK) + { + // hres_Read = 99; // for debug + readWasFinished = True; + } + } + { + const size_t inPos_Start = _state.inPos; + sres = ZstdDec_Decode(_dec, &_state); + _inProcessed += _state.inPos - inPos_Start; + } + /* + if (_state.status == ZSTD_STATUS_FINISHED_FRAME) + printf("\nfinished frame pos=%8x, checksum=%08x\n", (unsigned)_state.outProcessed, (unsigned)_state.info.checksum); + */ + const bool needStop = (sres != SZ_OK) + || _state.status == ZSTD_STATUS_OUT_REACHED + || (outSize && *outSize < _state.outProcessed) + || (readWasFinished && _state.inPos == _state.inLim + && ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(&_state)); + + size_t size = _state.winPos - _state.wrPos; // full write size + if (size) + { + if (!needStop) + { + // we try to flush on aligned positions, if possible + size = _state.needWrite_Size; // minimal required write size + const size_t alignedPos = _state.winPos & ~(size_t)_outStepMask; + if (alignedPos > _state.wrPos) + { + const size_t size2 = alignedPos - _state.wrPos; // optimized aligned size + if (size < size2) + size = size2; + } + } + if (size) + { + { + size_t curSize = size; + if (outSize) + { + const UInt64 rem = *outSize - writtenSize; + if (curSize > rem) + curSize = (size_t)rem; + } + if (curSize) + { + // printf("Write wrPos=%8x, size=%8x\n", (unsigned)_state.wrPos, (unsigned)size); + hres = WriteStream(outStream, _state.win + _state.wrPos, curSize); + if (hres != S_OK) + break; + writtenSize += curSize; // it's real size of data that was written to stream + } + } + _state.wrPos += size; // virtual written size, that will be reported to CZstdDec + // _state.needWrite_Size = 0; // optional + } + } + + if (needStop) + break; + if (progress) + if (_inProcessed - inPrev >= (1 << 27) + || _state.outProcessed - outPrev >= (1 << 28)) + { + inPrev = _inProcessed; + outPrev = _state.outProcessed; + RINOK(progress->SetRatioInfo(&inPrev, &outPrev)) + } + } + + if (hres == S_OK) + { + ZstdDec_GetResInfo(_dec, &_state, sres, &ResInfo); + sres = ResInfo.decode_SRes; + /* now (ResInfo.decode_SRes) can contain 2 extra error codes: + - SZ_ERROR_NO_ARCHIVE : if no frames + - SZ_ERROR_INPUT_EOF : if ZSTD_STATUS_NEEDS_MORE_INPUT + */ + _inProcessed -= ResInfo.extraSize; + if (hres_Read != S_OK && _state.inLim == _state.inPos && readWasFinished) + { + /* if (there is stream reading error, + and decoding was stopped because of end of input stream), + then we use reading error as main error code */ + if (sres == SZ_OK || + sres == SZ_ERROR_INPUT_EOF || + sres == SZ_ERROR_NO_ARCHIVE) + hres = hres_Read; + } + if (sres == SZ_ERROR_INPUT_EOF && !FinishMode) + { + /* SZ_ERROR_INPUT_EOF case is allowed case for (!FinishMode) mode. + So we restore SZ_OK result for that case: */ + ResInfo.decode_SRes = sres = SZ_OK; + } + if (hres == S_OK) + { + hres = SResToHRESULT(sres); + if (hres == S_OK && FinishMode) + { + if ((inSize && *inSize != _inProcessed) + || ResInfo.is_NonFinishedFrame + || (outSize && (*outSize != writtenSize || writtenSize != _state.outProcessed))) + hres = S_FALSE; + } + } + } + return hres; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER_ZSTD + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + _inProcessed = 0; + _hres_Read = S_OK; + _hres_Decode = S_OK; + _writtenSize = 0; + _readWasFinished = false; + _wasFinished = false; + return Prepare(outSize); +} + + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + + +// if SetInStream() mode: the caller must call GetFinishResult() after full decoding +// to check that there decoding was finished correctly + +HRESULT CDecoder::GetFinishResult() +{ + if (_state.winPos != _state.wrPos || !_wasFinished) + return FinishMode ? S_FALSE : S_OK; + // _state.winPos == _state.wrPos + // _wasFinished == true + if (FinishMode && _hres_Decode == S_OK && _state.outSize_Defined && _state.outSize != _writtenSize) + _hres_Decode = S_FALSE; + return _hres_Decode; +} + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + for (;;) + { + if (_state.outSize_Defined) + { + // _writtenSize <= _state.outSize + const UInt64 rem = _state.outSize - _writtenSize; + if (size > rem) + size = (UInt32)rem; + } + { + size_t cur = _state.winPos - _state.wrPos; + if (cur) + { + // _state.winPos != _state.wrPos; + // so there is some decoded data that was not written still + if (size == 0) + { + // if (FinishMode) and we are not allowed to write more, then it's data error + if (FinishMode && _state.outSize_Defined && _state.outSize == _writtenSize) + return S_FALSE; + return S_OK; + } + if (cur > size) + cur = (size_t)size; + // cur != 0 + memcpy(data, _state.win + _state.wrPos, cur); + _state.wrPos += cur; + _writtenSize += cur; + data = (void *)((Byte *)data + cur); + if (processedSize) + *processedSize += (UInt32)cur; + size -= (UInt32)cur; + continue; + } + } + + // _state.winPos == _state.wrPos + if (_wasFinished) + { + if (_hres_Decode == S_OK && FinishMode + && _state.outSize_Defined && _state.outSize != _writtenSize) + _hres_Decode = S_FALSE; + return _hres_Decode; + } + + // _wasFinished == false + if (size == 0 && _state.outSize_Defined && _state.outSize != _state.outProcessed) + { + /* size == 0 : so the caller don't need more data now. + _state.outSize > _state.outProcessed : so more data will be requested + later by caller for full processing. + So we exit without ZstdDec_Decode() call, because we don't want + ZstdDec_Decode() to start new block decoding + */ + return S_OK; + } + // size != 0 || !_state.outSize_Defined || _state.outSize == _state.outProcessed) + + if (_state.inPos == _state.inLim && !_readWasFinished) + { + _state.inPos = 0; + _state.inLim = _inBufSize; + _hres_Read = ReadStream(_inStream, _inBuf, &_state.inLim); + if (_state.inLim != _inBufSize || _hres_Read != S_OK) + { + // _hres_Read = 99; // for debug + _readWasFinished = True; + } + } + + SRes sres; + { + const SizeT inPos_Start = _state.inPos; + sres = ZstdDec_Decode(_dec, &_state); + _inProcessed += _state.inPos - inPos_Start; + } + + const bool inFinished = (_state.inPos == _state.inLim) && _readWasFinished; + + _wasFinished = (sres != SZ_OK) + || _state.status == ZSTD_STATUS_OUT_REACHED + || (_state.outSize_Defined && _state.outSize < _state.outProcessed) + || (inFinished + && ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(&_state)); + + if (!_wasFinished) + continue; + + // _wasFinished == true + /* (_state.winPos != _state.wrPos) is possible here. + So we still can have some data to flush, + but we must all result variables . + */ + HRESULT hres = S_OK; + ZstdDec_GetResInfo(_dec, &_state, sres, &ResInfo); + sres = ResInfo.decode_SRes; + _inProcessed -= ResInfo.extraSize; + if (_hres_Read != S_OK && inFinished) + { + if (sres == SZ_OK || + sres == SZ_ERROR_INPUT_EOF || + sres == SZ_ERROR_NO_ARCHIVE) + hres = _hres_Read; + } + if (sres == SZ_ERROR_INPUT_EOF && !FinishMode) + ResInfo.decode_SRes = sres = SZ_OK; + if (hres == S_OK) + { + hres = SResToHRESULT(sres); + if (hres == S_OK && FinishMode) + if (!inFinished + || ResInfo.is_NonFinishedFrame + || (_state.outSize_Defined && _state.outSize != _state.outProcessed)) + hres = S_FALSE; + } + _hres_Decode = hres; + } +} + +#endif + +}} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Compress/ZstdDecoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.h --- 7zip-22.01+dfsg/CPP/7zip/Compress/ZstdDecoder.h 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Compress/ZstdDecoder.h 2023-08-15 10:00:00.000000000 +0000 @@ -0,0 +1,98 @@ +// ZstdDecoder.h + +#ifndef ZIP7_INC_ZSTD_DECODER_H +#define ZIP7_INC_ZSTD_DECODER_H + +#include "../../../C/ZstdDec.h" + +#include "../../Common/MyCom.h" +#include "../ICoder.h" + +namespace NCompress { +namespace NZstd { + +#ifdef Z7_NO_READ_FROM_CODER +#define Z7_NO_READ_FROM_CODER_ZSTD +#endif + +#ifndef Z7_NO_READ_FROM_CODER_ZSTD +// #define Z7_NO_READ_FROM_CODER_ZSTD +#endif + +class CDecoder Z7_final: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressReadUnusedFromInBuf, + public ICompressSetBufSize, + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #endif + + HRESULT Prepare(const UInt64 *outSize); + + UInt32 _outStepMask; + CZstdDecHandle _dec; +public: + UInt64 _inProcessed; + CZstdDecState _state; + +private: + UInt32 _inBufSize; + UInt32 _inBufSize_Allocated; + Byte *_inBuf; + size_t _afterDecoding_tempPos; + + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + CMyComPtr _inStream; + HRESULT _hres_Read; + HRESULT _hres_Decode; + UInt64 _writtenSize; + bool _readWasFinished; + bool _wasFinished; + #endif + +public: + bool FinishMode; + Byte DisableHash; + CZstdDecResInfo ResInfo; + + HRESULT GetFinishResult(); + + CDecoder(); + ~CDecoder(); +}; + +}} + +#endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crc.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc.mak --- 7zip-22.01+dfsg/CPP/7zip/Crc.mak 2018-09-18 10:32:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc.mak 2023-11-09 07:00:00.000000000 +0000 @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\7zCrc.obj -!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +!IF defined(USE_NO_ASM) || defined(USE_C_CRC) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crc64.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc64.mak --- 7zip-22.01+dfsg/CPP/7zip/Crc64.mak 2018-09-18 10:32:45.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crc64.mak 2023-11-11 20:00:00.000000000 +0000 @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\XzCrc64.obj -!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +!IF defined(USE_NO_ASM) || defined(USE_C_CRC64) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAes.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAes.cpp 2021-01-26 11:28:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.cpp 2023-11-29 18:00:00.000000000 +0000 @@ -8,7 +8,7 @@ #include "../../Common/ComTry.h" #include "../../Common/MyBuffer2.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #endif @@ -17,7 +17,7 @@ #include "7zAes.h" #include "MyAes.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "RandGen.h" #endif @@ -58,7 +58,8 @@ // MY_ALIGN (16) // CSha256 sha; - CAlignedBuffer sha(sizeof(CSha256) + unrollSize + bufSize * 2); + const size_t shaAllocSize = sizeof(CSha256) + unrollSize + bufSize * 2; + CAlignedBuffer1 sha(shaAllocSize); Byte *buf = sha + sizeof(CSha256); memcpy(buf, Salt, SaltSize); @@ -86,8 +87,8 @@ r += numUnroll; do { - SetUi32(dest, i); i++; dest += bufSize; - // SetUi32(dest, i); i++; dest += bufSize; + SetUi32(dest, i) i++; dest += bufSize; + // SetUi32(dest, i) i++; dest += bufSize; } while (i < r); Sha256_Update((CSha256 *)(void *)(Byte *)sha, buf, unrollSize); @@ -108,7 +109,7 @@ */ Sha256_Final((CSha256 *)(void *)(Byte *)sha, Key); - memset(sha, 0, sha.Size()); + memset(sha, 0, shaAllocSize); } } @@ -153,7 +154,7 @@ static CKeyInfoCache g_GlobalKeyCache(32); -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); #else @@ -185,10 +186,10 @@ g_GlobalKeyCache.FindAndAdd(_key); } -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY /* -STDMETHODIMP CEncoder::ResetSalt() +Z7_COM7F_IMF(CEncoder::ResetSalt()) { _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); @@ -196,7 +197,7 @@ } */ -STDMETHODIMP CEncoder::ResetInitVector() +Z7_COM7F_IMF(CEncoder::ResetInitVector()) { for (unsigned i = 0; i < sizeof(_iv); i++) _iv[i] = 0; @@ -205,7 +206,7 @@ return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)]; unsigned propsSize = 1; @@ -243,7 +244,7 @@ _aesFilter = new CAesCbcDecoder(kKeySize); } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) { _key.ClearProps(); @@ -255,19 +256,16 @@ if (size == 0) return S_OK; - Byte b0 = data[0]; - + const unsigned b0 = data[0]; _key.NumCyclesPower = b0 & 0x3F; if ((b0 & 0xC0) == 0) return size == 1 ? S_OK : E_INVALIDARG; - if (size <= 1) return E_INVALIDARG; - Byte b1 = data[1]; - - unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4); - unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F); + const unsigned b1 = data[1]; + const unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4); + const unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F); if (size != 2 + saltSize + ivSize) return E_INVALIDARG; @@ -282,7 +280,7 @@ } -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)) { COM_TRY_BEGIN @@ -293,23 +291,23 @@ COM_TRY_END } -STDMETHODIMP CBaseCoder::Init() +Z7_COM7F_IMF(CBaseCoder::Init()) { COM_TRY_BEGIN PrepareKey(); CMyComPtr cp; - RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)) if (!cp) return E_FAIL; - RINOK(cp->SetKey(_key.Key, kKeySize)); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + RINOK(cp->SetKey(_key.Key, kKeySize)) + RINOK(cp->SetInitVector(_iv, sizeof(_iv))) return _aesFilter->Init(); COM_TRY_END } -STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CBaseCoder::Filter(Byte *data, UInt32 size)) { return _aesFilter->Filter(data, size); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAes.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAes.h 2019-10-11 10:50:54.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAes.h 2023-05-04 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zAes.h -#ifndef __CRYPTO_7Z_AES_H -#define __CRYPTO_7Z_AES_H +#ifndef ZIP7_INC_CRYPTO_7Z_AES_H +#define ZIP7_INC_CRYPTO_7Z_AES_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -43,10 +43,13 @@ Password.Wipe(); NumCyclesPower = 0; SaltSize = 0; - MY_memset_0_ARRAY(Salt); - MY_memset_0_ARRAY(Key); + Z7_memset_0_ARRAY(Salt); + Z7_memset_0_ARRAY(Key); } +#ifdef Z7_CPP_IS_SUPPORTED_default + CKeyInfo(const CKeyInfo &) = default; +#endif ~CKeyInfo() { Wipe(); } }; @@ -79,48 +82,46 @@ public CMyUnknownImp, public CBase { + Z7_IFACE_COM7_IMP(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoSetPassword) protected: + virtual ~CBaseCoder() {} CMyComPtr _aesFilter; - -public: - INTERFACE_ICompressFilter(;) - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public CBaseCoder, public ICompressWriteCoderProperties, // public ICryptoResetSalt, public ICryptoResetInitVector { -public: - MY_UNKNOWN_IMP4( + Z7_COM_UNKNOWN_IMP_4( ICompressFilter, ICryptoSetPassword, ICompressWriteCoderProperties, // ICryptoResetSalt, ICryptoResetInitVector) - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) +public: CEncoder(); }; #endif -class CDecoder: +class CDecoder Z7_final: public CBaseCoder, public ICompressSetDecoderProperties2 { -public: - MY_UNKNOWN_IMP3( + Z7_COM_UNKNOWN_IMP_3( ICompressFilter, ICryptoSetPassword, ICompressSetDecoderProperties2) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +public: CDecoder(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAesRegister.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAesRegister.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/7zAesRegister.cpp 2019-03-28 11:33:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/7zAesRegister.cpp 2022-12-19 22:00:00.000000000 +0000 @@ -9,7 +9,7 @@ namespace NCrypto { namespace N7z { -REGISTER_FILTER_E(_7zAES, +REGISTER_FILTER_E(SzAES, CDecoder, CEncoder, 0x6F10701, "7zAES") diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha1.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha1.cpp 2019-08-29 11:23:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include + #include "../../../C/CpuArch.h" #include "HmacSha1.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha1.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha1.h 2019-08-29 12:24:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha1.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,8 +1,8 @@ // HmacSha1.h // Implements HMAC-SHA-1 (RFC2104, FIPS-198) -#ifndef __CRYPTO_HMAC_SHA1_H -#define __CRYPTO_HMAC_SHA1_H +#ifndef ZIP7_INC_CRYPTO_HMAC_SHA1_H +#define ZIP7_INC_CRYPTO_HMAC_SHA1_H #include "Sha1Cls.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha256.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha256.cpp 2019-08-29 11:32:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include + #include "../../../C/CpuArch.h" #include "HmacSha256.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha256.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/HmacSha256.h 2019-08-29 11:32:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/HmacSha256.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,8 +1,8 @@ // HmacSha256.h // Implements HMAC-SHA-256 (RFC2104, FIPS-198) -#ifndef __CRYPTO_HMAC_SHA256_H -#define __CRYPTO_HMAC_SHA256_H +#ifndef ZIP7_INC_CRYPTO_HMAC_SHA256_H +#define ZIP7_INC_CRYPTO_HMAC_SHA256_H #include "../../../C/Sha256.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAes.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAes.cpp 2021-03-29 17:56:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.cpp 2024-12-10 08:00:00.000000000 +0000 @@ -10,11 +10,16 @@ static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; -CAesCoder::CAesCoder(bool encodeMode, unsigned keySize, bool ctrMode): - _keySize(keySize), +CAesCoder::CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ): _keyIsSet(false), - _encodeMode(encodeMode), - _ctrMode(ctrMode), + // _encodeMode(encodeMode), + // _ctrMode(ctrMode), + _keySize(keySize), + // _ctrPos(0), // _ctrPos =0 will be set in Init() _aes(AES_NUM_IVMRK_WORDS * 4 + AES_BLOCK_SIZE * 2) { // _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); @@ -24,170 +29,237 @@ for (unsigned i = 0; i < 16; i++) _iv[i] = (Byte)(i + 1); _iv[0] = 0xFE; _iv[1] = _iv[2] = _iv[3] = 0xFF; */ - SetFunctions(0); } -STDMETHODIMP CAesCoder::Init() +Z7_COM7F_IMF(CAesCoder::Init()) { + _ctrPos = 0; AesCbc_Init(Aes(), _iv); return _keyIsSet ? S_OK : E_NOTIMPL; // E_FAIL } -STDMETHODIMP_(UInt32) CAesCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CAesCoder::Filter(Byte *data, UInt32 size)) { if (!_keyIsSet) return 0; - if (size == 0) - return 0; if (size < AES_BLOCK_SIZE) { - #ifndef _SFX - if (_ctrMode) - { - // use that code only for last block !!! - Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); - memset(ctr, 0, AES_BLOCK_SIZE); - memcpy(ctr, data, size); - _codeFunc(Aes(), ctr, 1); - memcpy(data, ctr, size); - return size; - } - #endif + if (size == 0) + return 0; return AES_BLOCK_SIZE; } size >>= 4; + // (data) must be aligned for 16-bytes here _codeFunc(Aes(), data, size); return size << 4; } -STDMETHODIMP CAesCoder::SetKey(const Byte *data, UInt32 size) + +Z7_COM7F_IMF(CAesCoder::SetKey(const Byte *data, UInt32 size)) { if ((size & 0x7) != 0 || size < 16 || size > 32) return E_INVALIDARG; if (_keySize != 0 && size != _keySize) return E_INVALIDARG; - AES_SET_KEY_FUNC setKeyFunc = (_ctrMode | _encodeMode) ? Aes_SetKey_Enc : Aes_SetKey_Dec; - setKeyFunc(Aes() + 4, data, size); + _setKeyFunc(Aes() + 4, data, size); _keyIsSet = true; return S_OK; } -STDMETHODIMP CAesCoder::SetInitVector(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CAesCoder::SetInitVector(const Byte *data, UInt32 size)) { if (size != AES_BLOCK_SIZE) return E_INVALIDARG; memcpy(_iv, data, size); + /* we allow SetInitVector() call before SetKey() call. + so we ignore possible error in Init() here */ CAesCoder::Init(); // don't call virtual function here !!! return S_OK; } -#ifndef _SFX -#ifdef MY_CPU_X86_OR_AMD64 - #define USE_HW_AES -#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define USE_HW_AES - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_AES - #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_AES - #endif - #endif -#endif - -#endif +#ifndef Z7_SFX +/* +Z7_COM7F_IMF(CAesCtrCoder::Init()) +{ + _ctrPos = 0; + return CAesCoder::Init(); +} +*/ -bool CAesCoder::SetFunctions(UInt32 - #ifndef _SFX - algo - #endif - ) +Z7_COM7F_IMF2(UInt32, CAesCtrCoder::Filter(Byte *data, UInt32 size)) { - _codeFunc = g_AesCbc_Decode; + if (!_keyIsSet) + return 0; + if (size == 0) + return 0; + + if (_ctrPos != 0) + { + /* Optimized caller will not call here */ + const Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + unsigned num = 0; + for (unsigned i = _ctrPos; i != AES_BLOCK_SIZE; i++) + { + if (num == size) + { + _ctrPos = i; + return num; + } + data[num++] ^= ctr[i]; + } + _ctrPos = 0; + /* if (num < size) { + we can filter more data with _codeFunc(). + But it's supposed that the caller can work correctly, + even if we do only partial filtering here. + So we filter data only for current 16-byte block. } + */ + /* + size -= num; + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data + num, size); + return num + (size << 4); + */ + return num; + } + + if (size < AES_BLOCK_SIZE) + { + /* The good optimized caller can call here only in last Filter() call. + But we support also non-optimized callers, + where another Filter() calls are allowed after this call. + */ + Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + memset(ctr, 0, AES_BLOCK_SIZE); + memcpy(ctr, data, size); + _codeFunc(Aes(), ctr, 1); + memcpy(data, ctr, size); + _ctrPos = size; + return size; + } + + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data, size); + return size << 4; +} - #ifdef _SFX +#endif // Z7_SFX - return true; - #else - - if (_ctrMode) - _codeFunc = g_AesCtr_Code; - else if (_encodeMode) - _codeFunc = g_AesCbc_Encode; +#ifndef Z7_EXTRACT_ONLY - if (algo < 1) - return true; +#ifdef MY_CPU_X86_OR_AMD64 - if (algo == 1) - { - _codeFunc = AesCbc_Decode; - - #ifndef _SFX - if (_ctrMode) - _codeFunc = AesCtr_Code; - else if (_encodeMode) - _codeFunc = AesCbc_Encode; + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) + #define USE_HW_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_HW_VAES + #endif #endif - return true; - } - - #ifdef USE_HW_AES - // if (CPU_IsSupported_AES()) - { - if (algo == 2) - if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW) - { - _codeFunc = AesCbc_Decode_HW; - #ifndef _SFX - if (_ctrMode) - _codeFunc = AesCtr_Code_HW; - else if (_encodeMode) - _codeFunc = AesCbc_Encode_HW; + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_HW_AES + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_HW_VAES #endif - return true; - } + #elif defined(_MSC_VER) + #define USE_HW_AES + #define USE_HW_VAES + #endif - #if defined(MY_CPU_X86_OR_AMD64) - if (algo == 3) - if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256) - { - _codeFunc = AesCbc_Decode_HW_256; - #ifndef _SFX - if (_ctrMode) - _codeFunc = AesCtr_Code_HW_256; - else if (_encodeMode) - _codeFunc = AesCbc_Encode_HW; - #endif - return true; - } +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_AES + #endif + #endif #endif - } #endif +#endif - return false; +#ifdef USE_HW_AES +// #pragma message("=== MyAES.c USE_HW_AES === ") - #endif -} + #define SET_AES_FUNC_2(f2) \ + if (algo == 2) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW) \ + { f = f2; } + #ifdef USE_HW_VAES + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) \ + if (algo == 3) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256) \ + { f = f3; } + #else // USE_HW_VAES + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) + #endif // USE_HW_VAES +#else // USE_HW_AES + #define SET_AES_FUNC_23(f2, f3) +#endif // USE_HW_AES + +#define SET_AES_FUNCS(c, f0, f1, f2, f3) \ + bool c::SetFunctions(UInt32 algo) { \ + _codeFunc = f0; if (algo < 1) return true; \ + AES_CODE_FUNC f = NULL; \ + if (algo == 1) { f = f1; } \ + SET_AES_FUNC_23(f2, f3) \ + if (f) { _codeFunc = f; return true; } \ + return false; } -#ifndef _SFX -STDMETHODIMP CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +#ifndef Z7_SFX +SET_AES_FUNCS( + CAesCtrCoder, + g_AesCtr_Code, + AesCtr_Code, + AesCtr_Code_HW, + AesCtr_Code_HW_256) +#endif + +SET_AES_FUNCS( + CAesCbcEncoder, + g_AesCbc_Encode, + AesCbc_Encode, + AesCbc_Encode_HW, + AesCbc_Encode_HW) + +SET_AES_FUNCS( + CAesCbcDecoder, + g_AesCbc_Decode, + AesCbc_Decode, + AesCbc_Decode_HW, + AesCbc_Decode_HW_256) + +Z7_COM7F_IMF(CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { UInt32 algo = 0; for (UInt32 i = 0; i < numProps; i++) { - const PROPVARIANT &prop = coderProps[i]; if (propIDs[i] == NCoderPropID::kDefaultProp) { + const PROPVARIANT &prop = coderProps[i]; if (prop.vt != VT_UI4) return E_INVALIDARG; if (prop.ulVal > 3) @@ -200,6 +272,6 @@ return S_OK; } -#endif +#endif // Z7_EXTRACT_ONLY } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAes.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAes.h 2021-01-26 11:24:50.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/MyAes.h -#ifndef __CRYPTO_MY_AES_H -#define __CRYPTO_MY_AES_H +#ifndef ZIP7_INC_CRYPTO_MY_AES_H +#define ZIP7_INC_CRYPTO_MY_AES_H #include "../../../C/Aes.h" @@ -12,68 +12,111 @@ namespace NCrypto { +#ifdef Z7_EXTRACT_ONLY +#define Z7_IFACEN_IAesCoderSetFunctions(x) +#else +#define Z7_IFACEN_IAesCoderSetFunctions(x) \ + virtual bool SetFunctions(UInt32 algo) x +#endif + + class CAesCoder: public ICompressFilter, public ICryptoProperties, - #ifndef _SFX + #ifndef Z7_EXTRACT_ONLY public ICompressSetCoderProperties, - #endif + #endif public CMyUnknownImp { - AES_CODE_FUNC _codeFunc; + Z7_COM_QI_BEGIN2(ICompressFilter) + Z7_COM_QI_ENTRY(ICryptoProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(ICompressSetCoderProperties) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + +public: + Z7_IFACE_COM7_IMP_NONFINAL(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoProperties) +private: + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + #endif + +protected: + bool _keyIsSet; + // bool _encodeMode; + // bool _ctrMode; // unsigned _offset; unsigned _keySize; - bool _keyIsSet; - bool _encodeMode; - bool _ctrMode; - + unsigned _ctrPos; // we need _ctrPos here for Init() / SetInitVector() + AES_CODE_FUNC _codeFunc; + AES_SET_KEY_FUNC _setKeyFunc; +private: // UInt32 _aes[AES_NUM_IVMRK_WORDS + 3]; - CAlignedBuffer _aes; + CAlignedBuffer1 _aes; Byte _iv[AES_BLOCK_SIZE]; // UInt32 *Aes() { return _aes + _offset; } +protected: UInt32 *Aes() { return (UInt32 *)(void *)(Byte *)_aes; } - bool SetFunctions(UInt32 algo); + Z7_IFACE_PURE(IAesCoderSetFunctions) public: - CAesCoder(bool encodeMode, unsigned keySize, bool ctrMode); - - virtual ~CAesCoder() {}; // we need virtual destructor for derived classes - - MY_QUERYINTERFACE_BEGIN2(ICompressFilter) - MY_QUERYINTERFACE_ENTRY(ICryptoProperties) - #ifndef _SFX - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_ICompressFilter(;) - + CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ); + virtual ~CAesCoder() {} // we need virtual destructor for derived classes void SetKeySize(unsigned size) { _keySize = size; } - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); - - #ifndef _SFX - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - #endif }; -#ifndef _SFX + +#ifndef Z7_EXTRACT_ONLY struct CAesCbcEncoder: public CAesCoder { - CAesCbcEncoder(unsigned keySize = 0): CAesCoder(true, keySize, false) {} + CAesCbcEncoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCbc_Encode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) }; #endif struct CAesCbcDecoder: public CAesCoder { - CAesCbcDecoder(unsigned keySize = 0): CAesCoder(false, keySize, false) {} + CAesCbcDecoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Dec; + _codeFunc = g_AesCbc_Decode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) }; +#ifndef Z7_SFX +struct CAesCtrCoder: public CAesCoder +{ +private: + // unsigned _ctrPos; + // Z7_IFACE_COM7_IMP(ICompressFilter) + // Z7_COM7F_IMP(Init()) + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + CAesCtrCoder(unsigned keySize = 0): CAesCoder(keySize) + { + _ctrPos = 0; + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCtr_Code; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) +}; +#endif + } #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAesReg.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAesReg.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/MyAesReg.cpp 2019-09-02 11:11:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/MyAesReg.cpp 2023-04-02 10:00:00.000000000 +0000 @@ -8,22 +8,21 @@ namespace NCrypto { -#ifndef _SFX +#ifndef Z7_SFX -#define REGISTER_AES_2(name, nameString, keySize, isCtr) \ +#define REGISTER_AES_2(name, nameString, keySize) \ REGISTER_FILTER_E(name, \ - CAesCoder(false, keySize, isCtr), \ - CAesCoder(true , keySize, isCtr), \ - 0x6F00100 | ((keySize - 16) * 8) | (isCtr ? 4 : 1), \ + CAesCbcDecoder(keySize), \ + CAesCbcEncoder(keySize), \ + 0x6F00100 | ((keySize - 16) * 8) | (/* isCtr */ 0 ? 4 : 1), \ nameString) \ -#define REGISTER_AES(name, nameString, isCtr) \ - /* REGISTER_AES_2(AES128 ## name, "AES128" nameString, 16, isCtr) */ \ - /* REGISTER_AES_2(AES192 ## name, "AES192" nameString, 24, isCtr) */ \ - REGISTER_AES_2(AES256 ## name, "AES256" nameString, 32, isCtr) \ +#define REGISTER_AES(name, nameString) \ + /* REGISTER_AES_2(AES128 ## name, "AES128" nameString, 16) */ \ + /* REGISTER_AES_2(AES192 ## name, "AES192" nameString, 24) */ \ + REGISTER_AES_2(AES256 ## name, "AES256" nameString, 32) \ -REGISTER_AES(CBC, "CBC", false) -// REGISTER_AES(CTR, "CTR", true) +REGISTER_AES(CBC, "CBC") #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp 2021-01-22 20:17:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include + #include "../../../C/CpuArch.h" #include "HmacSha1.h" @@ -28,7 +30,7 @@ MY_ALIGN (16) UInt32 u[kNumDigestWords]; - SetBe32(u, i); + SetBe32(u, i) ctx.Update((const Byte *)u, 4); ctx.Final((Byte *)u); @@ -36,7 +38,7 @@ ctx = baseCtx; ctx.GetLoopXorDigest1((void *)u, numIterations - 1); - const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize;; + const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize; memcpy(key, (const Byte *)u, curSize); key += curSize; keySize -= curSize; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.h 2019-03-13 17:35:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Pbkdf2HmacSha1.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,8 +1,8 @@ // Pbkdf2HmacSha1.h // Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1 -#ifndef __CRYPTO_PBKDF2_HMAC_SHA1_H -#define __CRYPTO_PBKDF2_HMAC_SHA1_H +#ifndef ZIP7_INC_CRYPTO_PBKDF2_HMAC_SHA1_H +#define ZIP7_INC_CRYPTO_PBKDF2_HMAC_SHA1_H #include diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/RandGen.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/RandGen.cpp 2021-04-01 11:43:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.cpp 2023-03-24 20:10:00.000000000 +0000 @@ -6,7 +6,7 @@ #ifndef USE_STATIC_SYSTEM_RAND -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #endif @@ -76,9 +76,9 @@ #ifdef _WIN32 DWORD w = ::GetCurrentProcessId(); - HASH_UPD(w); + HASH_UPD(w) w = ::GetCurrentThreadId(); - HASH_UPD(w); + HASH_UPD(w) #ifdef UNDER_CE /* @@ -96,11 +96,14 @@ } #else { - HMODULE hModule = ::LoadLibrary(TEXT("Advapi32.dll")); + const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); if (hModule) { // SystemFunction036() is real name of RtlGenRandom() function - Func_RtlGenRandom my_RtlGenRandom = (Func_RtlGenRandom)(void *)GetProcAddress(hModule, "SystemFunction036"); + const + Func_RtlGenRandom + my_RtlGenRandom = Z7_GET_PROC_ADDRESS( + Func_RtlGenRandom, hModule, "SystemFunction036"); if (my_RtlGenRandom) { if (my_RtlGenRandom(buf, kBufSize)) @@ -117,9 +120,9 @@ #else pid_t pid = getpid(); - HASH_UPD(pid); + HASH_UPD(pid) pid = getppid(); - HASH_UPD(pid); + HASH_UPD(pid) { int f = open("/dev/urandom", O_RDONLY); @@ -164,25 +167,25 @@ #ifdef _WIN32 LARGE_INTEGER v; if (::QueryPerformanceCounter(&v)) - HASH_UPD(v.QuadPart); + HASH_UPD(v.QuadPart) #endif #ifdef USE_POSIX_TIME #ifdef USE_POSIX_TIME2 timeval v; - if (gettimeofday(&v, 0) == 0) + if (gettimeofday(&v, NULL) == 0) { - HASH_UPD(v.tv_sec); - HASH_UPD(v.tv_usec); + HASH_UPD(v.tv_sec) + HASH_UPD(v.tv_usec) } #endif - time_t v2 = time(NULL); - HASH_UPD(v2); + const time_t v2 = time(NULL); + HASH_UPD(v2) #endif #ifdef _WIN32 - DWORD tickCount = ::GetTickCount(); - HASH_UPD(tickCount); + const DWORD tickCount = ::GetTickCount(); + HASH_UPD(tickCount) #endif for (unsigned j = 0; j < 100; j++) @@ -198,7 +201,7 @@ _needInit = false; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -222,7 +225,7 @@ Sha256_Init(&hash); UInt32 salt = 0xF672ABD1; - HASH_UPD(salt); + HASH_UPD(salt) Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); MY_ALIGN (16) Byte buff[SHA256_DIGEST_SIZE]; @@ -232,6 +235,7 @@ } } +MY_ALIGN (16) CRandomGenerator g_RandomGenerator; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/RandGen.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/RandGen.h 2019-02-20 08:52:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RandGen.h 2023-04-11 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RandGen.h -#ifndef __CRYPTO_RAND_GEN_H -#define __CRYPTO_RAND_GEN_H +#ifndef ZIP7_INC_CRYPTO_RAND_GEN_H +#define ZIP7_INC_CRYPTO_RAND_GEN_H #include "../../../C/Sha256.h" @@ -27,10 +27,11 @@ void Init(); public: - CRandomGenerator(): _needInit(true) {}; + CRandomGenerator(): _needInit(true) {} void Generate(Byte *data, unsigned size); }; +MY_ALIGN (16) extern CRandomGenerator g_RandomGenerator; #define MY_RAND_GEN(data, size) g_RandomGenerator.Generate(data, size) diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.cpp 2019-10-10 15:10:58.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.cpp 2023-03-07 07:00:00.000000000 +0000 @@ -54,7 +54,7 @@ Keys[3] = 0xA4E7F123L; Byte psw[128]; - MY_memset_0_ARRAY(psw); + Z7_memset_0_ARRAY(psw); if (size != 0) { if (size >= sizeof(psw)) @@ -99,22 +99,22 @@ B = D; D = TB; } - SetUi32(buf + 0, C ^ Keys[0]); - SetUi32(buf + 4, D ^ Keys[1]); - SetUi32(buf + 8, A ^ Keys[2]); - SetUi32(buf + 12, B ^ Keys[3]); + SetUi32(buf + 0, C ^ Keys[0]) + SetUi32(buf + 4, D ^ Keys[1]) + SetUi32(buf + 8, A ^ Keys[2]) + SetUi32(buf + 12, B ^ Keys[3]) UpdateKeys(encrypt ? buf : inBuf); } -STDMETHODIMP CDecoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { return S_OK; } static const UInt32 kBlockSize = 16; -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) { if (size == 0) return 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.h 2019-10-11 10:48:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar20Crypto.h 2023-03-07 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/Rar20Crypto.h -#ifndef __CRYPTO_RAR20_CRYPTO_H -#define __CRYPTO_RAR20_CRYPTO_H +#ifndef ZIP7_INC_CRYPTO_RAR20_CRYPTO_H +#define ZIP7_INC_CRYPTO_RAR20_CRYPTO_H #include "../../Common/MyCom.h" @@ -31,8 +31,8 @@ ~CData() { Wipe(); } void Wipe() { - MY_memset_0_ARRAY(SubstTable); - MY_memset_0_ARRAY(Keys); + Z7_memset_0_ARRAY(SubstTable); + Z7_memset_0_ARRAY(Keys); } void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } @@ -40,14 +40,13 @@ void SetPassword(const Byte *password, unsigned passwordLen); }; -class CDecoder: +class CDecoder Z7_final: public ICompressFilter, public CMyUnknownImp, public CData { -public: - MY_UNKNOWN_IMP - INTERFACE_ICompressFilter(;) + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ICompressFilter) }; }} diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar5Aes.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar5Aes.cpp 2019-10-10 15:07:49.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.cpp 2024-11-19 09:00:00.000000000 +0000 @@ -4,20 +4,21 @@ #include "../../../C/CpuArch.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #endif -#include "Rar5Aes.h" #include "HmacSha256.h" +#include "Rar5Aes.h" + +#define MY_ALIGN_FOR_SHA256 MY_ALIGN(16) namespace NCrypto { namespace NRar5 { static const unsigned kNumIterationsLog_Max = 24; - -static const unsigned kPswCheckCsumSize = 4; -static const unsigned kCheckSize = kPswCheckSize + kPswCheckCsumSize; +static const unsigned kPswCheckCsumSize32 = 1; +static const unsigned kCheckSize32 = kPswCheckSize32 + kPswCheckCsumSize32; CKey::CKey(): _needCalc(true), @@ -27,15 +28,29 @@ _salt[i] = 0; } +CKey::~CKey() +{ + Wipe(); +} + +void CKey::Wipe() +{ + _password.Wipe(); + Z7_memset_0_ARRAY(_salt); + // Z7_memset_0_ARRAY(_key32); + // Z7_memset_0_ARRAY(_check_Calced32); + // Z7_memset_0_ARRAY(_hashKey32); + CKeyBase::Wipe(); +} + CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) { *val = 0; - for (unsigned i = 0; i < maxSize && i < 10;) { - Byte b = p[i]; + const Byte b = p[i]; *val |= (UInt64)(b & 0x7F) << (7 * i); i++; if ((b & 0x80) == 0) @@ -64,7 +79,7 @@ size -= num; bool isCheck = IsThereCheck(); - if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize : 0)) + if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize32 * 4 : 0)) return E_NOTIMPL; if (_numIterationsLog != p[0]) @@ -93,19 +108,21 @@ if (isCheck) { - memcpy(_check, p, kPswCheckSize); + memcpy(_check32, p, sizeof(_check32)); + MY_ALIGN_FOR_SHA256 CSha256 sha; + MY_ALIGN_FOR_SHA256 Byte digest[SHA256_DIGEST_SIZE]; Sha256_Init(&sha); - Sha256_Update(&sha, _check, kPswCheckSize); + Sha256_Update(&sha, (const Byte *)_check32, sizeof(_check32)); Sha256_Final(&sha, digest); - _canCheck = (memcmp(digest, p + kPswCheckSize, kPswCheckCsumSize) == 0); + _canCheck = (memcmp(digest, p + sizeof(_check32), kPswCheckCsumSize32 * 4) == 0); if (_canCheck && isService) { // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros. // so we disable password checking for such bad records. _canCheck = false; - for (unsigned i = 0; i < kPswCheckSize; i++) + for (unsigned i = 0; i < kPswCheckSize32 * 4; i++) if (p[i] != 0) { _canCheck = true; @@ -129,46 +146,46 @@ } -STDMETHODIMP CDecoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { CalcKey_and_CheckPassword(); - RINOK(SetKey(_key, kAesKeySize)); - RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)); + RINOK(SetKey((const Byte *)_key32, kAesKeySize)) + RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) return CAesCoder::Init(); } UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const { - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); UInt32 v; - SetUi32(&v, crc); + SetUi32a(&v, crc) ctx.Update((const Byte *)&v, 4); - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 UInt32 h[SHA256_NUM_DIGEST_WORDS]; ctx.Final((Byte *)h); crc = 0; for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++) - crc ^= (UInt32)GetUi32(h + i); + crc ^= (UInt32)GetUi32a(h + i); return crc; -}; +} void CDecoder::Hmac_Convert_32Bytes(Byte *data) const { - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); ctx.Update(data, NSha256::kDigestSize); ctx.Final(data); -}; +} static CKey g_Key; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); #else @@ -190,30 +207,31 @@ if (_needCalc) { - Byte pswCheck[SHA256_DIGEST_SIZE]; - + MY_ALIGN_FOR_SHA256 + UInt32 pswCheck[SHA256_NUM_DIGEST_WORDS]; { // Pbkdf HMAC-SHA-256 - - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac baseCtx; baseCtx.SetKey(_password, _password.Size()); - - NSha256::CHmac ctx = baseCtx; + MY_ALIGN_FOR_SHA256 + NSha256::CHmac ctx; + ctx = baseCtx; ctx.Update(_salt, sizeof(_salt)); - MY_ALIGN (16) - Byte u[NSha256::kDigestSize]; - MY_ALIGN (16) - Byte key[NSha256::kDigestSize]; + MY_ALIGN_FOR_SHA256 + UInt32 u[SHA256_NUM_DIGEST_WORDS]; + MY_ALIGN_FOR_SHA256 + UInt32 key[SHA256_NUM_DIGEST_WORDS]; - u[0] = 0; - u[1] = 0; - u[2] = 0; - u[3] = 1; + // u[0] = 0; + // u[1] = 0; + // u[2] = 0; + // u[3] = 1; + SetUi32a(u, 0x1000000) - ctx.Update(u, 4); - ctx.Final(u); + ctx.Update((const Byte *)(const void *)u, 4); + ctx.Final((Byte *)(void *)u); memcpy(key, u, NSha256::kDigestSize); @@ -221,35 +239,24 @@ for (unsigned i = 0; i < 3; i++) { - UInt32 j = numIterations; - - for (; j != 0; j--) + for (; numIterations != 0; numIterations--) { ctx = baseCtx; - ctx.Update(u, NSha256::kDigestSize); - ctx.Final(u); - for (unsigned s = 0; s < NSha256::kDigestSize; s++) + ctx.Update((const Byte *)(const void *)u, NSha256::kDigestSize); + ctx.Final((Byte *)(void *)u); + for (unsigned s = 0; s < Z7_ARRAY_SIZE(u); s++) key[s] ^= u[s]; } // RAR uses additional iterations for additional keys - memcpy((i == 0 ? _key : (i == 1 ? _hashKey : pswCheck)), key, NSha256::kDigestSize); + memcpy(i == 0 ? _key32 : i == 1 ? _hashKey32 : pswCheck, + key, NSha256::kDigestSize); numIterations = 16; } } - - { - unsigned i; - - for (i = 0; i < kPswCheckSize; i++) - _check_Calced[i] = pswCheck[i]; - - for (i = kPswCheckSize; i < SHA256_DIGEST_SIZE; i++) - _check_Calced[i & (kPswCheckSize - 1)] ^= pswCheck[i]; - } - + _check_Calced32[0] = pswCheck[0] ^ pswCheck[2] ^ pswCheck[4] ^ pswCheck[6]; + _check_Calced32[1] = pswCheck[1] ^ pswCheck[3] ^ pswCheck[5] ^ pswCheck[7]; _needCalc = false; - { MT_LOCK g_Key = *this; @@ -258,7 +265,7 @@ } if (IsThereCheck() && _canCheck) - return (memcmp(_check_Calced, _check, kPswCheckSize) == 0); + return memcmp(_check_Calced32, _check32, sizeof(_check32)) == 0; return true; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar5Aes.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Rar5Aes.h 2019-10-11 10:52:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Rar5Aes.h 2024-11-19 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/Rar5Aes.h -#ifndef __CRYPTO_RAR5_AES_H -#define __CRYPTO_RAR5_AES_H +#ifndef ZIP7_INC_CRYPTO_RAR5_AES_H +#define ZIP7_INC_CRYPTO_RAR5_AES_H #include "../../../C/Sha256.h" @@ -13,7 +13,7 @@ namespace NRar5 { const unsigned kSaltSize = 16; -const unsigned kPswCheckSize = 8; +const unsigned kPswCheckSize32 = 2; const unsigned kAesKeySize = 32; namespace NCryptoFlags @@ -22,62 +22,65 @@ const unsigned kUseMAC = 1 << 1; } -struct CKey +struct CKeyBase { - bool _needCalc; +protected: + UInt32 _key32[kAesKeySize / 4]; + UInt32 _hashKey32[SHA256_NUM_DIGEST_WORDS]; + UInt32 _check_Calced32[kPswCheckSize32]; - unsigned _numIterationsLog; - Byte _salt[kSaltSize]; - CByteBuffer _password; + void Wipe() + { + memset(this, 0, sizeof(*this)); + } - Byte _key[kAesKeySize]; - Byte _check_Calced[kPswCheckSize]; - Byte _hashKey[SHA256_DIGEST_SIZE]; - - void CopyCalcedKeysFrom(const CKey &k) + void CopyCalcedKeysFrom(const CKeyBase &k) { - memcpy(_key, k._key, sizeof(_key)); - memcpy(_check_Calced, k._check_Calced, sizeof(_check_Calced)); - memcpy(_hashKey, k._hashKey, sizeof(_hashKey)); + *this = k; } +}; +struct CKey: public CKeyBase +{ + CByteBuffer _password; + bool _needCalc; + unsigned _numIterationsLog; + Byte _salt[kSaltSize]; + bool IsKeyEqualTo(const CKey &key) { - return (_numIterationsLog == key._numIterationsLog + return _numIterationsLog == key._numIterationsLog && memcmp(_salt, key._salt, sizeof(_salt)) == 0 - && _password == key._password); + && _password == key._password; } - - CKey(); - void Wipe() - { - _password.Wipe(); - MY_memset_0_ARRAY(_salt); - MY_memset_0_ARRAY(_key); - MY_memset_0_ARRAY(_check_Calced); - MY_memset_0_ARRAY(_hashKey); - } + CKey(); + ~CKey(); + + void Wipe(); - ~CKey() { Wipe(); } +#ifdef Z7_CPP_IS_SUPPORTED_default + // CKey(const CKey &) = default; + CKey& operator =(const CKey &) = default; +#endif }; -class CDecoder: +class CDecoder Z7_final: public CAesCbcDecoder, public CKey { - Byte _check[kPswCheckSize]; + UInt32 _check32[kPswCheckSize32]; bool _canCheck; UInt64 Flags; - bool IsThereCheck() const { return ((Flags & NCryptoFlags::kPswCheck) != 0); } + bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; } public: Byte _iv[AES_BLOCK_SIZE]; CDecoder(); - STDMETHOD(Init)(); + Z7_COM7F_IMP(Init()) void SetPassword(const Byte *data, size_t size); HRESULT SetDecoderProps(const Byte *data, unsigned size, bool includeIV, bool isService); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/RarAes.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/RarAes.cpp 2019-10-10 11:37:52.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.cpp 2024-11-18 18:00:00.000000000 +0000 @@ -78,11 +78,11 @@ _password.CopyFrom(data, (size_t)size); } -STDMETHODIMP CDecoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { CalcKey(); - RINOK(SetKey(_key, kAesKeySize)); - RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)); + RINOK(SetKey(_key, kAesKeySize)) + RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) return CAesCoder::Init(); } @@ -111,12 +111,13 @@ for (i = 16; i < 80; i++) { - WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1); + const UInt32 t = WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16); + WW(i) = rotlFixed(t, 1); } for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) { - SetUi32(data + i * 4, W[kNumW - SHA1_NUM_BLOCK_WORDS + i]); + SetUi32(data + i * 4, W[kNumW - SHA1_NUM_BLOCK_WORDS + i]) } } @@ -128,6 +129,7 @@ const unsigned kSaltSize = 8; + MY_ALIGN (16) Byte buf[kPasswordLen_Bytes_MAX + kSaltSize]; if (_password.Size() != 0) @@ -148,7 +150,7 @@ MY_ALIGN (16) Byte digest[NSha1::kDigestSize]; // rar reverts hash for sha. - const UInt32 kNumRounds = ((UInt32)1 << 18); + const UInt32 kNumRounds = (UInt32)1 << 18; UInt32 pos = 0; UInt32 i; for (i = 0; i < kNumRounds; i++) @@ -171,8 +173,14 @@ } } pos += (UInt32)rawSize; +#if 1 + UInt32 pswNum; + SetUi32a(&pswNum, i) + sha.Update((const Byte *)&pswNum, 3); +#else Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; sha.Update(pswNum, 3); +#endif pos += 3; if (i % (kNumRounds / 16) == 0) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/RarAes.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/RarAes.h 2019-10-10 15:09:27.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/RarAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/RarAes.h -#ifndef __CRYPTO_RAR_AES_H -#define __CRYPTO_RAR_AES_H +#ifndef ZIP7_INC_CRYPTO_RAR_AES_H +#define ZIP7_INC_CRYPTO_RAR_AES_H #include "../../../C/Aes.h" @@ -16,10 +16,8 @@ const unsigned kAesKeySize = 16; -class CDecoder: +class CDecoder Z7_final: public CAesCbcDecoder - // public ICompressSetDecoderProperties2, - // public ICryptoSetPassword { Byte _salt[8]; bool _thereIsSalt; @@ -33,25 +31,20 @@ void CalcKey(); public: - /* - MY_UNKNOWN_IMP1( - ICryptoSetPassword - // ICompressSetDecoderProperties2 - */ - STDMETHOD(Init)(); + Z7_COM7F_IMP(Init()) void SetPassword(const Byte *data, unsigned size); HRESULT SetDecoderProperties2(const Byte *data, UInt32 size); CDecoder(); - ~CDecoder() { Wipe(); } + ~CDecoder() Z7_DESTRUCTOR_override { Wipe(); } void Wipe() { _password.Wipe(); - MY_memset_0_ARRAY(_salt); - MY_memset_0_ARRAY(_key); - MY_memset_0_ARRAY(_iv); + Z7_memset_0_ARRAY(_salt); + Z7_memset_0_ARRAY(_key); + Z7_memset_0_ARRAY(_iv); } // void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/Sha1Cls.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Sha1Cls.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/Sha1Cls.h 2020-10-02 10:23:23.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/Sha1Cls.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/Sha1Cls.h -#ifndef __CRYPTO_SHA1_CLS_H -#define __CRYPTO_SHA1_CLS_H +#ifndef ZIP7_INC_CRYPTO_SHA1_CLS_H +#define ZIP7_INC_CRYPTO_SHA1_CLS_H #include "../../../C/Sha1.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/StdAfx.h 2013-11-27 10:12:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/WzAes.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/WzAes.cpp 2021-01-25 18:49:19.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.cpp 2023-04-02 10:00:00.000000000 +0000 @@ -23,7 +23,7 @@ static const UInt32 kNumKeyGenIterations = 1000; -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)) { if (size > kPasswordSizeMax) return E_INVALIDARG; @@ -34,6 +34,7 @@ void CBaseCoder::Init2() { + _hmacOverCalc = 0; const unsigned dkSizeMax32 = (2 * kAesKeySizeMax + kPwdVerifSize + 3) / 4; Byte dk[dkSizeMax32 * 4]; @@ -59,7 +60,7 @@ if (_aesCoderSpec->Init() != S_OK) throw 3; } -STDMETHODIMP CBaseCoder::Init() +Z7_COM7F_IMF(CBaseCoder::Init()) { return S_OK; } @@ -69,7 +70,7 @@ unsigned saltSize = _key.GetSaltSize(); MY_RAND_GEN(_key.Salt, saltSize); Init2(); - RINOK(WriteStream(outStream, _key.Salt, saltSize)); + RINOK(WriteStream(outStream, _key.Salt, saltSize)) return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifSize); } @@ -82,7 +83,7 @@ } /* -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) { if (size != 1) return E_INVALIDARG; @@ -93,10 +94,10 @@ HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) { - unsigned saltSize = _key.GetSaltSize(); - unsigned extraSize = saltSize + kPwdVerifSize; + const unsigned saltSize = _key.GetSaltSize(); + const unsigned extraSize = saltSize + kPwdVerifSize; Byte temp[kSaltSizeMax + kPwdVerifSize]; - RINOK(ReadStream_FAIL(inStream, temp, extraSize)); + RINOK(ReadStream_FAIL(inStream, temp, extraSize)) unsigned i; for (i = 0; i < saltSize; i++) _key.Salt[i] = temp[i]; @@ -124,11 +125,13 @@ isOK = false; MY_ALIGN (16) Byte mac1[kMacSize]; - RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)); + RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)) MY_ALIGN (16) UInt32 mac2[NSha1::kNumDigestWords]; Hmac()->Final((Byte *)mac2); isOK = CompareArrays(mac1, (const Byte *)mac2, kMacSize); + if (_hmacOverCalc) + isOK = false; return S_OK; } @@ -202,7 +205,7 @@ /* (size != 16 * N) is allowed only for last Filter() call */ -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) { // AesCtr2_Code(&_aes, data, size); size = _aesCoder->Filter(data, size); @@ -210,14 +213,18 @@ return size; } -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) { if (size >= 16) size &= ~(UInt32)15; - - Hmac()->Update(data, size); + if (_hmacOverCalc < size) + { + Hmac()->Update(data + _hmacOverCalc, size - _hmacOverCalc); + _hmacOverCalc = size; + } // AesCtr2_Code(&_aes, data, size); size = _aesCoder->Filter(data, size); + _hmacOverCalc -= size; return size; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/WzAes.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/WzAes.h 2021-01-26 11:35:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/WzAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -9,8 +9,8 @@ - 2 bytes contain Password Verifier's Code */ -#ifndef __CRYPTO_WZ_AES_H -#define __CRYPTO_WZ_AES_H +#ifndef ZIP7_INC_CRYPTO_WZ_AES_H +#define ZIP7_INC_CRYPTO_WZ_AES_H #include "../../Common/MyBuffer.h" @@ -65,8 +65,8 @@ void Wipe() { Password.Wipe(); - MY_memset_0_ARRAY(Salt); - MY_memset_0_ARRAY(PwdVerifComputed); + Z7_memset_0_ARRAY(Salt); + Z7_memset_0_ARRAY(PwdVerifComputed); } ~CKeyInfo() { Wipe(); } @@ -94,12 +94,18 @@ public ICryptoSetPassword, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_1(ICryptoSetPassword) + Z7_COM7F_IMP(Init()) +public: + Z7_IFACE_COM7_IMP(ICryptoSetPassword) protected: CKeyInfo _key; // NSha1::CHmac _hmac; // NSha1::CHmac *Hmac() { return &_hmac; } - CAlignedBuffer _hmacBuf; + CAlignedBuffer1 _hmacBuf; + UInt32 _hmacOverCalc; + NSha1::CHmac *Hmac() { return (NSha1::CHmac *)(void *)(Byte *)_hmacBuf; } // CAesCtr2 _aes; @@ -108,18 +114,12 @@ CBaseCoder(): _hmacBuf(sizeof(NSha1::CHmac)) { - _aesCoderSpec = new CAesCoder(true, 32, true); - _aesCoder = _aesCoderSpec; + _aesCoderSpec = new CAesCtrCoder(32); + _aesCoder = _aesCoderSpec; } void Init2(); public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(Init)(); - unsigned GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifSize; } unsigned GetAddPackSize() const { return GetHeaderSize() + kMacSize; } @@ -134,24 +134,23 @@ virtual ~CBaseCoder() {} }; -class CEncoder: +class CEncoder Z7_final: public CBaseCoder { + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) public: - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); HRESULT WriteHeader(ISequentialOutStream *outStream); HRESULT WriteFooter(ISequentialOutStream *outStream); }; -class CDecoder: +class CDecoder Z7_final: public CBaseCoder // public ICompressSetDecoderProperties2 { Byte _pwdVerifFromArchive[kPwdVerifSize]; + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) public: - // ICompressSetDecoderProperties2 - // STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + // Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) HRESULT ReadHeader(ISequentialInStream *inStream); bool Init_and_CheckPassword(); HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipCrypto.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipCrypto.cpp 2019-02-10 10:41:44.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.cpp 2023-02-01 09:00:00.000000000 +0000 @@ -20,14 +20,14 @@ #define DECRYPT_BYTE_1 UInt32 temp = key2 | 2; #define DECRYPT_BYTE_2 ((Byte)((temp * (temp ^ 1)) >> 8)) -STDMETHODIMP CCipher::CryptoSetPassword(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CCipher::CryptoSetPassword(const Byte *data, UInt32 size)) { UInt32 key0 = 0x12345678; UInt32 key1 = 0x23456789; UInt32 key2 = 0x34567890; for (UInt32 i = 0; i < size; i++) - UPDATE_KEYS(data[i]); + UPDATE_KEYS(data[i]) KeyMem0 = key0; KeyMem1 = key1; @@ -36,7 +36,7 @@ return S_OK; } -STDMETHODIMP CCipher::Init() +Z7_COM7F_IMF(CCipher::Init()) { return S_OK; } @@ -58,7 +58,7 @@ return WriteStream(outStream, h, kHeaderSize); } -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) { UInt32 key0 = this->Key0; UInt32 key1 = this->Key1; @@ -69,7 +69,7 @@ Byte b = data[i]; DECRYPT_BYTE_1 data[i] = (Byte)(b ^ DECRYPT_BYTE_2); - UPDATE_KEYS(b); + UPDATE_KEYS(b) } this->Key0 = key0; @@ -90,7 +90,7 @@ Filter(_header, kHeaderSize); } -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) { UInt32 key0 = this->Key0; UInt32 key1 = this->Key1; @@ -100,7 +100,7 @@ { DECRYPT_BYTE_1 Byte b = (Byte)(data[i] ^ DECRYPT_BYTE_2); - UPDATE_KEYS(b); + UPDATE_KEYS(b) data[i] = b; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipCrypto.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipCrypto.h 2019-10-03 17:50:31.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipCrypto.h 2023-02-01 15:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/ZipCrypto.h -#ifndef __CRYPTO_ZIP_CRYPTO_H -#define __CRYPTO_ZIP_CRYPTO_H +#ifndef ZIP7_INC_CRYPTO_ZIP_CRYPTO_H +#define ZIP7_INC_CRYPTO_ZIP_CRYPTO_H #include "../../Common/MyCom.h" @@ -30,6 +30,10 @@ public ICryptoSetPassword, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_1(ICryptoSetPassword) + Z7_COM7F_IMP(Init()) +public: + Z7_IFACE_COM7_IMP(ICryptoSetPassword) protected: UInt32 Key0; UInt32 Key1; @@ -47,10 +51,6 @@ } public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) - STDMETHOD(Init)(); - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - virtual ~CCipher() { Key0 = KeyMem0 = @@ -59,18 +59,18 @@ } }; -class CEncoder: public CCipher +class CEncoder Z7_final: public CCipher { + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) public: - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); HRESULT WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc); }; -class CDecoder: public CCipher +class CDecoder Z7_final: public CCipher { + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) public: Byte _header[kHeaderSize]; - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); HRESULT ReadHeader(ISequentialInStream *inStream); void Init_BeforeDecode(); }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipStrong.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.cpp --- 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipStrong.cpp 2021-04-01 10:01:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.cpp 2024-11-19 10:00:00.000000000 +0000 @@ -24,30 +24,31 @@ if (method != AES && method != 3DES), probably we need another code. */ -static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) +static void DeriveKey2(const UInt32 *digest32, Byte c, UInt32 *dest32) { + const unsigned kBufSize = 64; MY_ALIGN (16) - Byte buf[64]; - memset(buf, c, 64); - for (unsigned i = 0; i < NSha1::kDigestSize; i++) - buf[i] ^= digest[i]; + UInt32 buf32[kBufSize / 4]; + memset(buf32, c, kBufSize); + for (unsigned i = 0; i < NSha1::kNumDigestWords; i++) + buf32[i] ^= digest32[i]; MY_ALIGN (16) NSha1::CContext sha; sha.Init(); - sha.Update(buf, 64); - sha.Final(dest); + sha.Update((const Byte *)buf32, kBufSize); + sha.Final((Byte *)dest32); } static void DeriveKey(NSha1::CContext &sha, Byte *key) { MY_ALIGN (16) - Byte digest[NSha1::kDigestSize]; - sha.Final(digest); + UInt32 digest32[NSha1::kNumDigestWords]; + sha.Final((Byte *)digest32); MY_ALIGN (16) - Byte temp[NSha1::kDigestSize * 2]; - DeriveKey2(digest, 0x36, temp); - DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); - memcpy(key, temp, 32); + UInt32 temp32[NSha1::kNumDigestWords * 2]; + DeriveKey2(digest32, 0x36, temp32); + DeriveKey2(digest32, 0x5C, temp32 + NSha1::kNumDigestWords); + memcpy(key, temp32, 32); } void CKeyInfo::SetPassword(const Byte *data, UInt32 size) @@ -59,36 +60,51 @@ DeriveKey(sha, MasterKey); } -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) + + +CDecoder::CDecoder() +{ + CAesCbcDecoder *d = new CAesCbcDecoder(); + _cbcDecoder = d; + _aesFilter = d; +} + +Z7_COM7F_IMF(CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)) { _key.SetPassword(data, size); return S_OK; } -STDMETHODIMP CBaseCoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { return S_OK; } +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + return _aesFilter->Filter(data, size); +} + + HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize) { Byte temp[4]; - RINOK(ReadStream_FALSE(inStream, temp, 2)); + RINOK(ReadStream_FALSE(inStream, temp, 2)) _ivSize = GetUi16(temp); if (_ivSize == 0) { memset(_iv, 0, 16); - SetUi32(_iv + 0, crc); - SetUi64(_iv + 4, unpackSize); + SetUi32(_iv + 0, crc) + SetUi64(_iv + 4, unpackSize) _ivSize = 12; } else if (_ivSize == 16) { - RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)); + RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)) } else return E_NOTIMPL; - RINOK(ReadStream_FALSE(inStream, temp, 4)); + RINOK(ReadStream_FALSE(inStream, temp, 4)) _remSize = GetUi32(temp); // const UInt32 kAlign = 16; if (_remSize < 16 || _remSize > (1 << 18)) @@ -107,24 +123,24 @@ passwOK = false; if (_remSize < 16) return E_NOTIMPL; - Byte *p = _bufAligned; - const unsigned format = GetUi16(p); + Byte * const p = _bufAligned; + const unsigned format = GetUi16a(p); if (format != 3) return E_NOTIMPL; - unsigned algId = GetUi16(p + 2); + unsigned algId = GetUi16a(p + 2); if (algId < kAES128) return E_NOTIMPL; algId -= kAES128; if (algId > 2) return E_NOTIMPL; - const unsigned bitLen = GetUi16(p + 4); - const unsigned flags = GetUi16(p + 6); + const unsigned bitLen = GetUi16a(p + 4); + const unsigned flags = GetUi16a(p + 6); if (algId * 64 + 128 != bitLen) return E_NOTIMPL; _key.KeySize = 16 + algId * 8; const bool cert = ((flags & 2) != 0); - if ((flags & 0x4000) != 0) + if (flags & 0x4000) { // Use 3DES for rd data return E_NOTIMPL; @@ -140,7 +156,7 @@ return E_NOTIMPL; } - UInt32 rdSize = GetUi16(p + 8); + UInt32 rdSize = GetUi16a(p + 8); if (rdSize + 16 > _remSize) return E_NOTIMPL; @@ -159,7 +175,7 @@ // PKCS7 padding if (rdSize < kPadSize) return E_NOTIMPL; - if ((rdSize & (kPadSize - 1)) != 0) + if (rdSize & (kPadSize - 1)) return E_NOTIMPL; } @@ -208,9 +224,10 @@ return E_NOTIMPL; { - RINOK(SetKey(_key.MasterKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - RINOK(Init()); + RINOK(_cbcDecoder->SetKey(_key.MasterKey, _key.KeySize)) + RINOK(_cbcDecoder->SetInitVector(_iv, 16)) + // SetInitVector() calls also Init() + RINOK(_cbcDecoder->Init()) // it's optional Filter(p, rdSize); rdSize -= kPadSize; @@ -228,9 +245,10 @@ sha.Update(p, rdSize); DeriveKey(sha, fileKey); - RINOK(SetKey(fileKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - Init(); + RINOK(_cbcDecoder->SetKey(fileKey, _key.KeySize)) + RINOK(_cbcDecoder->SetInitVector(_iv, 16)) + // SetInitVector() calls also Init() + RINOK(_cbcDecoder->Init()) // it's optional memmove(p, p + validOffset, validSize); Filter(p, validSize); diff -Nru 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipStrong.h 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.h --- 7zip-22.01+dfsg/CPP/7zip/Crypto/ZipStrong.h 2019-10-11 10:49:27.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Crypto/ZipStrong.h 2023-04-02 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Crypto/ZipStrong.h -#ifndef __CRYPTO_ZIP_STRONG_H -#define __CRYPTO_ZIP_STRONG_H +#ifndef ZIP7_INC_CRYPTO_ZIP_STRONG_H +#define ZIP7_INC_CRYPTO_ZIP_STRONG_H #include "../../Common/MyBuffer2.h" @@ -28,34 +28,29 @@ void SetPassword(const Byte *data, UInt32 size); - ~CKeyInfo() { Wipe(); } void Wipe() { - MY_memset_0_ARRAY(MasterKey); + Z7_memset_0_ARRAY(MasterKey); } }; -class CBaseCoder: - public CAesCbcDecoder, - public ICryptoSetPassword -{ -protected: - CKeyInfo _key; - CAlignedBuffer _bufAligned; -public: - STDMETHOD(Init)(); - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); -}; const unsigned kAesPadAllign = AES_BLOCK_SIZE; -class CDecoder: public CBaseCoder -{ +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressFilter + , ICryptoSetPassword +) + CAesCbcDecoder *_cbcDecoder; + CMyComPtr _aesFilter; + CKeyInfo _key; + CAlignedBuffer _bufAligned; + UInt32 _ivSize; Byte _iv[16]; UInt32 _remSize; public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize); HRESULT Init_and_CheckPassword(bool &passwOK); UInt32 GetPadSize(UInt32 packSize32) const @@ -64,11 +59,12 @@ // Change it, if is not AES return kAesPadAllign - (packSize32 & (kAesPadAllign - 1)); } - + CDecoder(); ~CDecoder() { Wipe(); } void Wipe() { - MY_memset_0_ARRAY(_iv); + Z7_memset_0_ARRAY(_iv); + _key.Wipe(); } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/GuiCommon.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/GuiCommon.rc --- 7zip-22.01+dfsg/CPP/7zip/GuiCommon.rc 2018-03-19 15:26:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/GuiCommon.rc 2024-11-13 18:00:00.000000000 +0000 @@ -54,31 +54,66 @@ #define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU - #define MY_MODAL_RESIZE_DIALOG_STYLE MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX | WS_THICKFRAME #define MY_PAGE_STYLE STYLE WS_CHILD | WS_DISABLED | WS_CAPTION #define MY_FONT FONT 8, "MS Shell Dlg" +#define MY_MODAL_DIALOG_POSTFIX 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT + #define SMALL_PAGE_SIZE_X 120 // #define MY_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT // #define MY_RESIZE_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT -#define MY_PAGE DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT +#define MY_PAGE_POSTFIX 0, 0, xs, ys MY_PAGE_STYLE MY_FONT +#define MY_PAGE DIALOG MY_PAGE_POSTFIX #define OK_CANCEL \ DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +#define CONTINUE_CANCEL \ + DEFPUSHBUTTON "Continue",IDCONTINUE, bx2, by, bxs, bys \ + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + #define MY_BUTTON__CLOSE \ DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys #define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP #define MY_COMBO_SORTED MY_COMBO | CBS_SORT -#define MY_COMBO_WITH_EDIT CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP +#define MY_COMBO_WITH_EDIT CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP #define MY_CHECKBOX "Button", BS_AUTOCHECKBOX | WS_TABSTOP +#define cboxColonSize 18 +#define colonString ":" + +#define MY_CONTROL_CHECKBOX(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_CHECKBOX, _x,_y,_xsize,10 +#define MY_CONTROL_CHECKBOX_2LINES(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_CHECKBOX | BS_MULTILINE, _x,_y,_xsize,16 +#define MY_CONTROL_CHECKBOX_COLON(_id,_x,_y) MY_CONTROL_CHECKBOX( colonString, _id, _x,_y,cboxColonSize) + +#define MY_AUTORADIOBUTTON "Button", BS_AUTORADIOBUTTON +#define MY_AUTORADIOBUTTON_GROUP MY_AUTORADIOBUTTON | WS_GROUP + +#define MY_CONTROL_AUTORADIOBUTTON(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_AUTORADIOBUTTON, _x,_y,_xsize,10 +#define MY_CONTROL_AUTORADIOBUTTON_GROUP(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_AUTORADIOBUTTON_GROUP, _x,_y,_xsize,10 + #define MY_TEXT_NOPREFIX 8, SS_NOPREFIX + + +// WS_EX_CLIENTEDGE +#define MY_CONTROL_EDIT_WITH_SPIN(_id_edit, _id_spin, _text, _x, _y, _xSize) \ + EDITTEXT _id_edit, _x, _y, _xSize, 12, ES_CENTER | ES_NUMBER | ES_AUTOHSCROLL \ + CONTROL _text, _id_spin, L"msctls_updown32", \ + UDS_SETBUDDYINT \ + | UDS_ALIGNRIGHT \ + | UDS_AUTOBUDDY \ + | UDS_ARROWKEYS \ + | UDS_NOTHOUSANDS, \ + _x + _xSize, _y, 8, 12 // these values are unused + + +#define OPTIONS_PAGE_XC_SIZE 300 +#define OPTIONS_PAGE_YC_SIZE 280 diff -Nru 7zip-22.01+dfsg/CPP/7zip/Guid.txt 7zip-22.01+really25.01+dfsg/CPP/7zip/Guid.txt --- 7zip-22.01+dfsg/CPP/7zip/Guid.txt 2022-06-06 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Guid.txt 2024-10-18 08:00:00.000000000 +0000 @@ -20,6 +20,8 @@ 10 IFolderArchiveUpdateCallback2 11 IFolderScanProgress 12 IFolderSetZoneIdMode + 13 IFolderSetZoneIdFile + 14 IFolderArchiveUpdateCallback_MoveArc 20 IFileExtractCallback.h::IGetProp 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old) @@ -31,12 +33,15 @@ 02 ISequentialOutStream 03 IInStream 04 IOutStream + 06 IStreamGetSize 07 IOutStreamFinish 08 IStreamGetProps 09 IStreamGetProps2 0A IStreamGetProp + 10 IStreamSetRestriction + 04 ICoder.h @@ -91,10 +96,13 @@ 04 IArchiveKeepModeForNextOpen 05 IArchiveAllowTail + 09 IArchiveRequestMemoryUseCallback + 10 IArchiveOpenCallback 20 IArchiveExtractCallback - 21 IArchiveExtractCallbackMessage + 21 IArchiveExtractCallbackMessage (deprecated in v23) + 22 IArchiveExtractCallbackMessage2 (new in v23) 30 IArchiveOpenVolumeCallback 40 IInArchiveGetStream @@ -172,7 +180,9 @@ 0B lzma86 0C xz 0D ppmd + 0E zstd + BF LVM C0 AVB C1 LP C2 Sparse diff -Nru 7zip-22.01+dfsg/CPP/7zip/ICoder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/ICoder.h --- 7zip-22.01+dfsg/CPP/7zip/ICoder.h 2021-08-05 07:18:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/ICoder.h 2024-12-14 19:00:00.000000000 +0000 @@ -1,39 +1,40 @@ // ICoder.h -#ifndef __ICODER_H -#define __ICODER_H +#ifndef ZIP7_INC_ICODER_H +#define ZIP7_INC_ICODER_H #include "IStream.h" -#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x) +Z7_PURE_INTERFACES_BEGIN -CODER_INTERFACE(ICompressProgressInfo, 0x04) -{ - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; - - /* (inSize) can be NULL, if unknown +#define Z7_IFACE_CONSTR_CODER(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 4, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACEM_ICompressProgressInfo(x) \ + x(SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressProgressInfo, 0x04) + /* + SetRatioInfo() + (inSize) can be NULL, if unknown (outSize) can be NULL, if unknown - returns: S_OK E_ABORT : Break by user another error codes */ -}; -CODER_INTERFACE(ICompressCoder, 0x05) -{ - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) PURE; -}; - -CODER_INTERFACE(ICompressCoder2, 0x18) -{ - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) PURE; -}; +#define Z7_IFACEM_ICompressCoder(x) \ + x(Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, \ + const UInt64 *inSize, const UInt64 *outSize, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder, 0x05) + +#define Z7_IFACEM_ICompressCoder2(x) \ + x(Code(ISequentialInStream * const *inStreams, const UInt64 *const *inSizes, UInt32 numInStreams, \ + ISequentialOutStream *const *outStreams, const UInt64 *const *outSizes, UInt32 numOutStreams, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder2, 0x18) /* ICompressCoder::Code @@ -54,7 +55,7 @@ { Encoders in 7-Zip ignore (inSize). Decoder can use (*inSize) to check that stream was decoded correctly. - Some decoder in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) + Some decoders in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) } If it's required to limit the reading from input stream (inStream), it can @@ -132,71 +133,94 @@ kCheckSize, // VT_UI4 : size of digest in bytes kFilter, // VT_BSTR kMemUse, // VT_UI8 - kAffinity // VT_UI8 + kAffinity, // VT_UI8 + kBranchOffset, // VT_UI4 + kHashBits, // VT_UI4 + kNumThreadGroups, // VT_UI4 + kThreadGroup, // VT_UI4 + kAffinityInGroup, // VT_UI8 + /* + // kHash3Bits, // VT_UI4 + // kHash2Bits, // VT_UI4 + // kChainBits, // VT_UI4 + kChainSize, // VT_UI4 + kNativeLevel, // VT_UI4 + kFast, // VT_UI4 + kMinMatch, // VT_UI4 The minimum slen is 3 and the maximum is 7. + kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6) + kRowMatchFinder, // VT_BOOL + kLdmEnable, // VT_BOOL + // kLdmWindowSizeLog, // VT_UI4 + kLdmWindowSize, // VT_UI4 + kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20). + kLdmMinMatchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64). + kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3). + kLdmHashRateLog, // VT_UI4 The default value is wlog - ldmhlog. + kWriteUnpackSizeFlag, // VT_BOOL + kUsePledged, // VT_BOOL + kUseSizeHintPledgedForSmall, // VT_BOOL + kUseSizeHintForEach, // VT_BOOL + kUseSizeHintGlobal, // VT_BOOL + kParamSelectMode, // VT_UI4 + // kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26 + // kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999. + */ + k_NUM_DEFINED }; } -CODER_INTERFACE(ICompressSetCoderPropertiesOpt, 0x1F) -{ - STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE; -}; +#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \ + x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F) -CODER_INTERFACE(ICompressSetCoderProperties, 0x20) -{ - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE; -}; + +#define Z7_IFACEM_ICompressSetCoderProperties(x) \ + x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20) /* -CODER_INTERFACE(ICompressSetCoderProperties, 0x21) -{ - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; -}; +#define Z7_IFACEM_ICompressSetDecoderProperties(x) \ + x(SetDecoderProperties(ISequentialInStream *inStream)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21) */ -CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) -{ +#define Z7_IFACEM_ICompressSetDecoderProperties2(x) \ + x(SetDecoderProperties2(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties2, 0x22) /* returns: S_OK E_NOTIMP : unsupported properties E_INVALIDARG : incorrect (or unsupported) properties E_OUTOFMEMORY : memory allocation error */ - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) -{ - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE; -}; - -CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) -{ - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; -}; - -CODER_INTERFACE(ICompressSetCoderMt, 0x25) -{ - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; -}; -CODER_INTERFACE(ICompressSetFinishMode, 0x26) -{ - STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE; +#define Z7_IFACEM_ICompressWriteCoderProperties(x) \ + x(WriteCoderProperties(ISequentialOutStream *outStream)) +Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23) + +#define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \ + x(GetInStreamProcessedSize(UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24) + +#define Z7_IFACEM_ICompressSetCoderMt(x) \ + x(SetNumberOfThreads(UInt32 numThreads)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25) + +#define Z7_IFACEM_ICompressSetFinishMode(x) \ + x(SetFinishMode(UInt32 finishMode)) +Z7_IFACE_CONSTR_CODER(ICompressSetFinishMode, 0x26) /* finishMode: 0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined. 1 : full decoding. The stream must be finished at the end of decoding. */ -}; -CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27) -{ - STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE; -}; - -CODER_INTERFACE(ICompressSetMemLimit, 0x28) -{ - STDMETHOD(SetMemLimit)(UInt64 memUsage) PURE; -}; +#define Z7_IFACEM_ICompressGetInStreamProcessedSize2(x) \ + x(GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27) + +#define Z7_IFACEM_ICompressSetMemLimit(x) \ + x(SetMemLimit(UInt64 memUsage)) +Z7_IFACE_CONSTR_CODER(ICompressSetMemLimit, 0x28) /* @@ -208,23 +232,18 @@ data from the internal buffer. in ReadUnusedFromInBuf(): the Coder is not allowed to use (ISequentialInStream *inStream) object, that was sent to ICoder::Code(). */ +#define Z7_IFACEM_ICompressReadUnusedFromInBuf(x) \ + x(ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29) -CODER_INTERFACE(ICompressReadUnusedFromInBuf, 0x29) -{ - STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize) PURE; -}; - - - -CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) -{ - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +#define Z7_IFACEM_ICompressGetSubStreamSize(x) \ + x(GetSubStreamSize(UInt64 subStream, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetSubStreamSize, 0x30) /* returns: S_OK : (*value) contains the size or estimated size (can be incorrect size) S_FALSE : size is undefined E_NOTIMP : the feature is not implemented - Let's (read_size) is size of data that was already read by ISequentialInStream::Read(). The caller should call GetSubStreamSize() after each Read() and check sizes: if (start_of_subStream + *value < read_size) @@ -234,74 +253,74 @@ subStream++; } */ -}; - -CODER_INTERFACE(ICompressSetInStream, 0x31) -{ - STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream)() PURE; -}; -CODER_INTERFACE(ICompressSetOutStream, 0x32) -{ - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream)() PURE; -}; +#define Z7_IFACEM_ICompressSetInStream(x) \ + x(SetInStream(ISequentialInStream *inStream)) \ + x(ReleaseInStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31) + +#define Z7_IFACEM_ICompressSetOutStream(x) \ + x(SetOutStream(ISequentialOutStream *outStream)) \ + x(ReleaseOutStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32) /* -CODER_INTERFACE(ICompressSetInStreamSize, 0x33) -{ - STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; -}; +#define Z7_IFACEM_ICompressSetInStreamSize(x) \ + x(SetInStreamSize(const UInt64 *inSize)) \ +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33) */ -CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) -{ - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; - +#define Z7_IFACEM_ICompressSetOutStreamSize(x) \ + x(SetOutStreamSize(const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStreamSize, 0x34) /* That function initializes decoder structures. Call this function only for stream version of decoder. if (outSize == NULL), then output size is unknown if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */ -}; - -CODER_INTERFACE(ICompressSetBufSize, 0x35) -{ - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE; - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICompressInitEncoder, 0x36) -{ - STDMETHOD(InitEncoder)() PURE; +#define Z7_IFACEM_ICompressSetBufSize(x) \ + x(SetInBufSize(UInt32 streamIndex, UInt32 size)) \ + x(SetOutBufSize(UInt32 streamIndex, UInt32 size)) + +Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35) + +#define Z7_IFACEM_ICompressInitEncoder(x) \ + x(InitEncoder()) +Z7_IFACE_CONSTR_CODER(ICompressInitEncoder, 0x36) /* That function initializes encoder structures. Call this function only for stream version of encoder. */ -}; -CODER_INTERFACE(ICompressSetInStream2, 0x37) -{ - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE; -}; +#define Z7_IFACEM_ICompressSetInStream2(x) \ + x(SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) \ + x(ReleaseInStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream2, 0x37) /* -CODER_INTERFACE(ICompressSetOutStream2, 0x38) -{ - STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE; -}; - -CODER_INTERFACE(ICompressSetInStreamSize2, 0x39) -{ - STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE; -}; +#define Z7_IFACEM_ICompressSetOutStream2(x) \ + x(SetOutStream2(UInt32 streamIndex, ISequentialOutStream *outStream)) + x(ReleaseOutStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38) + +#define Z7_IFACEM_ICompressSetInStreamSize2(x) \ + x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39) */ +/* +#define Z7_IFACEM_ICompressInSubStreams(x) \ + x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A) + +#define Z7_IFACEM_ICompressOutSubStreams(x) \ + x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressOutSubStreams, 0x3B) +*/ /* ICompressFilter - Filter() converts as most as possible bytes required for fast processing. + Filter(Byte *data, UInt32 size) + (size) + converts as most as possible bytes required for fast processing. Some filters have (smallest_fast_block). For example, (smallest_fast_block == 16) for AES CBC/CTR filters. If data stream is not finished, caller must call Filter() for larger block: @@ -310,13 +329,28 @@ { The filter can leave some bytes at the end of data without conversion: if there are data alignment reasons or speed reasons. - The caller must read additional data from stream and call Filter() again. + The caller can read additional data from stream and call Filter() again. } If data stream was finished, caller can call Filter() for (size < smallest_fast_block) - data : must be aligned for at least 16 bytes for some filters (AES) + (data) parameter: + Some filters require alignment for any Filter() call: + 1) (stream_offset % alignment_size) == (data % alignment_size) + 2) (alignment_size == 2^N) + where (stream_offset) - is the number of bytes that were already filtered before. + The callers of Filter() are required to meet these requirements. + (alignment_size) can be different: + 16 : for AES filters + 4 or 2 : for some branch convert filters + 1 : for another filters + (alignment_size >= 16) is enough for all current filters of 7-Zip. + But the caller can use larger (alignment_size). + Recommended alignment for (data) of Filter() call is (alignment_size == 64). + Also it's recommended to use aligned value for (size): + (size % alignment_size == 0), + if it's not last call of Filter() for current stream. - returns: (outSize): + returns: (outSize): if (outSize == 0) : Filter have not converted anything. So the caller can stop processing, if data stream was finished. if (outSize <= size) : Filter have converted outSize bytes @@ -325,60 +359,47 @@ (it's for crypto block algorithms). */ -#define INTERFACE_ICompressFilter(x) \ - STDMETHOD(Init)() x; \ - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \ - -CODER_INTERFACE(ICompressFilter, 0x40) -{ - INTERFACE_ICompressFilter(PURE); -}; - - -CODER_INTERFACE(ICompressCodecsInfo, 0x60) -{ - STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE; - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE; - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE; -}; - -CODER_INTERFACE(ISetCompressCodecsInfo, 0x61) -{ - STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE; -}; - -CODER_INTERFACE(ICryptoProperties, 0x80) -{ - STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; -}; +#define Z7_IFACEM_ICompressFilter(x) \ + x(Init()) \ + x##2(UInt32, Filter(Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressFilter, 0x40) + + +#define Z7_IFACEM_ICompressCodecsInfo(x) \ + x(GetNumMethods(UInt32 *numMethods)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateDecoder(UInt32 index, const GUID *iid, void* *coder)) \ + x(CreateEncoder(UInt32 index, const GUID *iid, void* *coder)) +Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60) + +#define Z7_IFACEM_ISetCompressCodecsInfo(x) \ + x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +Z7_IFACE_CONSTR_CODER(ISetCompressCodecsInfo, 0x61) + +#define Z7_IFACEM_ICryptoProperties(x) \ + x(SetKey(const Byte *data, UInt32 size)) \ + x(SetInitVector(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80) /* -CODER_INTERFACE(ICryptoResetSalt, 0x88) -{ - STDMETHOD(ResetSalt)() PURE; -}; + x(ResetSalt()) +Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88) */ -CODER_INTERFACE(ICryptoResetInitVector, 0x8C) -{ - STDMETHOD(ResetInitVector)() PURE; - +#define Z7_IFACEM_ICryptoResetInitVector(x) \ + x(ResetInitVector()) +Z7_IFACE_CONSTR_CODER(ICryptoResetInitVector, 0x8C) /* Call ResetInitVector() only for encoding. Call ResetInitVector() before encoding and before WriteCoderProperties(). Crypto encoder can create random IV in that function. */ -}; -CODER_INTERFACE(ICryptoSetPassword, 0x90) -{ - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICryptoSetCRC, 0xA0) -{ - STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; -}; +#define Z7_IFACEM_ICryptoSetPassword(x) \ + x(CryptoSetPassword(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90) + +#define Z7_IFACEM_ICryptoSetCRC(x) \ + x(CryptoSetCRC(UInt32 crc)) +Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0) namespace NMethodPropID @@ -399,24 +420,48 @@ }; } - -#define INTERFACE_IHasher(x) \ - STDMETHOD_(void, Init)() throw() x; \ - STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \ - STDMETHOD_(void, Final)(Byte *digest) throw() x; \ - STDMETHOD_(UInt32, GetDigestSize)() throw() x; \ - -CODER_INTERFACE(IHasher, 0xC0) +namespace NModuleInterfaceType { - INTERFACE_IHasher(PURE) -}; + /* + virtual destructor in IUnknown: + - no : 7-Zip (Windows) + - no : 7-Zip (Linux) (v23) in default mode + - yes : p7zip + - yes : 7-Zip (Linux) before v23 + - yes : 7-Zip (Linux) (v23), if Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN is defined + */ + const UInt32 k_IUnknown_VirtDestructor_No = 0; + const UInt32 k_IUnknown_VirtDestructor_Yes = 1; + const UInt32 k_IUnknown_VirtDestructor_ThisModule = + #if !defined(_WIN32) && defined(Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN) + k_IUnknown_VirtDestructor_Yes; + #else + k_IUnknown_VirtDestructor_No; + #endif +} -CODER_INTERFACE(IHashers, 0xC1) +namespace NModulePropID { - STDMETHOD_(UInt32, GetNumHashers)() PURE; - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE; -}; + enum EEnum + { + kInterfaceType, // VT_UI4 + kVersion // VT_UI4 + }; +} + + +#define Z7_IFACEM_IHasher(x) \ + x##2(void, Init()) \ + x##2(void, Update(const void *data, UInt32 size)) \ + x##2(void, Final(Byte *digest)) \ + x##2(UInt32, GetDigestSize()) +Z7_IFACE_CONSTR_CODER(IHasher, 0xC0) + +#define Z7_IFACEM_IHashers(x) \ + x##2(UInt32, GetNumHashers()) \ + x(GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateHasher(UInt32 index, IHasher **hasher)) +Z7_IFACE_CONSTR_CODER(IHashers, 0xC1) extern "C" { @@ -428,6 +473,8 @@ typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers); typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo); + typedef HRESULT (WINAPI *Func_GetModuleProp)(PROPID propID, PROPVARIANT *value); } +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/IDecl.h 7zip-22.01+really25.01+dfsg/CPP/7zip/IDecl.h --- 7zip-22.01+dfsg/CPP/7zip/IDecl.h 2015-03-06 11:13:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/IDecl.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,8 +1,9 @@ // IDecl.h -#ifndef __IDECL_H -#define __IDECL_H +#ifndef ZIP7_INC_IDECL_H +#define ZIP7_INC_IDECL_H +#include "../Common/Common0.h" #include "../Common/MyUnknown.h" #define k_7zip_GUID_Data1 0x23170F69 @@ -14,15 +15,62 @@ #define k_7zip_GUID_Data3_Encoder 0x2791 #define k_7zip_GUID_Data3_Hasher 0x2792 - -#define DECL_INTERFACE_SUB(i, base, groupId, subId) \ - DEFINE_GUID(IID_ ## i, \ +#define Z7_DECL_IFACE_7ZIP_SUB(i, _base, groupId, subId) \ + Z7_DEFINE_GUID(IID_ ## i, \ k_7zip_GUID_Data1, \ k_7zip_GUID_Data2, \ k_7zip_GUID_Data3_Common, \ 0, 0, 0, (groupId), 0, (subId), 0, 0); \ - struct i: public base + struct Z7_DECLSPEC_NOVTABLE i: public _base + +#define Z7_DECL_IFACE_7ZIP(i, groupId, subId) \ + Z7_DECL_IFACE_7ZIP_SUB(i, IUnknown, groupId, subId) + + +#ifdef COM_DECLSPEC_NOTHROW +#define Z7_COMWF_B COM_DECLSPEC_NOTHROW STDMETHODIMP +#define Z7_COMWF_B_(t) COM_DECLSPEC_NOTHROW STDMETHODIMP_(t) +#else +#define Z7_COMWF_B STDMETHODIMP +#define Z7_COMWF_B_(t) STDMETHODIMP_(t) +#endif + +#if defined(_MSC_VER) && !defined(COM_DECLSPEC_NOTHROW) +#define Z7_COM7F_B __declspec(nothrow) STDMETHODIMP +#define Z7_COM7F_B_(t) __declspec(nothrow) STDMETHODIMP_(t) +#else +#define Z7_COM7F_B Z7_COMWF_B +#define Z7_COM7F_B_(t) Z7_COMWF_B_(t) +#endif -#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId) +// #define Z7_COM7F_E Z7_noexcept +#define Z7_COM7F_E throw() +#define Z7_COM7F_EO Z7_COM7F_E Z7_override +#define Z7_COM7F_EOF Z7_COM7F_EO Z7_final +#define Z7_COM7F_IMF(f) Z7_COM7F_B f Z7_COM7F_E +#define Z7_COM7F_IMF2(t, f) Z7_COM7F_B_(t) f Z7_COM7F_E + +#define Z7_COM7F_PURE(f) virtual Z7_COM7F_IMF(f) =0; +#define Z7_COM7F_PURE2(t, f) virtual Z7_COM7F_IMF2(t, f) =0; +#define Z7_COM7F_IMP(f) Z7_COM7F_IMF(f) Z7_override Z7_final; +#define Z7_COM7F_IMP2(t, f) Z7_COM7F_IMF2(t, f) Z7_override Z7_final; +#define Z7_COM7F_IMP_NONFINAL(f) Z7_COM7F_IMF(f) Z7_override; +#define Z7_COM7F_IMP_NONFINAL2(t, f) Z7_COM7F_IMF2(t, f) Z7_override; + +#define Z7_IFACE_PURE(name) Z7_IFACEN_ ## name(=0;) +#define Z7_IFACE_IMP(name) Z7_IFACEN_ ## name(Z7_override Z7_final;) + +#define Z7_IFACE_COM7_PURE(name) Z7_IFACEM_ ## name(Z7_COM7F_PURE) +#define Z7_IFACE_COM7_IMP(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP) +#define Z7_IFACE_COM7_IMP_NONFINAL(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP_NONFINAL) + + +#define Z7_IFACE_DECL_PURE(name) \ + DECLARE_INTERFACE(name) \ + { Z7_IFACE_PURE(name) }; + +#define Z7_IFACE_DECL_PURE_(name, baseiface) \ + DECLARE_INTERFACE_(name, baseiface) \ + { Z7_IFACE_PURE(name) }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/IPassword.h 7zip-22.01+really25.01+dfsg/CPP/7zip/IPassword.h --- 7zip-22.01+dfsg/CPP/7zip/IPassword.h 2019-08-07 13:52:47.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/IPassword.h 2023-03-24 11:00:00.000000000 +0000 @@ -1,14 +1,17 @@ // IPassword.h -#ifndef __IPASSWORD_H -#define __IPASSWORD_H +#ifndef ZIP7_INC_IPASSWORD_H +#define ZIP7_INC_IPASSWORD_H #include "../Common/MyTypes.h" -#include "../Common/MyUnknown.h" #include "IDecl.h" -#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x) +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_PASSWORD(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 5, n) \ + { Z7_IFACE_COM7_PURE(i) }; /* How to use output parameter (BSTR *password): @@ -20,10 +23,9 @@ The caller must free BSTR string with function SysFreeString(); */ -PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) -{ - STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; -}; +#define Z7_IFACEM_ICryptoGetTextPassword(x) \ + x(CryptoGetTextPassword(BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword, 0x10) /* @@ -44,10 +46,9 @@ The caller must free BSTR string with function SysFreeString() */ +#define Z7_IFACEM_ICryptoGetTextPassword2(x) \ + x(CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword2, 0x11) -PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) -{ - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; -}; - +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/IProgress.h 7zip-22.01+really25.01+dfsg/CPP/7zip/IProgress.h --- 7zip-22.01+dfsg/CPP/7zip/IProgress.h 2015-08-01 14:40:47.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/IProgress.h 2023-02-01 18:00:00.000000000 +0000 @@ -1,19 +1,20 @@ // IProgress.h -#ifndef __IPROGRESS_H -#define __IPROGRESS_H +#ifndef ZIP7_INC_IPROGRESS_H +#define ZIP7_INC_IPROGRESS_H #include "../Common/MyTypes.h" #include "IDecl.h" -#define INTERFACE_IProgress(x) \ - STDMETHOD(SetTotal)(UInt64 total) x; \ - STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ - -DECL_INTERFACE(IProgress, 0, 5) -{ - INTERFACE_IProgress(PURE) -}; +Z7_PURE_INTERFACES_BEGIN +#define Z7_IFACEM_IProgress(x) \ + x(SetTotal(UInt64 total)) \ + x(SetCompleted(const UInt64 *completeValue)) \ + +Z7_DECL_IFACE_7ZIP(IProgress, 0, 5) + { Z7_IFACE_COM7_PURE(IProgress) }; + +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/IStream.h 7zip-22.01+really25.01+dfsg/CPP/7zip/IStream.h --- 7zip-22.01+dfsg/CPP/7zip/IStream.h 2022-02-15 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/IStream.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,24 +1,29 @@ // IStream.h -#ifndef __ISTREAM_H -#define __ISTREAM_H +#ifndef ZIP7_INC_ISTREAM_H +#define ZIP7_INC_ISTREAM_H +#include "../Common/Common0.h" #include "../Common/MyTypes.h" #include "../Common/MyWindows.h" #include "IDecl.h" -#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x) -#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) +Z7_PURE_INTERFACES_BEGIN -STREAM_INTERFACE(ISequentialInStream, 0x01) -{ - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* +#define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_STREAM(i, n) \ + Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n) + + +/* +ISequentialInStream::Read() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. - + if (size == 0), this function returns S_OK and (*processedSize) is set to 0. if (size != 0) @@ -31,21 +36,21 @@ If seek pointer before Read() call was changed to position past the end of stream: if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0. - + ERROR CASES: If the function returns error code, then (*processedSize) is size of data written to (data) buffer (it can be data before error or data with errors). The recommended way for callee to work with reading errors: 1) write part of data before error to (data) buffer and return S_OK. 2) return error code for further calls of Read(). - */ -}; +*/ +#define Z7_IFACEM_ISequentialInStream(x) \ + x(Read(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01) -STREAM_INTERFACE(ISequentialOutStream, 0x02) -{ - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* + +/* +ISequentialOutStream::Write() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. @@ -59,8 +64,11 @@ ERROR CASES: If the function returns error code, then (*processedSize) is size of data written from (data) buffer. - */ -}; +*/ +#define Z7_IFACEM_ISequentialOutStream(x) \ + x(Write(const void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02) + #ifdef _WIN32 @@ -72,48 +80,42 @@ #else -#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY__E_ERROR_NEGATIVE_SEEK +#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY_E_ERROR_NEGATIVE_SEEK #endif -/* Seek() Function - If you seek before the beginning of the stream, Seek() function returns error code: +/* +IInStream::Seek() / IOutStream::Seek() + If you seek to position before the beginning of the stream, + Seek() function returns error code: Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK). or STG_E_INVALIDFUNCTION - It is allowed to seek past the end of the stream. - - if Seek() returns error, then the value of *newPosition is undefined. */ -STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; -}; - -STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; - STDMETHOD(SetSize)(UInt64 newSize) PURE; -}; - -STREAM_INTERFACE(IStreamGetSize, 0x06) -{ - STDMETHOD(GetSize)(UInt64 *size) PURE; -}; - -STREAM_INTERFACE(IOutStreamFinish, 0x07) -{ - STDMETHOD(OutStreamFinish)() PURE; -}; - +#define Z7_IFACEM_IInStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03) + +#define Z7_IFACEM_IOutStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \ + x(SetSize(UInt64 newSize)) +Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04) + +#define Z7_IFACEM_IStreamGetSize(x) \ + x(GetSize(UInt64 *size)) +Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06) + +#define Z7_IFACEM_IOutStreamFinish(x) \ + x(OutStreamFinish()) +Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07) + +#define Z7_IFACEM_IStreamGetProps(x) \ + x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08) -STREAM_INTERFACE(IStreamGetProps, 0x08) -{ - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE; -}; struct CStreamFileProps { @@ -128,16 +130,81 @@ FILETIME MTime; }; -STREAM_INTERFACE(IStreamGetProps2, 0x09) -{ - STDMETHOD(GetProps2)(CStreamFileProps *props) PURE; -}; +#define Z7_IFACEM_IStreamGetProps2(x) \ + x(GetProps2(CStreamFileProps *props)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09) + +#define Z7_IFACEM_IStreamGetProp(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(ReloadProps()) +Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a) -STREAM_INTERFACE(IStreamGetProp, 0x0a) -{ - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(ReloadProps)() PURE; -}; +/* +IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end) + + It sets region of data in output stream that is restricted. + For restricted region it's expected (or allowed) + that the caller can write to same region with different calls of Write()/SetSize(). + Another regions of output stream will be supposed as non-restricted: + - The callee usually doesn't flush the data in restricted region. + - The callee usually can flush data from non-restricted region after writing. + +Actual restiction rules depend also from current stream position. +It's recommended to call SetRestriction() just before the Write() call. +So the callee can optimize writing and flushing, if that Write() +operation is not restricted. + +Note: Each new call of SetRestriction() sets new restictions, +so previous restrction calls has no effect anymore. + +inputs: + + (begin > end) is not allowed, and returns E_FAIL; + + if (begin == end) + { + No restriction. + The caller will call Write() in sequential order. + After SetRestriction(begin, begin), but before next call of SetRestriction() + { + Additional condition: + it's expected that current stream seek position is equal to stream size. + The callee can make final flushing for any data before current stream seek position. + For each Write(size) call: + The callee can make final flushing for that new written data. + } + The pair of values (begin == 0 && end == 0) is recommended to remove write restriction. + } + + if (begin < end) + { + it means that callee must NOT flush any data in region [begin, end). + The caller is allowed to Seek() to that region and rewrite the + data in that restriction region. + if (end == (UInt64)(Int64)-1) + { + there is no upper bound for restricted region. + So non-restricted region will be [0, begin) in that case + } + } + + returns: + - if (begin > end) it return ERROR code (E_FAIL) + - S_OK : if no errors. + - Also the call of SetRestriction() can initiate the flushing of already written data. + So it can return the result of that flushing. + + Note: IOutStream::SetSize() also can change the data. + So it's not expected the call + IOutStream::SetSize() to region that was written before as unrestricted. +*/ + +#define Z7_IFACEM_IStreamSetRestriction(x) \ + x(SetRestriction(UInt64 begin, UInt64 end)) \ + +Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10) + +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/LzmaDec.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/LzmaDec.mak --- 7zip-22.01+dfsg/CPP/7zip/LzmaDec.mak 2020-03-16 12:48:53.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/LzmaDec.mak 2024-02-29 08:00:00.000000000 +0000 @@ -1,6 +1,6 @@ -!IF "$(PLATFORM)" == "x64" +!IF "$(PLATFORM)" == "x64" || ("$(PLATFORM)" == "arm64" && !defined(NO_ASM_GNU)) !IFNDEF NO_ASM -CFLAGS_C_SPEC = -D_LZMA_DEC_OPT +CFLAGS_C_SPEC = -DZ7_LZMA_DEC_OPT ASM_OBJS = $(ASM_OBJS) \ $O\LzmaDecOpt.obj !ENDIF diff -Nru 7zip-22.01+dfsg/CPP/7zip/MyVersionInfo.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/MyVersionInfo.rc --- 7zip-22.01+dfsg/CPP/7zip/MyVersionInfo.rc 2011-04-18 11:38:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/MyVersionInfo.rc 2023-02-21 13:00:00.000000000 +0000 @@ -1,2 +1,2 @@ #include "MyVersion.h" -#include "..\..\C\7zVersion.rc" +#include "../../C/7zVersion.rc" diff -Nru 7zip-22.01+dfsg/CPP/7zip/PropID.h 7zip-22.01+really25.01+dfsg/CPP/7zip/PropID.h --- 7zip-22.01+dfsg/CPP/7zip/PropID.h 2022-05-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/PropID.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // PropID.h -#ifndef __7ZIP_PROP_ID_H -#define __7ZIP_PROP_ID_H +#ifndef ZIP7_INC_7ZIP_PROP_ID_H +#define ZIP7_INC_7ZIP_PROP_ID_H #include "../Common/MyTypes.h" @@ -110,6 +110,8 @@ kpidGroupId, kpidDeviceMajor, kpidDeviceMinor, + kpidDevMajor, + kpidDevMinor, kpid_NUM_DEFINED, diff -Nru 7zip-22.01+dfsg/CPP/7zip/Sort.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/Sort.mak --- 7zip-22.01+dfsg/CPP/7zip/Sort.mak 1970-01-01 00:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/Sort.mak 2025-07-02 08:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +!IF defined(USE_NO_ASM) || defined(USE_C_SORT) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ +!ELSE +ASM_OBJS = $(ASM_OBJS) \ +!ENDIF + $O\Sort.obj diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/Agent.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/Agent.cpp 2022-06-03 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.cpp 2024-10-04 10:00:00.000000000 +0000 @@ -12,7 +12,7 @@ #include "../../../Windows/FileName.h" #include "../../../Windows/PropVariantConv.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -29,8 +29,12 @@ false; // 22.00 // true; // 21.07 -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS + extern + CExternalCodecs g_ExternalCodecs; CExternalCodecs g_ExternalCodecs; + extern + const CExternalCodecs *g_ExternalCodecs_Ptr; const CExternalCodecs *g_ExternalCodecs_Ptr; static CCodecs::CReleaser g_CodecsReleaser; #else @@ -39,7 +43,7 @@ CMyComPtr g_CodecsRef; #endif -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -50,7 +54,7 @@ { MT_LOCK - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (g_CodecsObj) { g_CodecsObj->CloseLibs(); @@ -73,7 +77,7 @@ g_CodecsObj = new CCodecs; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS g_ExternalCodecs.GetCodecs = g_CodecsObj; g_ExternalCodecs.GetHashers = g_CodecsObj; g_CodecsReleaser.Set(g_CodecsObj); @@ -82,7 +86,7 @@ g_CodecsRef = g_CodecsObj; #endif - RINOK(g_CodecsObj->Load()); + RINOK(g_CodecsObj->Load()) if (g_CodecsObj->Formats.IsEmpty()) { FreeGlobalCodecs(); @@ -91,15 +95,15 @@ Codecs_AddHashArcHandler(g_CodecsObj); - #ifdef EXTERNAL_CODECS - RINOK(g_ExternalCodecs.Load()); + #ifdef Z7_EXTERNAL_CODECS + RINOK(g_ExternalCodecs.Load()) g_ExternalCodecs_Ptr = &g_ExternalCodecs; #endif return S_OK; } -STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder) +Z7_COM7F_IMF(CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)) { *agentFolder = this; return S_OK; @@ -119,9 +123,9 @@ _items.Add(item); const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; if (file.DirIndex != -1) - LoadFolder(file.DirIndex); + LoadFolder((unsigned)file.DirIndex); if (_loadAltStreams && file.AltDirIndex != -1) - LoadFolder(file.AltDirIndex); + LoadFolder((unsigned)file.AltDirIndex); } return; } @@ -143,7 +147,7 @@ } } -STDMETHODIMP CAgentFolder::LoadItems() +Z7_COM7F_IMF(CAgentFolder::LoadItems()) { if (!_agentSpec->_archiveLink.IsOpen) return E_FAIL; @@ -160,7 +164,7 @@ return S_OK; } -STDMETHODIMP CAgentFolder::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CAgentFolder::GetNumberOfItems(UInt32 *numItems)) { if (_flatMode) *numItems = _items.Size(); @@ -217,7 +221,7 @@ { const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex]; len += file.NameLen + 1; - proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream); + proxyIndex = (file.Parent == -1) ? 0 : (unsigned)_proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream); } wchar_t *p = prefix.GetBuf_SetEnd(len) + len; @@ -229,7 +233,7 @@ *p = WCHAR_PATH_SEPARATOR; p -= file.NameLen; wmemcpy(p, file.Name, file.NameLen); - proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream); + proxyIndex = (file.Parent == -1) ? 0 : (unsigned)_proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream); } } else @@ -239,7 +243,7 @@ { const CProxyDir *dir = &_proxy->Dirs[proxyIndex]; len += dir->NameLen + 1; - proxyIndex = dir->ParentDir; + proxyIndex = (unsigned)dir->ParentDir; } wchar_t *p = prefix.GetBuf_SetEnd(len) + len; @@ -251,14 +255,14 @@ *p = WCHAR_PATH_SEPARATOR; p -= dir->NameLen; wmemcpy(p, dir->Name, dir->NameLen); - proxyIndex = dir->ParentDir; + proxyIndex = (unsigned)dir->ParentDir; } } } UString CAgentFolder::GetFullPrefix(UInt32 index) const { - int foldIndex = _proxyDirIndex; + unsigned foldIndex = _proxyDirIndex; if (_flatMode) foldIndex = _items[index].DirIndex; @@ -269,7 +273,7 @@ return _proxy->GetDirPath_as_Prefix(foldIndex); } -STDMETHODIMP_(UInt64) CAgentFolder::GetItemSize(UInt32 index) +Z7_COM7F_IMF2(UInt64, CAgentFolder::GetItemSize(UInt32 index)) { unsigned arcIndex; if (_proxy2) @@ -294,7 +298,7 @@ return item.Size; if (!item.IsLeaf()) return 0; - arcIndex = item.ArcIndex; + arcIndex = (unsigned)item.ArcIndex; } else { @@ -309,7 +313,7 @@ return 0; } -STDMETHODIMP CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -363,7 +367,7 @@ // if (itemFolder.IsLeaf) if (!item.Ignore) { - RINOK(_agentSpec->GetArchive()->GetProperty(arcIndex, propID, value)); + RINOK(_agentSpec->GetArchive()->GetProperty(arcIndex, propID, value)) } if (itemFolder.CrcIsDefined && value->vt == VT_EMPTY) prop = itemFolder.Crc; @@ -397,7 +401,7 @@ { if (item.IsLeaf()) { - RINOK(_agentSpec->GetArchive()->GetProperty(item.ArcIndex, propID, value)); + RINOK(_agentSpec->GetArchive()->GetProperty((unsigned)item.ArcIndex, propID, value)) } if (item.CrcIsDefined && value->vt == VT_EMPTY) prop = item.Crc; @@ -405,7 +409,7 @@ } default: if (item.IsLeaf()) - return _agentSpec->GetArchive()->GetProperty(item.ArcIndex, propID, value); + return _agentSpec->GetArchive()->GetProperty((unsigned)item.ArcIndex, propID, value); } } else @@ -436,7 +440,7 @@ return 0; } -STDMETHODIMP CAgentFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len) +Z7_COM7F_IMF(CAgentFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) { if (_proxy2) { @@ -467,9 +471,9 @@ } } -STDMETHODIMP CAgentFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len) +Z7_COM7F_IMF(CAgentFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len)) { - *name = 0; + *name = NULL; *len = 0; if (!_flatMode) return S_OK; @@ -493,7 +497,7 @@ return S_OK; } -static int CompareRawProps(IArchiveGetRawProps *rawProps, int arcIndex1, int arcIndex2, PROPID propID) +static int CompareRawProps(IArchiveGetRawProps *rawProps, unsigned arcIndex1, unsigned arcIndex2, PROPID propID) { // if (propID == kpidSha1) if (rawProps) @@ -501,14 +505,14 @@ const void *p1, *p2; UInt32 size1, size2; UInt32 propType1, propType2; - HRESULT res1 = rawProps->GetRawProp(arcIndex1, propID, &p1, &size1, &propType1); - HRESULT res2 = rawProps->GetRawProp(arcIndex2, propID, &p2, &size2, &propType2); + const HRESULT res1 = rawProps->GetRawProp(arcIndex1, propID, &p1, &size1, &propType1); + const HRESULT res2 = rawProps->GetRawProp(arcIndex2, propID, &p2, &size2, &propType2); if (res1 == S_OK && res2 == S_OK) { for (UInt32 i = 0; i < size1 && i < size2; i++) { - Byte b1 = ((const Byte *)p1)[i]; - Byte b2 = ((const Byte *)p2)[i]; + const Byte b1 = ((const Byte *)p1)[i]; + const Byte b2 = ((const Byte *)p2)[i]; if (b1 < b2) return -1; if (b1 > b2) return 1; } @@ -681,7 +685,7 @@ } -STDMETHODIMP_(Int32) CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw) +Z7_COM7F_IMF2(Int32, CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw)) { try { if (_proxy2) @@ -725,7 +729,7 @@ if (realIndex1 < dir1->SubDirs.Size()) { proxFolder1 = &_proxy->Dirs[dir1->SubDirs[realIndex1]]; - arcIndex1 = proxFolder1->ArcIndex; + arcIndex1 = (unsigned)proxFolder1->ArcIndex; } else arcIndex1 = dir1->SubFiles[realIndex1 - dir1->SubDirs.Size()]; @@ -733,7 +737,7 @@ if (realIndex2 < dir2->SubDirs.Size()) { proxFolder2 = &_proxy->Dirs[dir2->SubDirs[realIndex2]]; - arcIndex2 = proxFolder2->ArcIndex; + arcIndex2 = (unsigned)proxFolder2->ArcIndex; } else arcIndex2 = dir2->SubFiles[realIndex2 - dir2->SubDirs.Size()]; @@ -866,17 +870,17 @@ return S_OK; } -STDMETHODIMP CAgentFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgentFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) { COM_TRY_BEGIN if (_proxy2) { SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; + const unsigned arcIndex = dir->Items[realIndex]; const CProxyFile2 &item = _proxy2->Files[arcIndex]; if (!item.IsDir()) return E_INVALIDARG; - return BindToFolder_Internal(item.DirIndex, resultFolder); + return BindToFolder_Internal((unsigned)item.DirIndex, resultFolder); } SET_realIndex_AND_dir if (realIndex >= (UInt32)dir->SubDirs.Size()) @@ -885,20 +889,20 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) { COM_TRY_BEGIN if (_proxy2) { - int index = _proxy2->FindItem(_proxyDirIndex, name, true); + const int index = _proxy2->FindItem(_proxyDirIndex, name, true); if (index == -1) return E_INVALIDARG; - return BindToFolder_Internal(_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder); + return BindToFolder_Internal((unsigned)_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder); } - int index = _proxy->FindSubDir(_proxyDirIndex, name); + const int index = _proxy->FindSubDir(_proxyDirIndex, name); if (index == -1) return E_INVALIDARG; - return BindToFolder_Internal(index, resultFolder); + return BindToFolder_Internal((unsigned)index, resultFolder); COM_TRY_END } @@ -933,7 +937,7 @@ return S_OK; } -STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **resultFolder)) { COM_TRY_BEGIN @@ -958,11 +962,11 @@ } else { - unsigned arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex; + const unsigned arcIndex = (unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex; const CProxyFile2 &item = _proxy2->Files[arcIndex]; if (item.AltDirIndex == -1) return S_OK; - altDirIndex = item.AltDirIndex; + altDirIndex = (unsigned)item.AltDirIndex; // parentFolder = _parentFolder; } @@ -974,17 +978,17 @@ } SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; + const unsigned arcIndex = dir->Items[realIndex]; const CProxyFile2 &item = _proxy2->Files[arcIndex]; if (item.AltDirIndex == -1) return S_OK; - return BindToAltStreams_Internal(item.AltDirIndex, resultFolder); + return BindToAltStreams_Internal((unsigned)item.AltDirIndex, resultFolder); } COM_TRY_END } -STDMETHODIMP CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder **resultFolder)) { COM_TRY_BEGIN @@ -1006,14 +1010,14 @@ const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; if (file.AltDirIndex != -1) if (CompareFileNames(file.Name, name) == 0) - return BindToAltStreams_Internal(file.AltDirIndex, resultFolder); + return BindToAltStreams_Internal((unsigned)file.AltDirIndex, resultFolder); } return E_INVALIDARG; } COM_TRY_END } -STDMETHODIMP CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupported) +Z7_COM7F_IMF(CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupported)) { *isSupported = BoolToInt(false); @@ -1032,7 +1036,7 @@ *isSupported = BoolToInt(true); return S_OK; } - arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex; + arcIndex = (unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex; } else { @@ -1046,7 +1050,7 @@ } -STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)) { COM_TRY_BEGIN /* @@ -1071,15 +1075,15 @@ if (parentIndex == -1) proxyDirIndex = k_Proxy2_RootDirIndex; else - proxyDirIndex = _proxy2->Files[(unsigned)parentIndex].DirIndex; + proxyDirIndex = (unsigned)_proxy2->Files[(unsigned)parentIndex].DirIndex; } } else { - int parent = _proxy->Dirs[_proxyDirIndex].ParentDir; + const int parent = _proxy->Dirs[_proxyDirIndex].ParentDir; if (parent == -1) return S_OK; - proxyDirIndex = parent; + proxyDirIndex = (unsigned)parent; } CAgentFolder *folderSpec = new CAgentFolder; @@ -1091,10 +1095,11 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream)) { - CMyComPtr getStream; - _agentSpec->GetArchive()->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); + Z7_DECL_CMyComPtr_QI_FROM( + IInArchiveGetStream, + getStream, _agentSpec->GetArchive()) if (!getStream) return S_OK; @@ -1113,7 +1118,7 @@ const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; if (!item.IsLeaf()) return S_OK; - arcIndex = item.ArcIndex; + arcIndex = (unsigned)item.ArcIndex; } else arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; @@ -1139,11 +1144,11 @@ VARTYPE Type; }; -STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CAgentFolder::GetNumberOfProperties(UInt32 *numProps)) { COM_TRY_BEGIN - RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProps)); - *numProps += ARRAY_SIZE(kProps); + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProps)) + *numProps += Z7_ARRAY_SIZE(kProps); if (!_flatMode) (*numProps)--; /* @@ -1164,7 +1169,7 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) { COM_TRY_BEGIN UInt32 numProps; @@ -1182,7 +1187,7 @@ { *propID = kpidName; *varType = VT_BSTR; - *name = 0; + *name = NULL; return S_OK; } index--; @@ -1190,7 +1195,7 @@ if (index < numProps) { - RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)) if (*propID == kpidPath) *propID = kpidName; } @@ -1206,7 +1211,7 @@ */ *propID = kProps[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; - *name = 0; + *name = NULL; } return S_OK; COM_TRY_END @@ -1221,7 +1226,7 @@ kpidCRC }; -STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN @@ -1284,21 +1289,23 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProps) +Z7_COM7F_IMF(CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProps)) { - *numProps = ARRAY_SIZE(kFolderProps); + *numProps = Z7_ARRAY_SIZE(kFolderProps); return S_OK; } -STDMETHODIMP CAgentFolder::GetFolderPropertyInfo IMP_IFolderFolder_GetProp(kFolderProps) +IMP_IFolderFolder_GetProp( + CAgentFolder::GetFolderPropertyInfo, + kFolderProps) -STDMETHODIMP CAgentFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */) +Z7_COM7F_IMF(CAgentFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */)) { return E_FAIL; } -STDMETHODIMP CAgentFolder::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CAgentFolder::GetNumRawProps(UInt32 *numProps)) { IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); if (rawProps) @@ -1307,7 +1314,7 @@ return S_OK; } -STDMETHODIMP CAgentFolder::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CAgentFolder::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) { IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); if (rawProps) @@ -1315,7 +1322,7 @@ return E_FAIL; } -STDMETHODIMP CAgentFolder::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CAgentFolder::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); if (rawProps) @@ -1339,7 +1346,7 @@ *propType = 0; return S_OK; } - arcIndex = item.ArcIndex; + arcIndex = (unsigned)item.ArcIndex; } else arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; @@ -1352,29 +1359,27 @@ return S_OK; } -STDMETHODIMP CAgentFolder::GetFolderArcProps(IFolderArcProps **object) +Z7_COM7F_IMF(CAgentFolder::GetFolderArcProps(IFolderArcProps **object)) { CMyComPtr temp = _agentSpec; *object = temp.Detach(); return S_OK; } -#ifdef NEW_FOLDER_INTERFACE -STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode) +Z7_COM7F_IMF(CAgentFolder::SetFlatMode(Int32 flatMode)) { _flatMode = IntToBool(flatMode); return S_OK; } -#endif int CAgentFolder::GetRealIndex(unsigned index) const { if (!_flatMode) { if (_proxy2) - return _proxy2->GetRealIndex(_proxyDirIndex, index); + return (int)_proxy2->GetRealIndex(_proxyDirIndex, index); else return _proxy->GetRealIndex(_proxyDirIndex, index); } @@ -1383,12 +1388,12 @@ if (_proxy2) { const CProxyDir2 *dir = &_proxy2->Dirs[item.DirIndex]; - return dir->Items[item.Index]; + return (int)dir->Items[item.Index]; } else { const CProxyDir *dir = &_proxy->Dirs[item.DirIndex]; - unsigned realIndex = item.Index; + const unsigned realIndex = item.Index; if (realIndex < dir->SubDirs.Size()) { const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; @@ -1396,7 +1401,7 @@ return -1; return f.ArcIndex; } - return dir->SubFiles[realIndex - dir->SubDirs.Size()]; + return (int)dir->SubFiles[realIndex - dir->SubDirs.Size()]; } } } @@ -1437,7 +1442,7 @@ const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; if (!f.IsLeaf()) continue; - arcIndex = f.ArcIndex; + arcIndex = (unsigned)f.ArcIndex; } else arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; @@ -1445,10 +1450,10 @@ realIndices.Add(arcIndex); } - HeapSort(&realIndices.Front(), realIndices.Size()); + HeapSort(realIndices.NonConstData(), realIndices.Size()); } -STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices, +Z7_COM7F_IMF(CAgentFolder::Extract(const UInt32 *indices, UInt32 numItems, Int32 includeAltStreams, Int32 replaceAltStreamColon, @@ -1456,7 +1461,7 @@ NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, Int32 testMode, - IFolderArchiveExtractCallback *extractCallback2) + IFolderArchiveExtractCallback *extractCallback2)) { COM_TRY_BEGIN @@ -1491,7 +1496,8 @@ if (path) { pathU = us2fs(path); - if (!pathU.IsEmpty()) + if (!pathU.IsEmpty() + && !NFile::NName::IsAltStreamPrefixWithColon(path)) { NFile::NName::NormalizeDirPathPrefix(pathU); NFile::NDir::CreateComplexDir(pathU); @@ -1510,6 +1516,8 @@ if (_zoneMode != NExtract::NZoneIdMode::kNone) { ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf); + if (_zoneBuf.Size() != 0) + extractCallbackSpec->ZoneBuf = _zoneBuf; } #endif @@ -1524,7 +1532,7 @@ (UInt64)(Int64)-1); if (_proxy2) - extractCallbackSpec->SetBaseParentFolderIndex(_proxy2->Dirs[_proxyDirIndex].ArcIndex); + extractCallbackSpec->SetBaseParentFolderIndex((unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex); // do we need another base folder for subfolders ? extractCallbackSpec->DirPathPrefix_for_HashFiles = _agentSpec->_hashBaseFolderPrefix; @@ -1538,7 +1546,7 @@ if (!testMode) { - RINOK(extractCallbackSpec->PrepareHardLinks(&realIndices)); + RINOK(extractCallbackSpec->PrepareHardLinks(&realIndices)) } #endif @@ -1546,10 +1554,10 @@ { CArchiveExtractCallback_Closer ecsCloser(extractCallbackSpec); - HRESULT res = _agentSpec->GetArchive()->Extract(&realIndices.Front(), + HRESULT res = _agentSpec->GetArchive()->Extract(realIndices.ConstData(), realIndices.Size(), testMode, extractCallback); - HRESULT res2 = ecsCloser.Close(); + const HRESULT res2 = ecsCloser.Close(); if (res == S_OK) res = res2; return res; @@ -1592,12 +1600,12 @@ return true; } -STDMETHODIMP CAgent::Open( +Z7_COM7F_IMF(CAgent::Open( IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveType, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN _archiveFilePath = filePath; @@ -1609,7 +1617,7 @@ if (!inStream) { if (!fi.Find(us2fs(_archiveFilePath))) - return ::GetLastError(); + return GetLastError_noZero_HRESULT(); if (fi.IsDir()) return E_FAIL; _attrib = fi.Attrib; @@ -1623,7 +1631,7 @@ } CArcInfoEx archiverInfo0, archiverInfo1; - RINOK(LoadGlobalCodecs()); + RINOK(LoadGlobalCodecs()) CObjectVector types; if (!ParseOpenTypes(*g_CodecsObj, arcFormat, types)) @@ -1665,7 +1673,7 @@ ArchiveType = GetTypeOfArc(arc); if (archiveType) { - RINOK(StringToBstr(ArchiveType, archiveType)); + RINOK(StringToBstr(ArchiveType, archiveType)) } if (arc.IsHashHandler(options)) @@ -1678,7 +1686,7 @@ } -STDMETHODIMP CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback) +Z7_COM7F_IMF(CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN if (_proxy2) @@ -1704,12 +1712,12 @@ options.filePath = _archiveFilePath; options.callback = openArchiveCallback; - RINOK(_archiveLink.ReOpen(options)); + RINOK(_archiveLink.ReOpen(options)) return ReadItems(); COM_TRY_END } -STDMETHODIMP CAgent::Close() +Z7_COM7F_IMF(CAgent::Close()) { COM_TRY_BEGIN return _archiveLink.Close(); @@ -1717,7 +1725,7 @@ } /* -STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) +Z7_COM7F_IMF(CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) { return _archive->EnumProperties(EnumProperties); } @@ -1748,7 +1756,7 @@ CMyComBSTR name; PROPID propID; VARTYPE varType; - RINOK(arc.Archive->GetPropertyInfo(i, &name, &propID, &varType)); + RINOK(arc.Archive->GetPropertyInfo(i, &name, &propID, &varType)) if (propID == kpidPath) ThereIsPathProp = true; /* @@ -1763,12 +1771,12 @@ return _proxy->Load(GetArc(), NULL); } -STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAgent::BindToRootFolder(IFolderFolder **resultFolder)) { COM_TRY_BEGIN if (!_archiveLink.Arcs.IsEmpty()) { - RINOK(ReadItems()); + RINOK(ReadItems()) } CAgentFolder *folderSpec = new CAgentFolder; CMyComPtr rootFolder = folderSpec; @@ -1778,12 +1786,12 @@ COM_TRY_END } -STDMETHODIMP CAgent::Extract( +Z7_COM7F_IMF(CAgent::Extract( NExtract::NPathMode::EEnum pathMode, NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, Int32 testMode, - IFolderArchiveExtractCallback *extractCallback2) + IFolderArchiveExtractCallback *extractCallback2)) { COM_TRY_BEGIN @@ -1820,40 +1828,40 @@ if (!testMode) { - RINOK(extractCallbackSpec->PrepareHardLinks(NULL)); // NULL means all items + RINOK(extractCallbackSpec->PrepareHardLinks(NULL)) // NULL means all items } #endif - return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback); + return GetArchive()->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallback); COM_TRY_END } -STDMETHODIMP CAgent::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CAgent::GetNumberOfProperties(UInt32 *numProps)) { COM_TRY_BEGIN return GetArchive()->GetNumberOfProperties(numProps); COM_TRY_END } -STDMETHODIMP CAgent::GetPropertyInfo(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CAgent::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType)) { COM_TRY_BEGIN - RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)); + RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)) if (*propID == kpidPath) *propID = kpidName; return S_OK; COM_TRY_END } -STDMETHODIMP CAgent::GetArcNumLevels(UInt32 *numLevels) +Z7_COM7F_IMF(CAgent::GetArcNumLevels(UInt32 *numLevels)) { *numLevels = _archiveLink.Arcs.Size(); return S_OK; } -STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -1933,28 +1941,28 @@ COM_TRY_END } -STDMETHODIMP CAgent::GetArcNumProps(UInt32 level, UInt32 *numProps) +Z7_COM7F_IMF(CAgent::GetArcNumProps(UInt32 level, UInt32 *numProps)) { return _archiveLink.Arcs[level].Archive->GetNumberOfArchiveProperties(numProps); } -STDMETHODIMP CAgent::GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CAgent::GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) { return _archiveLink.Arcs[level].Archive->GetArchivePropertyInfo(index, name, propID, varType); } // MainItemProperty -STDMETHODIMP CAgent::GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAgent::GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value)) { return _archiveLink.Arcs[level - 1].Archive->GetProperty(_archiveLink.Arcs[level].SubfileIndex, propID, value); } -STDMETHODIMP CAgent::GetArcNumProps2(UInt32 level, UInt32 *numProps) +Z7_COM7F_IMF(CAgent::GetArcNumProps2(UInt32 level, UInt32 *numProps)) { return _archiveLink.Arcs[level - 1].Archive->GetNumberOfProperties(numProps); } -STDMETHODIMP CAgent::GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CAgent::GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) { return _archiveLink.Arcs[level - 1].Archive->GetPropertyInfo(index, name, propID, varType); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/Agent.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/Agent.h 2022-06-01 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/Agent.h 2024-10-04 10:00:00.000000000 +0000 @@ -1,19 +1,17 @@ // Agent/Agent.h -#ifndef __AGENT_AGENT_H -#define __AGENT_AGENT_H +#ifndef ZIP7_INC_AGENT_AGENT_H +#define ZIP7_INC_AGENT_AGENT_H #include "../../../Common/MyCom.h" #include "../../../Windows/PropVariant.h" +#include "../Common/LoadCodecs.h" #include "../Common/OpenArchive.h" #include "../Common/UpdateAction.h" -#ifdef NEW_FOLDER_INTERFACE #include "../FileManager/IFolder.h" -#include "../Common/LoadCodecs.h" -#endif #include "AgentProxy.h" #include "IFolderArchive.h" @@ -24,10 +22,13 @@ class CAgentFolder; -DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC) -{ - STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE; -}; +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEM_IArchiveFolderInternal(x) \ + x(GetAgentFolder(CAgentFolder **agentFolder)) +Z7_IFACE_CONSTR_FOLDERARC(IArchiveFolderInternal, 0xC) + +Z7_PURE_INTERFACES_END struct CProxyItem { @@ -47,7 +48,7 @@ AGENT_OP_Comment }; -class CAgentFolder: +class CAgentFolder Z7_final: public IFolderFolder, public IFolderAltStreams, public IFolderProperties, @@ -59,71 +60,60 @@ public IArchiveFolderInternal, public IInArchiveGetStream, public IFolderSetZoneIdMode, -#ifdef NEW_FOLDER_INTERFACE + public IFolderSetZoneIdFile, public IFolderOperations, public IFolderSetFlatMode, -#endif public CMyUnknownImp { - void LoadFolder(unsigned proxyDirIndex); -public: - - MY_QUERYINTERFACE_BEGIN2(IFolderFolder) - MY_QUERYINTERFACE_ENTRY(IFolderAltStreams) - MY_QUERYINTERFACE_ENTRY(IFolderProperties) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps) - MY_QUERYINTERFACE_ENTRY(IFolderCompare) - MY_QUERYINTERFACE_ENTRY(IFolderGetItemName) - MY_QUERYINTERFACE_ENTRY(IArchiveFolder) - MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal) - MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) - MY_QUERYINTERFACE_ENTRY(IFolderSetZoneIdMode) - #ifdef NEW_FOLDER_INTERFACE - MY_QUERYINTERFACE_ENTRY(IFolderOperations) - MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE + Z7_COM_QI_BEGIN2(IFolderFolder) + Z7_COM_QI_ENTRY(IFolderAltStreams) + Z7_COM_QI_ENTRY(IFolderProperties) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IGetFolderArcProps) + Z7_COM_QI_ENTRY(IFolderCompare) + Z7_COM_QI_ENTRY(IFolderGetItemName) + Z7_COM_QI_ENTRY(IArchiveFolder) + Z7_COM_QI_ENTRY(IArchiveFolderInternal) + Z7_COM_QI_ENTRY(IInArchiveGetStream) + Z7_COM_QI_ENTRY(IFolderSetZoneIdMode) + Z7_COM_QI_ENTRY(IFolderSetZoneIdFile) + Z7_COM_QI_ENTRY(IFolderOperations) + Z7_COM_QI_ENTRY(IFolderSetFlatMode) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IFolderFolder) + Z7_IFACE_COM7_IMP(IFolderAltStreams) + Z7_IFACE_COM7_IMP(IFolderProperties) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IGetFolderArcProps) + Z7_IFACE_COM7_IMP(IFolderCompare) + Z7_IFACE_COM7_IMP(IFolderGetItemName) + Z7_IFACE_COM7_IMP(IArchiveFolder) + Z7_IFACE_COM7_IMP(IArchiveFolderInternal) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode) + Z7_IFACE_COM7_IMP(IFolderSetZoneIdFile) + Z7_IFACE_COM7_IMP(IFolderOperations) + Z7_IFACE_COM7_IMP(IFolderSetFlatMode) + void LoadFolder(unsigned proxyDirIndex); +public: HRESULT BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); HRESULT BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); int GetRealIndex(unsigned index) const; void GetRealIndices(const UInt32 *indices, UInt32 numItems, bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const; - INTERFACE_IFolderSetZoneIdMode(;) - - INTERFACE_FolderFolder(;) - INTERFACE_FolderAltStreams(;) - INTERFACE_FolderProperties(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IFolderGetItemName(;) - - STDMETHOD(GetFolderArcProps)(IFolderArcProps **object); - STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); int CompareItems3(UInt32 index1, UInt32 index2, PROPID propID); int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); - // IArchiveFolder - INTERFACE_IArchiveFolder(;) - - STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder); - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - - #ifdef NEW_FOLDER_INTERFACE - INTERFACE_FolderOperations(;) - - STDMETHOD(SetFlatMode)(Int32 flatMode); - #endif - CAgentFolder(): - _proxyDirIndex(0), _isAltStreamFolder(false), _flatMode(false), - _loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now - , _zoneMode(NExtract::NZoneIdMode::kNone) + _loadAltStreams(false), // _loadAltStreams alt streams works in flat mode, but we don't use it now + _proxyDirIndex(0), + _zoneMode(NExtract::NZoneIdMode::kNone) /* , _replaceAltStreamCharsMode(0) */ {} @@ -158,47 +148,49 @@ UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive public: + bool _isAltStreamFolder; + bool _flatMode; + bool _loadAltStreams; // in Flat mode const CProxyArc *_proxy; const CProxyArc2 *_proxy2; unsigned _proxyDirIndex; - bool _isAltStreamFolder; + NExtract::NZoneIdMode::EEnum _zoneMode; + CByteBuffer _zoneBuf; + // Int32 _replaceAltStreamCharsMode; // CMyComPtr _parentFolder; CMyComPtr _agent; CAgent *_agentSpec; - CRecordVector _items; - bool _flatMode; - bool _loadAltStreams; // in Flat mode - // Int32 _replaceAltStreamCharsMode; - NExtract::NZoneIdMode::EEnum _zoneMode; }; -class CAgent: + + +class CAgent Z7_final: public IInFolderArchive, public IFolderArcProps, - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public IOutFolderArchive, public ISetProperties, - #endif + #endif public CMyUnknownImp { -public: + Z7_COM_QI_BEGIN2(IInFolderArchive) + Z7_COM_QI_ENTRY(IFolderArcProps) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutFolderArchive) + Z7_COM_QI_ENTRY(ISetProperties) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE - MY_QUERYINTERFACE_BEGIN2(IInFolderArchive) - MY_QUERYINTERFACE_ENTRY(IFolderArcProps) - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutFolderArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE + Z7_IFACE_COM7_IMP(IInFolderArchive) + Z7_IFACE_COM7_IMP(IFolderArcProps) - INTERFACE_IInFolderArchive(;) - INTERFACE_IFolderArcProps(;) - - #ifndef EXTRACT_ONLY - INTERFACE_IOutFolderArchive(;) + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ISetProperties) +public: + Z7_IFACE_COM7_IMP(IOutFolderArchive) HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream, unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback); @@ -216,45 +208,44 @@ HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream, const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath, IFolderArchiveUpdateCallback *updateCallback100); + #endif - // ISetProperties - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif - - CAgent(); - ~CAgent(); private: HRESULT ReadItems(); + public: CProxyArc *_proxy; CProxyArc2 *_proxy2; CArchiveLink _archiveLink; - bool ThereIsPathProp; - // bool ThereIsAltStreamProp; - UString ArchiveType; FStringVector _names; FString _folderPrefix; // for new files from disk - bool _updatePathPrefix_is_AltFolder; UString _updatePathPrefix; CAgentFolder *_agentFolder; - UString _archiveFilePath; + UString _archiveFilePath; // it can be path of non-existing file if file is virtual + DWORD _attrib; + bool _updatePathPrefix_is_AltFolder; + bool ThereIsPathProp; bool _isDeviceFile; bool _isHashHandler; + FString _hashBaseFolderPrefix; - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY CObjectVector m_PropNames; CObjectVector m_PropValues; - #endif + #endif + + CAgent(); + ~CAgent(); const CArc &GetArc() const { return _archiveLink.Arcs.Back(); } - IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; } + IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return NULL; return GetArc().Archive; } bool CanUpdate() const; bool Is_Attrib_ReadOnly() const @@ -285,7 +276,7 @@ UString GetErrorMessage() const { UString s; - for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--) + for (int i = (int)_archiveLink.Arcs.Size() - 1; i >= 0; i--) { const CArc &arc = _archiveLink.Arcs[i]; @@ -326,23 +317,42 @@ } void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); } - }; -#ifdef NEW_FOLDER_INTERFACE +// #ifdef NEW_FOLDER_INTERFACE -class CArchiveFolderManager: - public IFolderManager, - public CMyUnknownImp +struct CCodecIcons { + struct CIconPair + { + UString Ext; + int IconIndex; + }; + CObjectVector IconPairs; + + // void Clear() { IconPairs.Clear(); } + void LoadIcons(HMODULE m); + bool FindIconIndex(const UString &ext, int &iconIndex) const; +}; + + +Z7_CLASS_IMP_COM_1( + CArchiveFolderManager + , IFolderManager +) + CObjectVector CodecIconsVector; + CCodecIcons InternalIcons; + bool WasLoaded; + void LoadFormats(); - int FindFormat(const UString &type); + // int FindFormat(const UString &type); public: - MY_UNKNOWN_IMP1(IFolderManager) - INTERFACE_IFolderManager(;) + CArchiveFolderManager(): + WasLoaded(false) + {} }; -#endif +// #endif #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentOut.cpp 2022-02-22 06:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentOut.cpp 2024-01-23 20:00:00.000000000 +0000 @@ -20,7 +20,7 @@ using namespace NWindows; using namespace NCOM; -STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder) +Z7_COM7F_IMF(CAgent::SetFolder(IFolderFolder *folder)) { _updatePathPrefix.Empty(); _updatePathPrefix_is_AltFolder = false; @@ -30,11 +30,12 @@ return S_OK; { - CMyComPtr afi; - RINOK(folder->QueryInterface(IID_IArchiveFolderInternal, (void **)&afi)); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveFolderInternal, + afi, folder) if (afi) { - RINOK(afi->GetAgentFolder(&_agentFolder)); + RINOK(afi->GetAgentFolder(&_agentFolder)) } if (!_agentFolder) return E_FAIL; @@ -47,8 +48,8 @@ return S_OK; } -STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix, - const wchar_t * const *names, UInt32 numNames) +Z7_COM7F_IMF(CAgent::SetFiles(const wchar_t *folderPrefix, + const wchar_t * const *names, UInt32 numNames)) { _folderPrefix = us2fs(folderPrefix); _names.ClearAndReserve(numNames); @@ -69,8 +70,8 @@ unsigned arcIndex = item.SubFiles[i]; const CProxyFile &fileItem = agent->_proxy->Files[arcIndex]; CArcItem ai; - RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime)); - RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined)); + RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime)) + RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined)) ai.IsDir = false; ai.Name = prefix + fileItem.Name; ai.Censored = true; // test it @@ -85,15 +86,15 @@ if (dirItem.IsLeaf()) { CArcItem ai; - RINOK(agent->GetArc().GetItem_MTime(dirItem.ArcIndex, ai.MTime)); + RINOK(agent->GetArc().GetItem_MTime((unsigned)dirItem.ArcIndex, ai.MTime)) ai.IsDir = true; ai.Size_Defined = false; ai.Name = fullName; ai.Censored = true; // test it - ai.IndexInServer = dirItem.ArcIndex; + ai.IndexInServer = (unsigned)dirItem.ArcIndex; arcItems.Add(ai); } - RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems)); + RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems)) } return S_OK; @@ -113,38 +114,38 @@ ai.IndexInServer = arcIndex; ai.Name = prefix + file.Name; ai.Censored = true; // test it - RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime)); + RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime)) ai.IsDir = file.IsDir(); ai.Size_Defined = false; ai.IsAltStream = file.IsAltStream; if (!ai.IsDir) { - RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined)); + RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined)) ai.IsDir = false; } arcItems.Add(ai); if (file.AltDirIndex != -1) { - RINOK(EnumerateArchiveItems2(agent, file.AltDirIndex, ai.Name + L':', arcItems)); + RINOK(EnumerateArchiveItems2(agent, (unsigned)file.AltDirIndex, ai.Name + L':', arcItems)) } if (ai.IsDir) { - RINOK(EnumerateArchiveItems2(agent, file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems)); + RINOK(EnumerateArchiveItems2(agent, (unsigned)file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems)) } } return S_OK; } -struct CAgUpCallbackImp: public IUpdateProduceCallback +struct CAgUpCallbackImp Z7_final: public IUpdateProduceCallback { const CObjectVector *_arcItems; IFolderArchiveUpdateCallback *_callback; CAgUpCallbackImp(const CObjectVector *a, IFolderArchiveUpdateCallback *callback): _arcItems(a), _callback(callback) {} - HRESULT ShowDeleteFile(unsigned arcIndex); + HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; }; HRESULT CAgUpCallbackImp::ShowDeleteFile(unsigned arcIndex) @@ -164,7 +165,7 @@ upd->ArcFileName = ExtractFileNameFromPath(arc.Path); } -struct CDirItemsCallback_AgentOut: public IDirItemsCallback +struct CDirItemsCallback_AgentOut Z7_final: public IDirItemsCallback { CMyComPtr FolderScanProgress; IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback; @@ -172,30 +173,28 @@ CDirItemsCallback_AgentOut(): FolderArchiveUpdateCallback(NULL), ErrorCode(S_OK) {} - HRESULT ScanError(const FString &name, DWORD systemError) + HRESULT ScanError(const FString &name, DWORD systemError) Z7_override { - HRESULT hres = HRESULT_FROM_WIN32(systemError); + const HRESULT hres = HRESULT_FROM_WIN32(systemError); if (FolderArchiveUpdateCallback) return FolderScanProgress->ScanError(fs2us(name), hres); ErrorCode = hres; return ErrorCode; } - HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) + HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) Z7_override { if (FolderScanProgress) return FolderScanProgress->ScanProgress(st.NumDirs, st.NumFiles + st.NumAltStreams, st.GetTotalBytes(), fs2us(path), BoolToInt(isDir)); - if (FolderArchiveUpdateCallback) return FolderArchiveUpdateCallback->SetNumFiles(st.NumFiles); - return S_OK; } }; -STDMETHODIMP CAgent::DoOperation( +Z7_COM7F_IMF(CAgent::DoOperation( FStringVector *requestedPaths, FStringVector *processedPaths, CCodecs *codecs, @@ -203,7 +202,7 @@ ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, - IFolderArchiveUpdateCallback *updateCallback100) + IFolderArchiveUpdateCallback *updateCallback100)) { if (!CanUpdate()) return E_NOTIMPL; @@ -226,9 +225,10 @@ { FString folderPrefix = _folderPrefix; - NFile::NName::NormalizeDirPathPrefix(folderPrefix); + if (!NFile::NName::IsAltStreamPrefixWithColon(fs2us(folderPrefix))) + NFile::NName::NormalizeDirPathPrefix(folderPrefix); - RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths)); + RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths)) if (_updatePathPrefix_is_AltFolder) { @@ -246,21 +246,21 @@ if (GetArchive()) { - RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)) } else { if (formatIndex < 0) return E_FAIL; - RINOK(codecs->CreateOutArchive(formatIndex, outArchive)); + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { CMyComPtr setCompressCodecsInfo; outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) } } #endif @@ -268,7 +268,7 @@ NFileTimeType::EEnum fileTimeType = NFileTimeType::kNotDefined; UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); + RINOK(outArchive->GetFileTimeType(&value)) // we support any future fileType here. // 22.00: fileTimeType = (NFileTimeType::EEnum)value; @@ -291,15 +291,15 @@ CObjectVector arcItems; if (GetArchive()) { - RINOK(ReadItems()); + RINOK(ReadItems()) if (_proxy2) { - RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems)); - RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems)); + RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems)) + RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems)) } else { - RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems)); + RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems)) } } @@ -321,21 +321,20 @@ if (updateCallback100) { - RINOK(updateCallback100->SetNumFiles(numFiles)); + RINOK(updateCallback100->SetNumFiles(numFiles)) } CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec ); + CMyComPtr2_Create updateCallback; - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->ArcItems = &arcItems; - updateCallbackSpec->UpdatePairs = &updatePairs2; + updateCallback->DirItems = &dirItems; + updateCallback->ArcItems = &arcItems; + updateCallback->UpdatePairs = &updatePairs2; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); - updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallback->Callback = &updateCallbackAgent; CByteBuffer processedItems; if (processedPaths) @@ -344,15 +343,17 @@ processedItems.Alloc(num); for (unsigned i = 0; i < num; i++) processedItems[i] = 0; - updateCallbackSpec->ProcessedItemsStatuses = processedItems; + updateCallback->ProcessedItemsStatuses = processedItems; } - CMyComPtr setProperties; - if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + Z7_DECL_CMyComPtr_QI_FROM( + ISetProperties, + setProperties, outArchive) + if (setProperties) { if (m_PropNames.Size() == 0) { - RINOK(setProperties->SetProperties(0, 0, 0)); + RINOK(setProperties->SetProperties(NULL, NULL, 0)) } else { @@ -365,7 +366,7 @@ { FOR_VECTOR (i, m_PropValues) propValues[i] = m_PropValues[i]; - RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size())); + RINOK(setProperties->SetProperties(names.ConstData(), propValues, names.Size())) } catch(...) { @@ -380,15 +381,14 @@ if (sfxModule != NULL) { - CInFileStream *sfxStreamSpec = new CInFileStream; - CMyComPtr sfxStream(sfxStreamSpec); - if (!sfxStreamSpec->Open(us2fs(sfxModule))) + CMyComPtr2_Create sfxStream; + if (!sfxStream->Open(us2fs(sfxModule))) return E_FAIL; // throw "Can't open sfx module"; - RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL)); + RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL)) } - HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback); + const HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback); if (res == S_OK && processedPaths) { { @@ -413,11 +413,11 @@ return res; } -STDMETHODIMP CAgent::DoOperation2( +Z7_COM7F_IMF(CAgent::DoOperation2( FStringVector *requestedPaths, FStringVector *processedPaths, ISequentialOutStream *outArchiveStream, - const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100) + const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100)) { return DoOperation(requestedPaths, processedPaths, g_CodecsObj, -1, outArchiveStream, stateActions, sfxModule, updateCallback100); } @@ -428,21 +428,20 @@ if (!CanUpdate()) return E_NOTIMPL; CMyComPtr outArchive; - RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)) return outArchive->UpdateItems(outArchiveStream, numUpdateItems, updateCallback); } -STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream, +Z7_COM7F_IMF(CAgent::DeleteItems(ISequentialOutStream *outArchiveStream, const UInt32 *indices, UInt32 numItems, - IFolderArchiveUpdateCallback *updateCallback100) + IFolderArchiveUpdateCallback *updateCallback100)) { if (!CanUpdate()) return E_NOTIMPL; CRecordVector updatePairs; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); + CMyComPtr2_Create updateCallback; CUIntVector realIndices; _agentFolder->GetRealIndices(indices, numItems, @@ -451,7 +450,7 @@ realIndices); unsigned curIndex = 0; UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) UString deletePath; @@ -460,8 +459,8 @@ if (curIndex < realIndices.Size()) if (realIndices[curIndex] == i) { - RINOK(GetArc().GetItem_Path2(i, deletePath)); - RINOK(updateCallback100->DeleteOperation(deletePath)); + RINOK(GetArc().GetItem_Path2(i, deletePath)) + RINOK(updateCallback100->DeleteOperation(deletePath)) curIndex++; continue; @@ -470,11 +469,11 @@ up2.SetAs_NoChangeArcItem(i); updatePairs.Add(up2); } - updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallback->UpdatePairs = &updatePairs; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); - updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallback->Callback = &updateCallbackAgent; return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); } @@ -487,11 +486,10 @@ CDirItems dirItems; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); + CMyComPtr2_Create updateCallback; UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) for (UInt32 i = 0; i < numItemsInArchive; i++) { CUpdatePair2 up2; @@ -524,11 +522,11 @@ dirItems.Items.Add(di); - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallback->Callback = &updateCallbackAgent; + updateCallback->DirItems = &dirItems; + updateCallback->UpdatePairs = &updatePairs; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); } @@ -547,8 +545,7 @@ CRecordVector updatePairs; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); + CMyComPtr2_Create updateCallback; CUIntVector realIndices; _agentFolder->GetRealIndices(indices, numItems, @@ -569,7 +566,7 @@ unsigned curIndex = 0; UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) for (UInt32 i = 0; i < numItemsInArchive; i++) { @@ -579,26 +576,26 @@ if (realIndices[curIndex] == i) { up2.NewProps = true; - RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)); // it must work without that line too. + RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)) // it must work without that line too. UString oldFullPath; - RINOK(GetArc().GetItem_Path2(i, oldFullPath)); + RINOK(GetArc().GetItem_Path2(i, oldFullPath)) if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath)) return E_INVALIDARG; - up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len())); + up2.NewNameIndex = (int)newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len())); up2.IsMainRenameItem = (mainRealIndex == (int)i); curIndex++; } updatePairs.Add(up2); } - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->UpdatePairs = &updatePairs; - updateCallbackSpec->NewNames = &newNames; + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; + updateCallback->NewNames = &newNames; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); } @@ -618,8 +615,7 @@ CRecordVector updatePairs; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); + CMyComPtr2_Create updateCallback; const int mainRealIndex = _agentFolder->GetRealIndex(indices[0]); @@ -627,7 +623,7 @@ return E_NOTIMPL; UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) UString newName = newItemName; @@ -640,12 +636,12 @@ updatePairs.Add(up2); } - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->UpdatePairs = &updatePairs; - updateCallbackSpec->CommentIndex = mainRealIndex; - updateCallbackSpec->Comment = &newName; + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; + updateCallback->CommentIndex = mainRealIndex; + updateCallback->Comment = &newName; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); } @@ -662,8 +658,7 @@ CDirItems dirItems; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); + CMyComPtr2_Create updateCallback; UInt32 realIndex; { @@ -686,7 +681,7 @@ } UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) for (UInt32 i = 0; i < numItemsInArchive; i++) { CUpdatePair2 up2; @@ -700,17 +695,17 @@ } updatePairs.Add(up2); } - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallback->DirItems = &dirItems; + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; - SetInArchiveInterfaces(this, updateCallbackSpec); + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); - updateCallbackSpec->KeepOriginalItemNames = true; + updateCallback->KeepOriginalItemNames = true; return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); } -STDMETHODIMP CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { m_PropNames.Clear(); m_PropValues.Clear(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.cpp 2022-01-25 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.cpp 2025-08-02 18:00:00.000000000 +0000 @@ -39,7 +39,7 @@ const unsigned dirIndex2 = subDirs[mid]; const int comp = CompareFileNames(name, Dirs[dirIndex2].Name); if (comp == 0) - return dirIndex2; + return (int)dirIndex2; if (comp < 0) right = mid; else @@ -77,18 +77,18 @@ if (item.ArcIndex == -1) item.ArcIndex = arcIndex; } - return subDirIndex; + return (unsigned)subDirIndex; } - subDirIndex = Dirs.Size(); - Dirs[dirIndex].SubDirs.Insert(insertPos, subDirIndex); + subDirIndex = (int)Dirs.Size(); + Dirs[dirIndex].SubDirs.Insert(insertPos, (unsigned)subDirIndex); CProxyDir &item = Dirs.AddNew(); item.NameLen = name.Len(); item.Name = AllocStringAndCopy(name); item.ArcIndex = arcIndex; - item.ParentDir = dirIndex; - return subDirIndex; + item.ParentDir = (int)dirIndex; + return (unsigned)subDirIndex; } void CProxyDir::Clear() @@ -97,14 +97,15 @@ SubFiles.Clear(); } -void CProxyArc::GetDirPathParts(int dirIndex, UStringVector &pathParts) const +void CProxyArc::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const { pathParts.Clear(); - while (dirIndex != -1) + // while (dirIndex != -1) + for (;;) { const CProxyDir &dir = Dirs[dirIndex]; - dirIndex = dir.ParentDir; - if (dirIndex == -1) + dirIndex = (unsigned)dir.ParentDir; + if (dir.ParentDir == -1) break; pathParts.Insert(0, dir.Name); // 22.00: we normalize name @@ -112,14 +113,15 @@ } } -UString CProxyArc::GetDirPath_as_Prefix(int dirIndex) const +UString CProxyArc::GetDirPath_as_Prefix(unsigned dirIndex) const { UString s; - while (dirIndex != -1) + // while (dirIndex != -1) + for (;;) { const CProxyDir &dir = Dirs[dirIndex]; - dirIndex = dir.ParentDir; - if (dirIndex == -1) + dirIndex = (unsigned)dir.ParentDir; + if (dir.ParentDir == -1) break; s.InsertAtFront(WCHAR_PATH_SEPARATOR); s.Insert(0, dir.Name); @@ -133,7 +135,7 @@ { const CProxyDir &dir = Dirs[dirIndex]; if (dir.IsLeaf()) - realIndices.Add(dir.ArcIndex); + realIndices.Add((unsigned)dir.ArcIndex); unsigned i; for (i = 0; i < dir.SubDirs.Size(); i++) AddRealIndices(dir.SubDirs[i], realIndices); @@ -144,7 +146,7 @@ int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const { const CProxyDir &dir = Dirs[dirIndex]; - unsigned numDirItems = dir.SubDirs.Size(); + const unsigned numDirItems = dir.SubDirs.Size(); if (index < numDirItems) { const CProxyDir &f = Dirs[dir.SubDirs[index]]; @@ -152,7 +154,7 @@ return f.ArcIndex; return -1; } - return dir.SubFiles[index - numDirItems]; + return (int)dir.SubFiles[index - numDirItems]; } void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const @@ -161,14 +163,14 @@ realIndices.Clear(); for (UInt32 i = 0; i < numItems; i++) { - UInt32 index = indices[i]; - unsigned numDirItems = dir.SubDirs.Size(); + const UInt32 index = indices[i]; + const unsigned numDirItems = dir.SubDirs.Size(); if (index < numDirItems) AddRealIndices(dir.SubDirs[index], realIndices); else realIndices.Add(dir.SubFiles[index - numDirItems]); } - HeapSort(&realIndices.Front(), realIndices.Size()); + HeapSort(realIndices.NonConstData(), realIndices.Size()); } /////////////////////////////////////////////// @@ -196,9 +198,9 @@ for (i = 0; i < dir.SubFiles.Size(); i++) { - UInt32 index = (UInt32)dir.SubFiles[i]; + const UInt32 index = (UInt32)dir.SubFiles[i]; UInt64 size, packSize; - bool sizeDefined = GetSize(archive, index, kpidSize, size); + const bool sizeDefined = GetSize(archive, index, kpidSize, size); dir.Size += size; GetSize(archive, index, kpidPackSize, packSize); dir.PackSize += packSize; @@ -242,10 +244,10 @@ IInArchive *archive = arc.Archive; UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) if (progress) - RINOK(progress->SetTotal(numItems)); + RINOK(progress->SetTotal(numItems)) Files.Alloc(numItems); @@ -258,7 +260,7 @@ if (progress && (i & 0xFFFF) == 0) { const UInt64 currentItemIndex = i; - RINOK(progress->SetCompleted(¤tItemIndex)); + RINOK(progress->SetCompleted(¤tItemIndex)) } const wchar_t *s = NULL; @@ -293,7 +295,7 @@ #endif { prop.Clear(); - RINOK(arc.Archive->GetProperty(i, kpidPath, &prop)); + RINOK(arc.Archive->GetProperty(i, kpidPath, &prop)) if (prop.vt == VT_BSTR) { s = prop.bstrVal; @@ -303,7 +305,7 @@ return E_FAIL; if (len == 0) { - RINOK(arc.GetItem_DefaultPath(i, path)); + RINOK(arc.GetItem_DefaultPath(i, path)) len = path.Len(); s = path; } @@ -370,7 +372,7 @@ */ bool isDir; - RINOK(Archive_IsItem_Dir(archive, i, isDir)); + RINOK(Archive_IsItem_Dir(archive, i, isDir)) CProxyFile &f = Files[i]; @@ -407,31 +409,32 @@ // ---------- for Tree-mode archive ---------- -void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const +void CProxyArc2::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const { pathParts.Clear(); isAltStreamDir = false; - if (dirIndex == (int)k_Proxy2_RootDirIndex) + if (dirIndex == k_Proxy2_RootDirIndex) return; - if (dirIndex == (int)k_Proxy2_AltRootDirIndex) + if (dirIndex == k_Proxy2_AltRootDirIndex) { isAltStreamDir = true; return; } - while (dirIndex >= (int)k_Proxy2_NumRootDirs) + while (dirIndex >= k_Proxy2_NumRootDirs) { const CProxyDir2 &dir = Dirs[dirIndex]; const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex]; - if (pathParts.IsEmpty() && dirIndex == file.AltDirIndex) + if (pathParts.IsEmpty() && (int)dirIndex == file.AltDirIndex) isAltStreamDir = true; pathParts.Insert(0, file.Name); - int par = file.Parent; + const int par = file.Parent; if (par == -1) break; - dirIndex = Files[(unsigned)par].DirIndex; + dirIndex = (unsigned)Files[(unsigned)par].DirIndex; + // if ((int)dirIndex == -1) break; } } @@ -465,9 +468,9 @@ realIndices.Add(arcIndex); const CProxyFile2 &file = Files[arcIndex]; if (file.DirIndex != -1) - AddRealIndices_of_Dir(file.DirIndex, includeAltStreams, realIndices); + AddRealIndices_of_Dir((unsigned)file.DirIndex, includeAltStreams, realIndices); if (includeAltStreams && file.AltDirIndex != -1) - AddRealIndices_of_Dir(file.AltDirIndex, includeAltStreams, realIndices); + AddRealIndices_of_Dir((unsigned)file.AltDirIndex, includeAltStreams, realIndices); } void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const @@ -492,7 +495,7 @@ { AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices); } - HeapSort(&realIndices.Front(), realIndices.Size()); + HeapSort(realIndices.NonConstData(), realIndices.Size()); } void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive) @@ -508,7 +511,7 @@ { UInt32 index = dir.Items[i]; UInt64 size, packSize; - bool sizeDefined = GetSize(archive, index, kpidSize, size); + const bool sizeDefined = GetSize(archive, index, kpidSize, size); dir.Size += size; GetSize(archive, index, kpidPackSize, packSize); dir.PackSize += packSize; @@ -538,7 +541,7 @@ dir.NumSubDirs++; CProxyDir2 &f = Dirs[subFile.DirIndex]; f.PathPrefix = dir.PathPrefix + s + WCHAR_PATH_SEPARATOR; - CalculateSizes(subFile.DirIndex, archive); + CalculateSizes((unsigned)subFile.DirIndex, archive); dir.Size += f.Size; dir.PackSize += f.PackSize; dir.NumSubFiles += f.NumSubFiles; @@ -557,7 +560,7 @@ // dir.NumSubDirs++; CProxyDir2 &f = Dirs[subFile.AltDirIndex]; f.PathPrefix = dir.PathPrefix + subFile.Name + L':'; - CalculateSizes(subFile.AltDirIndex, archive); + CalculateSizes((unsigned)subFile.AltDirIndex, archive); } } } @@ -589,9 +592,9 @@ IInArchive *archive = arc.Archive; UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) if (progress) - RINOK(progress->SetTotal(numItems)); + RINOK(progress->SetTotal(numItems)) UString fileName; @@ -617,7 +620,7 @@ if (progress && (i & 0xFFFFF) == 0) { UInt64 currentItemIndex = i; - RINOK(progress->SetCompleted(¤tItemIndex)); + RINOK(progress->SetCompleted(¤tItemIndex)) } CProxyFile2 &file = Files[i]; @@ -625,7 +628,7 @@ const void *p; UInt32 size; UInt32 propType; - RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType)); + RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType)) #ifdef MY_CPU_LE if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) @@ -633,7 +636,7 @@ file.Name = (const wchar_t *)p; file.NameLen = 0; if (size >= sizeof(wchar_t)) - file.NameLen = size / sizeof(wchar_t) - 1; + file.NameLen = size / (unsigned)sizeof(wchar_t) - 1; } else #endif @@ -648,7 +651,7 @@ else { NCOM::CPropVariant prop; - RINOK(arc.Archive->GetProperty(i, kpidName, &prop)); + RINOK(arc.Archive->GetProperty(i, kpidName, &prop)) const wchar_t *s; if (prop.vt == VT_BSTR) s = prop.bstrVal; @@ -663,13 +666,13 @@ UInt32 parent = (UInt32)(Int32)-1; UInt32 parentType = 0; - RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType)); + RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType)) file.Parent = (Int32)parent; if (arc.Ask_Deleted) { bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)); + RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)) if (isDeleted) { // continue; @@ -678,16 +681,16 @@ } bool isDir; - RINOK(Archive_IsItem_Dir(archive, i, isDir)); + RINOK(Archive_IsItem_Dir(archive, i, isDir)) if (isDir) { - file.DirIndex = Dirs.Size(); + file.DirIndex = (int)Dirs.Size(); CProxyDir2 &dir = Dirs.AddNew(); - dir.ArcIndex = i; + dir.ArcIndex = (int)i; } if (arc.Ask_AltStream) - RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream)); + RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream)) } for (i = 0; i < numItems; i++) @@ -704,7 +707,7 @@ int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex; if (folderIndex2 == -1) { - folderIndex2 = Dirs.Size(); + folderIndex2 = (int)Dirs.Size(); CProxyDir2 &dir = Dirs.AddNew(); dir.ArcIndex = file.Parent; } @@ -743,7 +746,7 @@ if (foldersOnly && file.DirIndex == -1) continue; if (CompareFileNames(file.Name, name) == 0) - return i; + return (int)i; } return -1; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.h 2022-01-08 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/AgentProxy.h 2023-01-19 15:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // AgentProxy.h -#ifndef __AGENT_PROXY_H -#define __AGENT_PROXY_H +#ifndef ZIP7_INC_AGENT_PROXY_H +#define ZIP7_INC_AGENT_PROXY_H #include "../Common/OpenArchive.h" @@ -34,7 +34,7 @@ UInt32 NumSubFiles; bool CrcIsDefined; - CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {}; + CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {} ~CProxyDir() { delete [](wchar_t *)(void *)Name; } void Clear(); @@ -54,9 +54,9 @@ // returns index in Dirs[], or -1, int FindSubDir(unsigned dirIndex, const wchar_t *name) const; - void GetDirPathParts(int dirIndex, UStringVector &pathParts) const; + void GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const; // returns full path of Dirs[dirIndex], including back slash - UString GetDirPath_as_Prefix(int dirIndex) const; + UString GetDirPath_as_Prefix(unsigned dirIndex) const; // AddRealIndices DOES ADD also item represented by dirIndex (if it's Leaf) void AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const; @@ -73,7 +73,7 @@ { int DirIndex; // >= 0 for dir. (index in ProxyArchive2->Dirs) int AltDirIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Dirs) - int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files) + int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files) const wchar_t *Name; unsigned NameLen; bool NeedDeleteName; @@ -109,7 +109,7 @@ UInt32 NumSubDirs; UInt32 NumSubFiles; - CProxyDir2(): ArcIndex(-1) {}; + CProxyDir2(): ArcIndex(-1) {} void AddFileSubItem(UInt32 index, const UString &name); void Clear(); }; @@ -130,7 +130,7 @@ bool IsThere_SubDir(unsigned dirIndex, const UString &name) const; - void GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const; + void GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const; UString GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const; bool IsAltDir(unsigned dirIndex) const; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolder.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolder.cpp 2022-06-01 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolder.cpp 2024-10-04 10:00:00.000000000 +0000 @@ -9,22 +9,29 @@ #include "Agent.h" /* -STDMETHODIMP CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCharsMode) +Z7_COM7F_IMF(CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCharsMode)) { _replaceAltStreamCharsMode = replaceAltStreamCharsMode; return S_OK; } */ -STDMETHODIMP CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode) +Z7_COM7F_IMF(CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)) { _zoneMode = zoneMode; return S_OK; } -STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, +Z7_COM7F_IMF(CAgentFolder::SetZoneIdFile(const Byte *data, UInt32 size)) +{ + _zoneBuf.CopyFrom(data, size); + return S_OK; +} + + +Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, - const wchar_t *path, IFolderOperationsExtractCallback *callback) + const wchar_t *path, IFolderOperationsExtractCallback *callback)) { if (moveMode) return E_NOTIMPL; @@ -32,7 +39,7 @@ CMyComPtr extractCallback2; { CMyComPtr callbackWrap = callback; - RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)); + RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)) } NExtract::NPathMode::EEnum pathMode; if (!_flatMode) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp 2020-06-07 13:35:11.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp 2023-04-01 14:00:00.000000000 +0000 @@ -2,26 +2,96 @@ #include "StdAfx.h" +// #ifdef NEW_FOLDER_INTERFACE + +#include "../../../Common/StringToInt.h" #include "../../../Windows/DLL.h" +#include "../../../Windows/ResourceString.h" #include "Agent.h" +extern HINSTANCE g_hInstance; +static const UINT kIconTypesResId = 100; + +void CCodecIcons::LoadIcons(HMODULE m) +{ + IconPairs.Clear(); + UString iconTypes; + NWindows::MyLoadString(m, kIconTypesResId, iconTypes); + UStringVector pairs; + SplitString(iconTypes, pairs); + FOR_VECTOR (i, pairs) + { + const UString &s = pairs[i]; + int pos = s.Find(L':'); + CIconPair iconPair; + iconPair.IconIndex = -1; + if (pos < 0) + pos = (int)s.Len(); + else + { + const UString num = s.Ptr((unsigned)pos + 1); + if (!num.IsEmpty()) + { + const wchar_t *end; + iconPair.IconIndex = (int)ConvertStringToUInt32(num, &end); + if (*end != 0) + continue; + } + } + iconPair.Ext = s.Left((unsigned)pos); + IconPairs.Add(iconPair); + } +} + +bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const +{ + iconIndex = -1; + FOR_VECTOR (i, IconPairs) + { + const CIconPair &pair = IconPairs[i]; + if (ext.IsEqualTo_NoCase(pair.Ext)) + { + iconIndex = pair.IconIndex; + return true; + } + } + return false; +} + + void CArchiveFolderManager::LoadFormats() { + if (WasLoaded) + return; + LoadGlobalCodecs(); + + #ifdef Z7_EXTERNAL_CODECS + CodecIconsVector.Clear(); + FOR_VECTOR (i, g_CodecsObj->Libs) + { + CCodecIcons &ci = CodecIconsVector.AddNew(); + ci.LoadIcons(g_CodecsObj->Libs[i].Lib.Get_HMODULE()); + } + #endif + InternalIcons.LoadIcons(g_hInstance); + WasLoaded = true; } +/* int CArchiveFolderManager::FindFormat(const UString &type) { FOR_VECTOR (i, g_CodecsObj->Formats) if (type.IsEqualTo_NoCase(g_CodecsObj->Formats[i].Name)) - return i; + return (int)i; return -1; } +*/ -STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream, +Z7_COM7F_IMF(CArchiveFolderManager::OpenFolderFile(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, - IFolderFolder **resultFolder, IProgress *progress) + IFolderFolder **resultFolder, IProgress *progress)) { CMyComPtr openArchiveCallback; if (progress) @@ -32,7 +102,7 @@ CAgent *agent = new CAgent(); CMyComPtr archive = agent; - HRESULT res = agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback); + const HRESULT res = archive->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback); if (res != S_OK) { @@ -44,7 +114,7 @@ return res; } - RINOK(agent->BindToRootFolder(resultFolder)); + RINOK(archive->BindToRootFolder(resultFolder)) return res; } @@ -58,7 +128,7 @@ /* -STDMETHODIMP CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *extensions) +Z7_COM7F_IMF(CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *extensions)) { *extensions = 0; int formatIndex = FindFormat(type); @@ -78,47 +148,52 @@ } } -STDMETHODIMP CArchiveFolderManager::GetExtensions(BSTR *extensions) + +Z7_COM7F_IMF(CArchiveFolderManager::GetExtensions(BSTR *extensions)) { + *extensions = NULL; LoadFormats(); - *extensions = 0; UString res; - #ifdef EXTERNAL_CODECS - + #ifdef Z7_EXTERNAL_CODECS + /* FOR_VECTOR (i, g_CodecsObj->Libs) - AddIconExt(g_CodecsObj->Libs[i], res); - + AddIconExt(g_CodecsObj->Libs[i].CodecIcons, res); + */ + FOR_VECTOR (i, CodecIconsVector) + AddIconExt(CodecIconsVector[i], res); #endif - AddIconExt(g_CodecsObj->InternalIcons, res); + AddIconExt( + // g_CodecsObj-> + InternalIcons, res); + return StringToBstr(res, extensions); } -STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) + +Z7_COM7F_IMF(CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex)) { - *iconPath = 0; + *iconPath = NULL; *iconIndex = 0; - LoadFormats(); - #ifdef EXTERNAL_CODECS - - FOR_VECTOR (i, g_CodecsObj->Libs) + #ifdef Z7_EXTERNAL_CODECS + // FOR_VECTOR (i, g_CodecsObj->Libs) + FOR_VECTOR (i, CodecIconsVector) { - const CCodecLib &lib = g_CodecsObj->Libs[i]; int ii; - if (lib.FindIconIndex(ext, ii)) + if (CodecIconsVector[i].FindIconIndex(ext, ii)) { + const CCodecLib &lib = g_CodecsObj->Libs[i]; *iconIndex = ii; return StringToBstr(fs2us(lib.Path), iconPath); } } - #endif int ii; - if (g_CodecsObj->InternalIcons.FindIconIndex(ext, ii)) + if (InternalIcons.FindIconIndex(ext, ii)) { FString path; if (NWindows::NDLL::MyGetModuleFileName(path)) @@ -131,7 +206,7 @@ } /* -STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types) +Z7_COM7F_IMF(CArchiveFolderManager::GetTypes(BSTR *types)) { LoadFormats(); UString typesStrings; @@ -146,9 +221,11 @@ } return StringToBstr(typesStrings, types); } -STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * type, - const wchar_t * filePath, IProgress progress) +Z7_COM7F_IMF(CArchiveFolderManager::CreateFolderFile(const wchar_t * type, + const wchar_t * filePath, IProgress progress)) { return E_NOTIMPL; } */ + +// #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp 2022-01-08 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp 2024-10-19 07:00:00.000000000 +0000 @@ -62,6 +62,33 @@ return RemoveDir(path); } + + +struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final: + public ICopyFileProgress +{ + IFolderArchiveUpdateCallback_MoveArc *Callback; + HRESULT CallbackResult; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // we can ignore E_ABORT here, because we update archive, + // and we want to get correct archive after updating + if (res == E_ABORT) + res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_FolderCallback_MoveArc( + IFolderArchiveUpdateCallback_MoveArc *callback) : + Callback(callback), + CallbackResult(S_OK) + {} +}; + + HRESULT CAgentFolder::CommonUpdateOperation( AGENT_OP operation, bool moveMode, @@ -83,7 +110,7 @@ try { - RINOK(_agentSpec->SetFolder(this)); + RINOK(_agentSpec->SetFolder(this)) // ---------- Save FolderItem ---------- @@ -95,7 +122,7 @@ FStringVector processedPaths; CWorkDirTempFile tempFile; - RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath))); + RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath))) { CMyComPtr tailStream; const CArc &arc = *_agentSpec->_archiveLink.GetArc(); @@ -106,8 +133,8 @@ { if (arc.Offset < 0) return E_NOTIMPL; - RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL)); + RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL)) CTailOutStream *tailStreamSpec = new CTailOutStream; tailStream = tailStreamSpec; tailStreamSpec->Stream = tempFile.OutStream; @@ -117,7 +144,7 @@ HRESULT result; - switch (operation) + switch ((int)operation) { case AGENT_OP_Delete: result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100); @@ -149,18 +176,61 @@ return E_FAIL; } - RINOK(result); + RINOK(result) } _agentSpec->KeepModeForNextOpen(); - _agentSpec->Close(); + _agent->Close(); // before 9.26: if there was error for MoveToOriginal archive was closed. // now: we reopen archive after close // m_FolderItem = NULL; + _items.Clear(); + _proxyDirIndex = k_Proxy_RootDirIndex; + + CMyComPtr updateCallback_MoveArc; + if (progress) + progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc); - HRESULT res = tempFile.MoveToOriginal(true); + HRESULT res; + if (updateCallback_MoveArc) + { + const FString &tempFilePath = tempFile.Get_TempFilePath(); + UInt64 totalSize = 0; + { + NFind::CFileInfo fi; + if (fi.Find(tempFilePath)) + totalSize = fi.Size; + } + RINOK(updateCallback_MoveArc->MoveArc_Start( + fs2us(tempFilePath), + fs2us(tempFile.Get_OriginalFilePath()), + totalSize, + 1)) // updateMode + + C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc); + res = tempFile.MoveToOriginal( + true, // deleteOriginal + &prox); + if (res == S_OK) + { + res = updateCallback_MoveArc->MoveArc_Finish(); + // we don't return after E_ABORT here, because + // we want to reopen new archive still. + } + else if (prox.CallbackResult != S_OK) + res = prox.CallbackResult; + + // if updating callback returned E_ABORT, + // then openCallback still can return E_ABORT also. + // So ReOpen() will return with E_ABORT. + // But we want to open archive still. + // And Before_ArcReopen() call will clear user break status in that case. + RINOK(updateCallback_MoveArc->Before_ArcReopen()) + } + else + res = tempFile.MoveToOriginal(true); // deleteOriginal // RINOK(res); if (res == S_OK) @@ -185,21 +255,21 @@ CMyComPtr openCallback; if (updateCallback100) updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback); - RINOK(_agentSpec->ReOpen(openCallback)); + RINOK(_agent->ReOpen(openCallback)) } // CAgent::ReOpen() deletes _proxy and _proxy2 - _items.Clear(); + // _items.Clear(); _proxy = NULL; _proxy2 = NULL; - _proxyDirIndex = k_Proxy_RootDirIndex; + // _proxyDirIndex = k_Proxy_RootDirIndex; _isAltStreamFolder = false; // ---------- Restore FolderItem ---------- CMyComPtr archiveFolder; - RINOK(_agentSpec->BindToRootFolder(&archiveFolder)); + RINOK(_agent->BindToRootFolder(&archiveFolder)) // CAgent::BindToRootFolder() changes _proxy and _proxy2 _proxy = _agentSpec->_proxy; @@ -209,10 +279,10 @@ { FOR_VECTOR (i, pathParts) { - int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]); + const int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]); if (next == -1) break; - _proxyDirIndex = next; + _proxyDirIndex = (unsigned)next; } } @@ -224,19 +294,19 @@ } else FOR_VECTOR (i, pathParts) { - bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder); - int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly); + const bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder); + const int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly); if (index == -1) break; const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]]; if (dirOnly) - _proxyDirIndex = file.DirIndex; + _proxyDirIndex = (unsigned)file.DirIndex; else { if (file.AltDirIndex != -1) - _proxyDirIndex = file.AltDirIndex; + _proxyDirIndex = (unsigned)file.AltDirIndex; break; } } @@ -295,7 +365,7 @@ { UString s2 ("Error: "); s2 += s; - RINOK(updateCallback100->UpdateErrorMessage(s2)); + RINOK(updateCallback100->UpdateErrorMessage(s2)) return E_FAIL; } throw; @@ -303,16 +373,15 @@ } - -STDMETHODIMP CAgentFolder::CopyFrom(Int32 moveMode, - const wchar_t *fromFolderPath, // test it +Z7_COM7F_IMF(CAgentFolder::CopyFrom(Int32 moveMode, + const wchar_t *fromFolderPath, /* test it */ const wchar_t * const *itemsPaths, UInt32 numItems, - IProgress *progress) + IProgress *progress)) { COM_TRY_BEGIN { - RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems)); + RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems)) return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL, &NUpdateArchive::k_ActionSet_Add, NULL, 0, progress); @@ -320,7 +389,7 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress) +Z7_COM7F_IMF(CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress)) { COM_TRY_BEGIN return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath, @@ -329,7 +398,7 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress) +Z7_COM7F_IMF(CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress)) { COM_TRY_BEGIN return CommonUpdateOperation(AGENT_OP_Delete, false, NULL, @@ -337,7 +406,7 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress) +Z7_COM7F_IMF(CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)) { COM_TRY_BEGIN @@ -359,7 +428,7 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress) +Z7_COM7F_IMF(CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)) { COM_TRY_BEGIN return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL, @@ -367,13 +436,13 @@ COM_TRY_END } -STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) +Z7_COM7F_IMF(CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)) { return E_NOTIMPL; } -STDMETHODIMP CAgentFolder::SetProperty(UInt32 index, PROPID propID, - const PROPVARIANT *value, IProgress *progress) +Z7_COM7F_IMF(CAgentFolder::SetProperty(UInt32 index, PROPID propID, + const PROPVARIANT *value, IProgress *progress)) { COM_TRY_BEGIN if (propID != kpidComment || value->vt != VT_BSTR) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/IFolderArchive.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/IFolderArchive.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/IFolderArchive.h 2022-06-01 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/IFolderArchive.h 2024-10-18 08:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // IFolderArchive.h -#ifndef __IFOLDER_ARCHIVE_H -#define __IFOLDER_ARCHIVE_H +#ifndef ZIP7_INC_IFOLDER_ARCHIVE_H +#define ZIP7_INC_IFOLDER_ARCHIVE_H #include "../../../Common/MyString.h" @@ -12,8 +12,7 @@ #include "../Common/ExtractMode.h" #include "../Common/IFileExtractCallback.h" -#define FOLDER_ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 0x01, x) -#define FOLDER_ARCHIVE_INTERFACE(i, x) FOLDER_ARCHIVE_INTERFACE_SUB(i, IUnknown, x) +Z7_PURE_INTERFACES_BEGIN /* ---------- IArchiveFolder ---------- IArchiveFolder is implemented by CAgentFolder (Agent/Agent.h) @@ -24,19 +23,16 @@ CPlugin::ExtractFiles */ -#define INTERFACE_IArchiveFolder(x) \ - STDMETHOD(Extract)(const UInt32 *indices, UInt32 numItems, \ +#define Z7_IFACEM_IArchiveFolder(x) \ + x(Extract(const UInt32 *indices, UInt32 numItems, \ Int32 includeAltStreams, \ Int32 replaceAltStreamCharsMode, \ NExtract::NPathMode::EEnum pathMode, \ NExtract::NOverwriteMode::EEnum overwriteMode, \ const wchar_t *path, Int32 testMode, \ - IFolderArchiveExtractCallback *extractCallback2) x; \ + IFolderArchiveExtractCallback *extractCallback2)) \ -FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x0D) -{ - INTERFACE_IArchiveFolder(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IArchiveFolder, 0x0D) /* ---------- IInFolderArchive ---------- @@ -44,85 +40,84 @@ IInFolderArchive Is used by FAR/Plugin */ -#define INTERFACE_IInFolderArchive(x) \ - STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \ - STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \ - STDMETHOD(Close)() x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) x; \ - STDMETHOD(Extract)(NExtract::NPathMode::EEnum pathMode, \ +#define Z7_IFACEM_IInFolderArchive(x) \ + x(Open(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback)) \ + x(ReOpen(IArchiveOpenCallback *openArchiveCallback)) \ + x(Close()) \ + x(GetNumberOfProperties(UInt32 *numProperties)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(BindToRootFolder(IFolderFolder **resultFolder)) \ + x(Extract(NExtract::NPathMode::EEnum pathMode, \ NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \ - Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \ + Int32 testMode, IFolderArchiveExtractCallback *extractCallback2)) \ -FOLDER_ARCHIVE_INTERFACE(IInFolderArchive, 0x0E) -{ - INTERFACE_IInFolderArchive(PURE) -}; - -#define INTERFACE_IFolderArchiveUpdateCallback(x) \ - STDMETHOD(CompressOperation)(const wchar_t *name) x; \ - STDMETHOD(DeleteOperation)(const wchar_t *name) x; \ - STDMETHOD(OperationResult)(Int32 opRes) x; \ - STDMETHOD(UpdateErrorMessage)(const wchar_t *message) x; \ - STDMETHOD(SetNumFiles)(UInt64 numFiles) x; \ - -FOLDER_ARCHIVE_INTERFACE_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B) -{ - INTERFACE_IFolderArchiveUpdateCallback(PURE) -}; - -#define INTERFACE_IOutFolderArchive(x) \ - STDMETHOD(SetFolder)(IFolderFolder *folder) x; \ - STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t * const *names, UInt32 numNames) x; \ - STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, \ - const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(DoOperation)( \ +Z7_IFACE_CONSTR_FOLDERARC(IInFolderArchive, 0x0E) + +#define Z7_IFACEM_IFolderArchiveUpdateCallback(x) \ + x(CompressOperation(const wchar_t *name)) \ + x(DeleteOperation(const wchar_t *name)) \ + x(OperationResult(Int32 opRes)) \ + x(UpdateErrorMessage(const wchar_t *message)) \ + x(SetNumFiles(UInt64 numFiles)) \ + +Z7_IFACE_CONSTR_FOLDERARC_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B) + +#define Z7_IFACEM_IOutFolderArchive(x) \ + x(SetFolder(IFolderFolder *folder)) \ + x(SetFiles(const wchar_t *folderPrefix, const wchar_t * const *names, UInt32 numNames)) \ + x(DeleteItems(ISequentialOutStream *outArchiveStream, \ + const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback)) \ + x(DoOperation( \ FStringVector *requestedPaths, \ FStringVector *processedPaths, \ CCodecs *codecs, int index, \ ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ - IFolderArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(DoOperation2)( \ + IFolderArchiveUpdateCallback *updateCallback)) \ + x(DoOperation2( \ FStringVector *requestedPaths, \ FStringVector *processedPaths, \ ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ - IFolderArchiveUpdateCallback *updateCallback) x; \ + IFolderArchiveUpdateCallback *updateCallback)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IOutFolderArchive, 0x0F) + + +#define Z7_IFACEM_IFolderArchiveUpdateCallback2(x) \ + x(OpenFileError(const wchar_t *path, HRESULT errorCode)) \ + x(ReadingFileError(const wchar_t *path, HRESULT errorCode)) \ + x(ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *path)) \ + x(ReportUpdateOperation(UInt32 notifyOp, const wchar_t *path, Int32 isDir)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback2, 0x10) + -FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0F) -{ - INTERFACE_IOutFolderArchive(PURE) -}; +#define Z7_IFACEM_IFolderScanProgress(x) \ + x(ScanError(const wchar_t *path, HRESULT errorCode)) \ + x(ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 isDir)) \ +Z7_IFACE_CONSTR_FOLDERARC(IFolderScanProgress, 0x11) -#define INTERFACE_IFolderArchiveUpdateCallback2(x) \ - STDMETHOD(OpenFileError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ReadingFileError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 isEncrypted, const wchar_t *path) x; \ - STDMETHOD(ReportUpdateOperation)(UInt32 notifyOp, const wchar_t *path, Int32 isDir) x; \ -FOLDER_ARCHIVE_INTERFACE(IFolderArchiveUpdateCallback2, 0x10) -{ - INTERFACE_IFolderArchiveUpdateCallback2(PURE) -}; +#define Z7_IFACEM_IFolderSetZoneIdMode(x) \ + x(SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)) \ +Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12) -#define INTERFACE_IFolderScanProgress(x) \ - STDMETHOD(ScanError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ScanProgress)(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 isDir) x; \ +#define Z7_IFACEM_IFolderSetZoneIdFile(x) \ + x(SetZoneIdFile(const Byte *data, UInt32 size)) \ -FOLDER_ARCHIVE_INTERFACE(IFolderScanProgress, 0x11) -{ - INTERFACE_IFolderScanProgress(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdFile, 0x13) -#define INTERFACE_IFolderSetZoneIdMode(x) \ - STDMETHOD(SetZoneIdMode)(NExtract::NZoneIdMode::EEnum zoneMode) x; \ +// if the caller calls Before_ArcReopen(), the callee must +// clear user break status, because the caller want to open archive still. +#define Z7_IFACEM_IFolderArchiveUpdateCallback_MoveArc(x) \ + x(MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) \ + x(MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) \ + x(MoveArc_Finish()) \ + x(Before_ArcReopen()) \ -FOLDER_ARCHIVE_INTERFACE(IFolderSetZoneIdMode, 0x12) -{ - INTERFACE_IFolderSetZoneIdMode(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback_MoveArc, 0x14) +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/StdAfx.h 2013-01-20 19:25:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp 2021-09-28 10:35:09.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp 2023-04-01 14:00:00.000000000 +0000 @@ -71,12 +71,12 @@ HRESULT CUpdateCallbackAgent::OpenFileError(const FString &path, DWORD systemError) { - HRESULT hres = HRESULT_FROM_WIN32(systemError); + const HRESULT hres = HRESULT_FROM_WIN32(systemError); // if (systemError == ERROR_SHARING_VIOLATION) { if (Callback2) { - RINOK(Callback2->OpenFileError(fs2us(path), hres)); + RINOK(Callback2->OpenFileError(fs2us(path), hres)) return S_FALSE; } @@ -86,7 +86,7 @@ s += NError::MyFormatMessage(systemError); s += ": "; s += fs2us(path); - RINOK(Callback->UpdateErrorMessage(s)); + RINOK(Callback->UpdateErrorMessage(s)) return S_FALSE; } } @@ -96,13 +96,13 @@ HRESULT CUpdateCallbackAgent::ReadingFileError(const FString &path, DWORD systemError) { - HRESULT hres = HRESULT_FROM_WIN32(systemError); + const HRESULT hres = HRESULT_FROM_WIN32(systemError); // if (systemError == ERROR_SHARING_VIOLATION) { if (Callback2) { - RINOK(Callback2->ReadingFileError(fs2us(path), hres)); + RINOK(Callback2->ReadingFileError(fs2us(path), hres)) } else if (Callback) { @@ -110,7 +110,7 @@ s += NError::MyFormatMessage(systemError); s += ": "; s += fs2us(path); - RINOK(Callback->UpdateErrorMessage(s)); + RINOK(Callback->UpdateErrorMessage(s)) } } // FailedFiles.Add(name); @@ -164,12 +164,12 @@ /* HRESULT CUpdateCallbackAgent::SetPassword(const UString & - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO password #endif ) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO PasswordIsDefined = true; Password = password; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.h 2015-01-07 08:45:19.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Agent/UpdateCallbackAgent.h 2023-01-28 20:00:00.000000000 +0000 @@ -1,15 +1,15 @@ // UpdateCallbackAgent.h -#ifndef __UPDATE_CALLBACK_AGENT_H -#define __UPDATE_CALLBACK_AGENT_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_AGENT_H +#define ZIP7_INC_UPDATE_CALLBACK_AGENT_H #include "../Common/UpdateCallback.h" #include "IFolderArchive.h" -class CUpdateCallbackAgent: public IUpdateCallbackUI +class CUpdateCallbackAgent Z7_final: public IUpdateCallbackUI { - INTERFACE_IUpdateCallbackUI(;) + Z7_IFACE_IMP(IUpdateCallbackUI) CMyComPtr _cryptoGetTextPassword; CMyComPtr Callback; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/Client7z.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/Client7z.cpp 2022-05-18 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.cpp 2024-03-13 06:00:00.000000000 +0000 @@ -5,10 +5,9 @@ #include #include "../../../Common/MyWindows.h" - -#include "../../../Common/Defs.h" #include "../../../Common/MyInitGuid.h" +#include "../../../Common/Defs.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" @@ -24,19 +23,26 @@ #include "../../Archive/IArchive.h" +#if 0 +// for password request functions: +#include "../../UI/Console/UserInputUtils.h" +#endif + #include "../../IPassword.h" #include "../../../../C/7zVersion.h" #ifdef _WIN32 extern HINSTANCE g_hInstance; -HINSTANCE g_hInstance = 0; +HINSTANCE g_hInstance = NULL; #endif +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + // You can find full list of all GUIDs supported by 7-Zip in Guid.txt file. // 7z format GUID: {23170F69-40C1-278A-1000-000110070000} -#define DEFINE_GUID_ARC(name, id) DEFINE_GUID(name, \ +#define DEFINE_GUID_ARC(name, id) Z7_DEFINE_GUID(name, \ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00); enum @@ -154,7 +160,7 @@ static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); + RINOK(archive->GetProperty(index, propID, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt == VT_EMPTY) @@ -177,18 +183,13 @@ // Archive Open callback class -class CArchiveOpenCallback: +class CArchiveOpenCallback Z7_final: public IArchiveOpenCallback, public ICryptoGetTextPassword, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(IArchiveOpenCallback, ICryptoGetTextPassword) public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); bool PasswordIsDefined; UString Password; @@ -196,25 +197,28 @@ CArchiveOpenCallback() : PasswordIsDefined(false) {} }; -STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)) { if (!PasswordIsDefined) { // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; +#if 0 + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else PrintError("Password is not defined"); return E_ABORT; +#endif } return StringToBstr(Password, password); } @@ -321,27 +325,14 @@ -class CArchiveExtractCallback: +class CArchiveExtractCallback Z7_final: public IArchiveExtractCallback, public ICryptoGetTextPassword, public CMyUnknownImp { -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - // IArchiveExtractCallback - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); - STDMETHOD(PrepareOperation)(Int32 askExtractMode); - STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); + Z7_IFACES_IMP_UNK_2(IArchiveExtractCallback, ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(IProgress) -private: CMyComPtr _archiveHandler; FString _directoryPath; // Output directory UString _filePath; // name inside arcvhive @@ -376,26 +367,26 @@ NName::NormalizeDirPathPrefix(_directoryPath); } -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, - ISequentialOutStream **outStream, Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) { - *outStream = 0; + *outStream = NULL; _outFileStream.Release(); { // Get Name NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) UString fullPath; if (prop.vt == VT_EMPTY) @@ -415,7 +406,7 @@ { // Get Attrib NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) { _processedFileInfo.Attrib = 0; @@ -430,13 +421,13 @@ } } - RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)); + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)) { _processedFileInfo.MTime.Clear(); // Get Modified Time NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) switch (prop.vt) { case VT_EMPTY: @@ -453,7 +444,7 @@ { // Get Size NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)) UInt64 newFileSize; /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize); } @@ -487,7 +478,7 @@ _outFileStreamSpec = new COutFileStream; CMyComPtr outStreamLoc(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS)) + if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath)) { PrintError("Cannot open output file", fullProcessedPath); return E_ABORT; @@ -498,13 +489,13 @@ return S_OK; } -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) { _extractMode = false; switch (askExtractMode) { case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; - }; + } switch (askExtractMode) { case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break; @@ -513,12 +504,12 @@ case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break; default: Print("??? "); break; - }; + } Print(_filePath); return S_OK; } -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 operationResult)) { switch (operationResult) { @@ -564,7 +555,7 @@ else { char temp[16]; - ConvertUInt32ToString(operationResult, temp); + ConvertUInt32ToString((UInt32)operationResult, temp); Print("Error #"); Print(temp); } @@ -579,7 +570,7 @@ _processedFileInfo.MTime.Write_To_FiTime(ft); _outFileStreamSpec->SetMTime(&ft); } - RINOK(_outFileStreamSpec->Close()); + RINOK(_outFileStreamSpec->Close()) } _outFileStream.Release(); if (_extractMode && _processedFileInfo.Attrib_Defined) @@ -589,15 +580,18 @@ } -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) { if (!PasswordIsDefined) { +#if 0 // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else PrintError("Password is not defined"); return E_ABORT; +#endif } return StringToBstr(Password, password); } @@ -617,28 +611,14 @@ {} }; -class CArchiveUpdateCallback: +class CArchiveUpdateCallback Z7_final: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp { -public: - MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - // IUpdateCallback2 - STDMETHOD(GetUpdateItemInfo)(UInt32 index, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); - STDMETHOD(SetOperationResult)(Int32 operationResult); - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); - - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + Z7_IFACES_IMP_UNK_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) public: CRecordVector VolumesSizes; @@ -675,18 +655,18 @@ } }; -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)) { if (newData) *newData = BoolToInt(true); @@ -697,7 +677,7 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; @@ -744,9 +724,9 @@ Print(name); } -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) { - RINOK(Finilize()); + RINOK(Finilize()) const CDirItem &dirItem = (*DirItems)[index]; GetStream2(dirItem.Path_For_Handler); @@ -760,8 +740,8 @@ FString path = DirPrefix + dirItem.FullPath; if (!inStreamSpec->Open(path)) { - DWORD sysError = ::GetLastError(); - FailedCodes.Add(sysError); + const DWORD sysError = ::GetLastError(); + FailedCodes.Add(HRESULT_FROM_WIN32(sysError)); FailedFiles.Add(path); // if (systemError == ERROR_SHARING_VIOLATION) { @@ -777,13 +757,13 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)) { m_NeedBeClosed = true; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) { if (VolumesSizes.Size() == 0) return S_FALSE; @@ -793,7 +773,7 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) { wchar_t temp[16]; ConvertUInt32ToString(index + 1, temp); @@ -801,28 +781,30 @@ while (res.Len() < 2) res.InsertAtFront(L'0'); UString fileName = VolName; - fileName += '.'; + fileName.Add_Dot(); fileName += res; fileName += VolExt; COutFileStream *streamSpec = new COutFileStream; CMyComPtr streamLoc(streamSpec); - if (!streamSpec->Create(us2fs(fileName), false)) - return ::GetLastError(); + if (!streamSpec->Create_NEW(us2fs(fileName))) + return GetLastError_noZero_HRESULT(); *volumeStream = streamLoc.Detach(); return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) { if (!PasswordIsDefined) { if (AskPassword) { - // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; +#if 0 + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else PrintError("Password is not defined"); return E_ABORT; +#endif } } *passwordIsDefined = BoolToInt(PasswordIsDefined); @@ -836,7 +818,7 @@ #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; #endif -int MY_CDECL main(int numArgs, const char *args[]) +int Z7_CDECL main(int numArgs, const char *args[]) { NT_CHECK @@ -872,8 +854,19 @@ return 1; } - Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject"); - if (!createObjectFunc) +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#ifdef _WIN32 +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + + Func_CreateObject + f_CreateObject = Z7_GET_PROC_ADDRESS( + Func_CreateObject, lib.Get_HMODULE(), + "CreateObject"); + if (!f_CreateObject) { PrintError("Cannot get CreateObject"); return 1; @@ -959,14 +952,14 @@ COutFileStream *outFileStreamSpec = new COutFileStream; CMyComPtr outFileStream = outFileStreamSpec; - if (!outFileStreamSpec->Create(archiveName, false)) + if (!outFileStreamSpec->Create_NEW(archiveName)) { PrintError("can't create archive file"); return 1; } CMyComPtr outArchive; - if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) + if (f_CreateObject(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) { PrintError("Cannot get class object"); return 1; @@ -986,7 +979,7 @@ L"s", L"x" }; - const unsigned kNumProps = ARRAY_SIZE(names); + const unsigned kNumProps = Z7_ARRAY_SIZE(names); NCOM::CPropVariant values[kNumProps] = { L"lzma", @@ -1048,7 +1041,7 @@ } CMyComPtr archive; - if (createObjectFunc(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) + if (f_CreateObject(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) { PrintError("Cannot get class object"); return 1; @@ -1088,7 +1081,7 @@ // Get uncompressed size of file NCOM::CPropVariant prop; archive->GetProperty(i, kpidSize, &prop); - char s[32]; + char s[64]; ConvertPropVariantToShortString(prop, s); Print(s); Print(" "); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/Client7z.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.dsp --- 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/Client7z.dsp 2016-12-02 09:58:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/Client7z.dsp 2024-03-20 07:00:00.000000000 +0000 @@ -104,6 +104,10 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\DLL.cpp # End Source File # Begin Source File @@ -144,6 +148,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -158,12 +166,28 @@ SOURCE=..\..\..\Windows\PropVariantConv.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File # End Group # Begin Group "Common" # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -172,6 +196,22 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -180,6 +220,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyVector.cpp # End Source File # Begin Source File @@ -188,6 +232,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -222,6 +270,54 @@ SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File # End Group # Begin Source File @@ -229,7 +325,7 @@ # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Sort.h +SOURCE=..\..\Archive\IArchive.h # End Source File # End Target # End Project diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/StdAfx.h 2013-01-22 16:33:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile --- 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/makefile 2021-03-08 10:12:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -21,6 +21,7 @@ $O\FileName.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ + $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ $O\FileStreams.obj \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/UI/Client7z/makefile.gcc 2022-07-15 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Client7z/makefile.gcc 2025-08-02 18:00:00.000000000 +0000 @@ -24,7 +24,6 @@ SYS_OBJS = \ $O/MyWindows.o \ - $O/TimeUtils.o \ endif @@ -53,12 +52,16 @@ $O/FileName.o \ $O/PropVariant.o \ $O/PropVariantConv.o \ + $O/TimeUtils.o \ 7ZIP_COMMON_OBJS = \ $O/FileStreams.o \ +C_OBJS = \ + $O/Alloc.o \ OBJS = \ + $(C_OBJS) \ $(COMMON_OBJS) \ $(WIN_OBJS) \ $(SYS_OBJS) \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 2022-06-01 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 2025-08-01 16:00:00.000000000 +0000 @@ -15,7 +15,7 @@ #include -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES #include "../../../../C/Alloc.h" #endif @@ -27,6 +27,7 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariantConv.h" #include "../../../Windows/System.h" #ifdef _WIN32 #include "../../../Windows/FileMapping.h" @@ -42,7 +43,7 @@ extern bool g_CaseSensitive; extern bool g_PathTrailReplaceMode; -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES extern bool g_LargePagesMode; bool g_LargePagesMode = false; @@ -62,17 +63,46 @@ #else -// #define MY_isatty_fileno(x) (isatty(fileno(x))) -// #define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); -static inline bool MY_IS_TERMINAL(FILE *x) -{ - return ( - #if defined(_MSC_VER) && (_MSC_VER >= 1400) - _isatty(_fileno(x)) - #else - isatty(fileno(x)) - #endif - != 0); +static bool MY_IS_TERMINAL(FILE *x) +{ +#ifdef _WIN32 + /* +crt/stdio.h: +typedef struct _iobuf FILE; +#define stdin (&_iob[0]) +#define stdout (&_iob[1]) +#define stderr (&_iob[2]) +*/ + // fprintf(stderr, "\nMY_IS_TERMINAL = %p", x); + const int fd = _fileno(x); + /* (fd) is 0, 1 or 2 in console program. + docs: If stdout or stderr is not associated with + an output stream (for example, in a Windows application + without a console window), the file descriptor returned is -2. + In previous versions, the file descriptor returned was -1. + */ + if (fd < 0) // is not associated with an output stream application (without a console window) + return false; + // fprintf(stderr, "\n\nstderr _fileno(%p) = %d", x, fd); + if (!_isatty(fd)) + return false; + // fprintf(stderr, "\nisatty_val = true"); + const HANDLE h = (HANDLE)_get_osfhandle(fd); + /* _get_osfhandle() returns intptr_t in new SDK, or long in MSVC6. + Also it can return (INVALID_HANDLE_VALUE). + docs: _get_osfhandle also returns the special value -2 when + the file descriptor is not associated with a stream + in old msvcrt.dll: it returns (-1) for incorrect value + */ + // fprintf(stderr, "\n_get_osfhandle() = %p", (void *)h); + if (h == NULL || h == INVALID_HANDLE_VALUE) + return false; + DWORD st; + // fprintf(stderr, "\nGetConsoleMode() = %u", (unsigned)GetConsoleMode(h, &st)); + return GetConsoleMode(h, &st) != 0; +#else + return isatty(fileno(x)) != 0; +#endif } #endif @@ -135,6 +165,7 @@ kHash, // kHashGenFile, kHashDir, + kExtractMemLimit, kStdIn, kStdOut, @@ -144,6 +175,8 @@ kConsoleCharSet, kTechMode, kListFields, + kListPathSlash, + kListTimestampUTC, kPreserveATime, kShareForWrite, @@ -174,7 +207,7 @@ kDeleteAfterCompressing, kSetArcMTime - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , kPassword #endif }; @@ -283,6 +316,7 @@ { "scrc", SWFRM_STRING_MULT(0) }, // { "scrf", SWFRM_STRING_SINGL(1) }, { "shd", SWFRM_STRING_SINGL(1) }, + { "smemx", SWFRM_STRING }, { "si", SWFRM_STRING }, { "so", SWFRM_SIMPLE }, @@ -292,6 +326,8 @@ { "scc", SWFRM_STRING }, { "slt", SWFRM_SIMPLE }, { "slf", SWFRM_STRING_SINGL(1) }, + { "slsl", SWFRM_MINUS }, + { "slmu", SWFRM_MINUS }, { "ssp", SWFRM_SIMPLE }, { "ssw", SWFRM_SIMPLE }, @@ -305,7 +341,7 @@ { "spf", SWFRM_STRING_SINGL(0) }, { "snh", SWFRM_MINUS }, - { "snld", SWFRM_MINUS }, + { "snld", SWFRM_STRING }, { "snl", SWFRM_MINUS }, { "sni", SWFRM_SIMPLE }, @@ -322,7 +358,7 @@ { "sdel", SWFRM_SIMPLE }, { "stl", SWFRM_SIMPLE } - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , { "p", SWFRM_STRING } #endif }; @@ -340,7 +376,7 @@ bool CArcCommand::IsFromExtractGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtract: @@ -353,7 +389,7 @@ NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtractFull: @@ -365,7 +401,7 @@ bool CArcCommand::IsFromUpdateGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kAdd: case NCommandType::kUpdate: @@ -438,7 +474,7 @@ { bool recursed = false; - switch (nop.RecursedType) + switch ((int)nop.RecursedType) { case NRecursedType::kWildcardOnlyRecursed: recursed = DoesNameContainWildcard(name); @@ -457,6 +493,7 @@ censor.AddPreItem(nop.Include, name, props); } +#ifndef Z7_EXTRACT_ONLY static void AddRenamePair(CObjectVector *renamePairs, const UString &oldName, const UString &newName, NRecursedType::EEnum type, bool wildcardMatching) @@ -481,6 +518,7 @@ throw CArcCmdLineException("Unsupported rename command:", val); } } +#endif static void AddToCensorFromListFile( CObjectVector *renamePairs, @@ -507,6 +545,7 @@ } if (renamePairs) { + #ifndef Z7_EXTRACT_ONLY if ((names.Size() & 1) != 0) throw CArcCmdLineException(kIncorrectListFile, fileName); for (unsigned i = 0; i < names.Size(); i += 2) @@ -514,6 +553,9 @@ // change type !!!! AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching); } + #else + throw "not implemented"; + #endif } else FOR_VECTOR (i, names) @@ -562,6 +604,7 @@ AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage); else if (renamePairs) { + #ifndef Z7_EXTRACT_ONLY if (oldIndex == -1) oldIndex = (int)i; else @@ -571,6 +614,9 @@ // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type); oldIndex = -1; } + #else + throw "not implemented"; + #endif } else AddNameToCensor(censor, nop, s); @@ -605,10 +651,10 @@ const CNameOption &nop) { UString s (s2); - int pos = s.Find(L':'); + const int pos = s.Find(L':'); if (pos < 0) return k_IncorrectMapCommand; - int pos2 = s.Find(L':', (unsigned)(pos + 1)); + const int pos2 = s.Find(L':', (unsigned)(pos + 1)); if (pos2 < 0) return k_IncorrectMapCommand; @@ -625,7 +671,7 @@ CFileMapping map; if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0) return "Cannot open mapping"; - LPVOID data = map.Map(FILE_MAP_READ, 0, size); + const LPVOID data = map.Map(FILE_MAP_READ, 0, size); if (!data) return "MapViewOfFile error"; CFileUnmapper unmapper(data); @@ -634,10 +680,10 @@ const wchar_t *p = (const wchar_t *)data; if (*p != 0) // data format marker return "Unsupported Map data"; - UInt32 numChars = size / sizeof(wchar_t); + const UInt32 numChars = size / sizeof(wchar_t); for (UInt32 i = 1; i < numChars; i++) { - wchar_t c = p[i]; + const wchar_t c = p[i]; if (c == 0) { // MessageBoxW(0, name, L"7-Zip", 0); @@ -905,7 +951,7 @@ CUpdateOptions &options) { NUpdateArchive::CActionSet defaultActionSet; - switch (commandType) + switch ((int)commandType) { case NCommandType::kAdd: defaultActionSet = NUpdateArchive::k_ActionSet_Add; @@ -944,8 +990,10 @@ FOR_VECTOR (i, sv) { UInt64 size; - if (!ParseComplexSize(sv[i], size) || size == 0) + if (!ParseComplexSize(sv[i], size)) throw CArcCmdLineException("Incorrect volume size:", sv[i]); + if (i == sv.Size() - 1 && size == 0) + throw CArcCmdLineException("zero size last volume is not allowed"); options.VolumesSizes.Add(size); } } @@ -992,7 +1040,7 @@ CArcCmdLineOptions &options) { Parse1Log.Empty(); - if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings)) + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine); options.IsInTerminal = MY_IS_TERMINAL(stdin); @@ -1000,6 +1048,7 @@ options.IsStdErrTerminal = MY_IS_TERMINAL(stderr); options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; + options.YesToAll = parser[NKey::kYes].ThereIs; options.StdInMode = parser[NKey::kStdIn].ThereIs; options.StdOutMode = parser[NKey::kStdOut].ThereIs; @@ -1009,9 +1058,19 @@ const UString &s = parser[NKey::kListFields].PostStrings[0]; options.ListFields = GetAnsiString(s); } + if (parser[NKey::kListPathSlash].ThereIs) + { + options.ListPathSeparatorSlash.Val = !parser[NKey::kListPathSlash].WithMinus; + options.ListPathSeparatorSlash.Def = true; + } + if (parser[NKey::kListTimestampUTC].ThereIs) + g_Timestamp_Show_UTC = !parser[NKey::kListTimestampUTC].WithMinus; options.TechMode = parser[NKey::kTechMode].ThereIs; options.ShowTime = parser[NKey::kShowTime].ThereIs; + if (parser[NKey::kDisablePercents].ThereIs) + options.DisablePercents = true; + if (parser[NKey::kDisablePercents].ThereIs || options.StdOutMode || !options.IsStdOutTerminal) @@ -1054,17 +1113,17 @@ if (parser[NKey::kLargePages].ThereIs) { - unsigned slp = 0; + UInt32 slp = 0; const UString &s = parser[NKey::kLargePages].PostStrings[0]; if (s.IsEmpty()) slp = 1; - else if (s != L"-") + else if (!s.IsEqualTo("-")) { if (!StringToUInt32(s, slp)) throw CArcCmdLineException("Unsupported switch postfix for -slp", s); } - #ifdef _7ZIP_LARGE_PAGES + #ifdef Z7_LARGE_PAGES if (slp > #if defined(_WIN32) && !defined(UNDER_CE) (unsigned)NSecurity::Get_LargePages_RiskLevel() @@ -1088,7 +1147,7 @@ } - #ifndef UNDER_CE +#ifndef UNDER_CE if (parser[NKey::kAffinity].ThereIs) { @@ -1099,7 +1158,9 @@ a.SetFromWStr_if_Ascii(s); Parse1Log += "Set process affinity mask: "; - #ifdef _WIN32 + bool isError = false; + +#ifdef _WIN32 UInt64 v = 0; { @@ -1109,61 +1170,62 @@ a.Empty(); } if (a.IsEmpty()) - throw CArcCmdLineException("Unsupported switch postfix -stm", s); - + isError = true; + else { - #ifndef _WIN64 +#ifndef _WIN64 if (v >= ((UInt64)1 << 32)) throw CArcCmdLineException("unsupported value -stm", s); - #endif + else +#endif { PrintHex(Parse1Log, v); if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v)) { - DWORD lastError = GetLastError(); + const DWORD lastError = GetLastError(); Parse1Log += " : ERROR : "; Parse1Log += NError::MyFormatMessage(lastError); } } } - #else // _WIN32 +#else // _WIN32 + if (a.Len() != s.Len()) + isError = true; + else { Parse1Log += a; NSystem::CProcessAffinity aff; aff.CpuZero(); - for (unsigned i = 0; i < a.Len(); i++) + unsigned cpu = 0; + unsigned i = a.Len(); + while (i) { - char c = a[i]; - unsigned v; - if (c >= '0' && c <= '9') v = (unsigned)(c - '0'); - else if (c >= 'A' && c <= 'F') v = 10 + (unsigned)(c - 'A'); - else if (c >= 'a' && c <= 'f') v = 10 + (unsigned)(c - 'a'); - else - throw CArcCmdLineException("Unsupported switch postfix -stm", s); - for (unsigned k = 0; k < 4; k++) - { - const unsigned cpu = (a.Len() - 1 - i) * 4 + k; - if (v & ((unsigned)1 << k)) + unsigned v = (Byte)a[--i]; + Z7_PARSE_HEX_DIGIT(v, { isError = true; break; }) + for (unsigned mask = 1; mask != 1u << 4; mask <<= 1, cpu++) + if (v & mask) aff.CpuSet(cpu); - } } - + if (!isError) if (!aff.SetProcAffinity()) { - DWORD lastError = GetLastError(); + const DWORD lastError = GetLastError(); Parse1Log += " : ERROR : "; Parse1Log += NError::MyFormatMessage(lastError); } } - #endif // _WIN32 +#endif // _WIN32 + + if (isError) + throw CArcCmdLineException("Unsupported switch postfix -stm", s); Parse1Log.Add_LF(); } } - #endif +#endif } @@ -1181,8 +1243,8 @@ { "utf-8", CP_UTF8 }, { "win", CP_ACP }, { "dos", CP_OEMCP }, - { "utf-16le", MY__CP_UTF16 }, - { "utf-16be", MY__CP_UTF16BE } + { "utf-16le", Z7_WIN_CP_UTF16 }, + { "utf-16be", Z7_WIN_CP_UTF16BE } }; static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex, @@ -1197,7 +1259,7 @@ if (v < ((UInt32)1 << 16)) return (Int32)v; name.MakeLower_Ascii(); - unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs); + const unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : Z7_ARRAY_SIZE(g_CodePagePairs); for (unsigned i = 0;; i++) { if (i == num) // to disable warnings from different compilers @@ -1216,6 +1278,40 @@ bp.Val = !parser[switchID].WithMinus; } + +static bool ParseSizeString(const wchar_t *s, UInt64 &res) +{ + const wchar_t *end; + const UInt64 v = ConvertStringToUInt64(s, &end); + if (s == end) + return false; + const wchar_t c = *end; + + if (c == 0) + { + res = v; + return true; + } + if (end[1] != 0) + return false; + + unsigned numBits; + switch (MyCharLower_Ascii(c)) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + const UInt64 val2 = v << numBits; + if ((val2 >> numBits) != v) + return false; + res = val2; + return true; +} + void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) { const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; @@ -1250,6 +1346,13 @@ if (parser[NKey::kHashDir].ThereIs) options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0]; + if (parser[NKey::kExtractMemLimit].ThereIs) + { + const UString &s = parser[NKey::kExtractMemLimit].PostStrings[0]; + if (!ParseSizeString(s, options.ExtractOptions.NtOptions.MemLimit)) + throw CArcCmdLineException("Unsupported -smemx:", s); + } + if (parser[NKey::kElimDup].ThereIs) { options.ExtractOptions.ElimDup.Def = true; @@ -1264,7 +1367,7 @@ const UString &s = parser[NKey::kFullPathMode].PostStrings[0]; if (!s.IsEmpty()) { - if (s == L"2") + if (s.IsEqualTo("2")) censorPathMode = NWildcard::k_FullPath; else throw CArcCmdLineException("Unsupported -spf:", s); @@ -1298,7 +1401,7 @@ options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); - UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); + const UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); bool thereAreSwitchIncludes = false; @@ -1326,6 +1429,7 @@ const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; const bool isRename = options.Command.CommandType == NCommandType::kRename; + options.UpdateOptions.RenameMode = isRename; if ((isExtractOrList || isRename) && options.StdInMode) thereIsArchiveName = false; @@ -1352,10 +1456,7 @@ nop, thereAreSwitchIncludes, codePage); - options.YesToAll = parser[NKey::kYes].ThereIs; - - - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO options.PasswordEnabled = parser[NKey::kPassword].ThereIs; if (options.PasswordEnabled) options.Password = parser[NKey::kPassword].PostStrings[0]; @@ -1378,14 +1479,8 @@ SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId); SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName); - - CBoolPair symLinks_AllowDangerous; - SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); - - /* bool supportSymLink = options.SymLinks.Val; - if (!options.SymLinks.Def) { if (isExtractOrList) @@ -1393,7 +1488,6 @@ else supportSymLink = false; } - #ifdef ENV_HAVE_LSTAT if (supportSymLink) global_use_lstat = 1; @@ -1402,7 +1496,6 @@ #endif */ - if (isExtractOrList) { CExtractOptionsBase &eo = options.ExtractOptions; @@ -1426,7 +1519,15 @@ if (!options.SymLinks.Def) nt.SymLinks.Val = true; - nt.SymLinks_AllowDangerous = symLinks_AllowDangerous; + if (parser[NKey::kSymLinks_AllowDangerous].ThereIs) + { + const UString &s = parser[NKey::kSymLinks_AllowDangerous].PostStrings[0]; + UInt32 v = 9; // default value for "-snld" instead of default = 5 without "-snld". + if (!s.IsEmpty()) + if (!StringToUInt32(s, v)) + throw CArcCmdLineException("Unsupported switch postfix -snld", s); + nt.SymLinks_DangerousLevel = (unsigned)v; + } nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; @@ -1445,9 +1546,9 @@ const UString &s = parser[NKey::kZoneFile].PostStrings[0]; if (!s.IsEmpty()) { - if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone; - else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll; - else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice; + if (s.IsEqualTo("0")) eo.ZoneMode = NExtract::NZoneIdMode::kNone; + else if (s.IsEqualTo("1")) eo.ZoneMode = NExtract::NZoneIdMode::kAll; + else if (s.IsEqualTo("2")) eo.ZoneMode = NExtract::NZoneIdMode::kOffice; else throw CArcCmdLineException("Unsupported -snz:", s); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.h 2022-04-17 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveCommandLine.h 2024-06-06 05:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ArchiveCommandLine.h -#ifndef __ARCHIVE_COMMAND_LINE_H -#define __ARCHIVE_COMMAND_LINE_H +#ifndef ZIP7_INC_ARCHIVE_COMMAND_LINE_H +#define ZIP7_INC_ARCHIVE_COMMAND_LINE_H #include "../../../Common/CommandLineParser.h" #include "../../../Common/Wildcard.h" @@ -60,11 +60,22 @@ bool StdInMode; bool StdOutMode; bool EnableHeaders; + bool DisablePercents; + bool YesToAll; bool ShowDialog; bool TechMode; bool ShowTime; + CBoolPair ListPathSeparatorSlash; + + CBoolPair NtSecurity; + CBoolPair AltStreams; + CBoolPair HardLinks; + CBoolPair SymLinks; + + CBoolPair StoreOwnerId; + CBoolPair StoreOwnerName; AString ListFields; @@ -75,7 +86,7 @@ CArcCommand Command; UString ArchiveName; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordEnabled; UString Password; #endif @@ -83,7 +94,7 @@ UStringVector HashMethods; // UString HashFilePath; - bool AppendName; + // bool AppendName; // UStringVector ArchivePathsSorted; // UStringVector ArchivePathsFullSorted; NWildcard::CCensor arcCensor; @@ -93,14 +104,6 @@ CExtractOptionsBase ExtractOptions; - CBoolPair NtSecurity; - CBoolPair AltStreams; - CBoolPair HardLinks; - CBoolPair SymLinks; - - CBoolPair StoreOwnerId; - CBoolPair StoreOwnerName; - CUpdateOptions UpdateOptions; CHashOptions HashOptions; UString ArcType; @@ -131,6 +134,7 @@ StdOutMode(false), EnableHeaders(false), + DisablePercents(false), YesToAll(false), ShowDialog(false), @@ -145,7 +149,13 @@ LogLevel(0) { - }; + ListPathSeparatorSlash.Val = +#ifdef _WIN32 + false; +#else + true; +#endif + } }; class CArcCmdLineParser diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2022-06-09 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2025-08-02 18:42:00.000000000 +0000 @@ -6,12 +6,10 @@ #undef printf // #include -// #include "../../../../C/CpuTicks.h" #include "../../../../C/Alloc.h" #include "../../../../C/CpuArch.h" - #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" @@ -25,14 +23,16 @@ #include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariantConv.h" -#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) -#define _USE_SECURITY_CODE +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif #include "../../Common/FilePathAutoRename.h" #include "../../Common/StreamUtils.h" +#include "../../Archive/Common/ItemNameUtils.h" + #include "../Common/ExtractingFilePath.h" #include "../Common/PropIDUtils.h" @@ -47,16 +47,35 @@ static const char * const kCantDeleteOutputFile = "Cannot delete output file"; static const char * const kCantDeleteOutputDir = "Cannot delete output folder"; static const char * const kCantOpenOutFile = "Cannot open output file"; +#ifndef Z7_SFX static const char * const kCantOpenInFile = "Cannot open input file"; +#endif static const char * const kCantSetFileLen = "Cannot set length for output file"; #ifdef SUPPORT_LINKS static const char * const kCantCreateHardLink = "Cannot create hard link"; static const char * const kCantCreateSymLink = "Cannot create symbolic link"; +static const char * const k_HardLink_to_SymLink_Ignored = "Hard link to symbolic link was ignored"; +static const char * const k_CantDelete_File_for_SymLink = "Cannot delete file for symbolic link creation"; +static const char * const k_CantDelete_Dir_for_SymLink = "Cannot delete directory for symbolic link creation"; #endif -#ifndef _SFX +static const unsigned k_LinkDataSize_LIMIT = 1 << 12; -STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize) +#ifdef SUPPORT_LINKS +#if WCHAR_PATH_SEPARATOR != L'/' + // we convert linux slashes to windows slashes for further processing. + // also we convert linux backslashes to BackslashReplacement character. + #define REPLACE_SLASHES_from_Linux_to_Sys(s) \ + { NArchive::NItemName::ReplaceToWinSlashes(s, true); } // useBackslashReplacement + // { s.Replace(L'/', WCHAR_PATH_SEPARATOR); } +#else + #define REPLACE_SLASHES_from_Linux_to_Sys(s) +#endif +#endif + +#ifndef Z7_SFX + +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -69,10 +88,10 @@ return result; } -#endif // _SFX +#endif // Z7_SFX -#ifdef _USE_SECURITY_CODE +#ifdef Z7_USE_SECURITY_CODE bool InitLocalPrivileges(); bool InitLocalPrivileges() { @@ -92,11 +111,11 @@ return false; return (GetLastError() == ERROR_SUCCESS); } -#endif // _USE_SECURITY_CODE +#endif // Z7_USE_SECURITY_CODE -#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) static const char * const kOfficeExtensions = " doc dot wbk" @@ -117,14 +136,14 @@ return false; AString s; - for (unsigned pos = dotPos + 1;; pos++) + for (unsigned pos = (unsigned)(dotPos + 1);; pos++) { const wchar_t c = name[pos]; if (c <= 0) break; if (c >= 0x80) return false; - s += (char)MyCharLower_Ascii((char)c); + s.Add_Char((char)MyCharLower_Ascii((char)c)); } for (unsigned i = 0; p[i] != 0;) { @@ -138,21 +157,25 @@ } -static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); +static const char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier"; -void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) +bool Is_ZoneId_StreamName(const wchar_t *s) { - FString fileName = fileName2; - fileName += k_ZoneId_StreamName; + return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1); +} +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf) +{ buf.Free(); + FString path (fileName); + path += k_ZoneId_StreamName_With_Colon_Prefix; NIO::CInFile file; - if (!file.Open(fileName)) + if (!file.Open(path)) return; UInt64 fileSize; if (!file.GetLength(fileSize)) return; - if (fileSize == 0 || fileSize >= ((UInt32)1 << 16)) + if (fileSize == 0 || fileSize >= (1u << 15)) return; buf.Alloc((size_t)fileSize); size_t processed; @@ -161,10 +184,12 @@ buf.Free(); } -static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf) +bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf) { + FString path (fileName); + path += k_ZoneId_StreamName_With_Colon_Prefix; NIO::COutFile file; - if (!file.Create(fileName, true)) + if (!file.Create_ALWAYS(path)) return false; return file.WriteFull(buf, buf.Size()); } @@ -188,13 +213,13 @@ defined = false; { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidINode, &prop)); + RINOK(archive->GetProperty(index, kpidINode, &prop)) if (!ConvertPropVariantToUInt64(prop, h.INode)) return S_OK; } { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidStreamId, &prop)); + RINOK(archive->GetProperty(index, kpidStreamId, &prop)) ConvertPropVariantToUInt64(prop, h.StreamId); } defined = true; @@ -209,7 +234,7 @@ if (!_arc->Ask_INode) return S_OK; - IInArchive *archive = _arc->Archive; + IInArchive * const archive = _arc->Archive; CRecordVector &hardIDs = _hardLinks.IDs; { @@ -218,22 +243,27 @@ numItems = realIndices->Size(); else { - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) } for (UInt32 i = 0; i < numItems; i++) { CHardLinkNode h; bool defined; - UInt32 realIndex = realIndices ? (*realIndices)[i] : i; + const UInt32 realIndex = realIndices ? (*realIndices)[i] : i; - RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)); + RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)) if (defined) { bool isAltStream = false; - RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)); + RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)) if (!isAltStream) - hardIDs.Add(h); + { + bool isDir = false; + RINOK(Archive_IsItem_Dir(archive, realIndex, isDir)) + if (!isDir) + hardIDs.Add(h); + } } } } @@ -266,16 +296,14 @@ CArchiveExtractCallback::CArchiveExtractCallback(): + // Write_CTime(true), + // Write_ATime(true), + // Write_MTime(true), + Is_elimPrefix_Mode(false), _arc(NULL), - Write_CTime(true), - Write_ATime(true), - Write_MTime(true), _multiArchives(false) { - LocalProgressSpec = new CLocalProgress(); - _localProgress = LocalProgressSpec; - - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } @@ -283,9 +311,9 @@ void CArchiveExtractCallback::InitBeforeNewArchive() { - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) ZoneBuf.Free(); - #endif +#endif } void CArchiveExtractCallback::Init( @@ -302,39 +330,35 @@ _outFileStream.Release(); _bufPtrSeqOutStream.Release(); - #ifdef SUPPORT_LINKS +#ifdef SUPPORT_LINKS _hardLinks.Clear(); - #endif + _postLinks.Clear(); +#endif - #ifdef SUPPORT_ALT_STREAMS +#ifdef SUPPORT_ALT_STREAMS _renamedFiles.Clear(); - #endif +#endif _ntOptions = ntOptions; _wildcardCensor = wildcardCensor; - _stdOutMode = stdOutMode; _testMode = testMode; - - // _progressTotal = 0; - // _progressTotal_Defined = false; - _packTotal = packSize; _progressTotal = packSize; - _progressTotal_Defined = true; - + // _progressTotal = 0; + // _progressTotal_Defined = false; + // _progressTotal_Defined = true; _extractCallback2 = extractCallback2; - + /* _compressProgress.Release(); _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); - _callbackMessage.Release(); - _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage); - + _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage); + */ _folderArchiveExtractCallback2.Release(); _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); - #ifndef _SFX + #ifndef Z7_SFX ExtractToStreamCallback.Release(); _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); @@ -355,7 +379,7 @@ _removePathParts = removePathParts; _removePartsForAltStreams = removePartsForAltStreams; - #ifndef _SFX + #ifndef Z7_SFX _baseParentFolder = (UInt32)(Int32)-1; _use_baseParentFolder_mode = false; #endif @@ -374,11 +398,11 @@ } -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size)) { COM_TRY_BEGIN _progressTotal = size; - _progressTotal_Defined = true; + // _progressTotal_Defined = true; if (!_multiArchives && _extractCallback2) return _extractCallback2->SetTotal(size); return S_OK; @@ -407,7 +431,7 @@ } -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)) { COM_TRY_BEGIN @@ -418,7 +442,7 @@ if (_multiArchives) { packCur = LocalProgressSpec->InSize; - if (completeValue && _progressTotal_Defined) + if (completeValue /* && _progressTotal_Defined */) packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal); completeValue = &packCur; } @@ -428,15 +452,16 @@ } -STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { COM_TRY_BEGIN - return _localProgress->SetRatioInfo(inSize, outSize); + return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize); COM_TRY_END } -void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath) +void CArchiveExtractCallback::CreateComplexDirectory( + const UStringVector &dirPathParts, bool isFinal, FString &fullPath) { // we use (_item.IsDir) in this function @@ -468,7 +493,7 @@ const UString &s = dirPathParts[i]; fullPath += us2fs(s); - const bool isFinalDir = (i == dirPathParts.Size() - 1 && _item.IsDir); + const bool isFinalDir = (i == dirPathParts.Size() - 1 && isFinal && _item.IsDir); if (fullPath.IsEmpty()) { @@ -490,16 +515,15 @@ } #endif - // bool res = - CreateDir(fullPath); - // if (!res) + HRESULT hres = S_OK; + if (!CreateDir(fullPath)) + hres = GetLastError_noZero_HRESULT(); if (isFinalDir) { if (!NFile::NFind::DoesDirExist(fullPath)) { _itemFailure = true; - SendMessageError("Cannot create folder", fullPath); - // SendMessageError_with_LastError() + SendMessageError_with_Error(hres, "Cannot create folder", fullPath); } } } @@ -510,7 +534,7 @@ { ft.Clear(); NCOM::CPropVariant prop; - RINOK(_arc->Archive->GetProperty(index, propID, &prop)); + RINOK(_arc->Archive->GetProperty(index, propID, &prop)) if (prop.vt == VT_FILETIME) ft.Set_From_Prop(prop); else if (prop.vt != VT_EMPTY) @@ -521,7 +545,7 @@ HRESULT CArchiveExtractCallback::GetUnpackSize() { - return _arc->GetItem_Size(_index, _curSize, _curSizeDefined); + return _arc->GetItem_Size(_index, _curSize, _curSize_Defined); } static void AddPathToMessage(UString &s, const FString &path) @@ -530,19 +554,18 @@ s += fs2us(path); } -HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path) +HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path) const { UString s (message); AddPathToMessage(s, path); return _extractCallback2->MessageError(s); } -HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) + +HRESULT CArchiveExtractCallback::SendMessageError_with_Error(HRESULT errorCode, const char *message, const FString &path) const { - DWORD errorCode = GetLastError(); - if (errorCode == 0) - errorCode = (DWORD)E_FAIL; UString s (message); + if (errorCode != S_OK) { s += " : "; s += NError::MyFormatMessage(errorCode); @@ -551,7 +574,13 @@ return _extractCallback2->MessageError(s); } -HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2) +HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) const +{ + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + return SendMessageError_with_Error(errorCode, message, path); +} + +HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2) const { UString s (message); if (errorCode != 0) @@ -564,15 +593,32 @@ return _extractCallback2->MessageError(s); } -#ifndef _SFX +HRESULT CArchiveExtractCallback::SendMessageError2_with_LastError( + const char *message, const FString &path1, const FString &path2) const +{ + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + return SendMessageError2(errorCode, message, path1, path2); +} + +#ifndef Z7_SFX + +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) +public: + UInt32 IndexInArc; + const CArc *Arc; + // UString BaseName; // relative path +}; -STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) { /* - if (propID == kpidName) + if (propID == kpidBaseName) { COM_TRY_BEGIN - NCOM::CPropVariant prop = Name; + NCOM::CPropVariant prop = BaseName; prop.Detach(value); return S_OK; COM_TRY_END @@ -581,41 +627,28 @@ return Arc->Archive->GetProperty(IndexInArc, propID, value); } -#endif // _SFX - - -#ifdef SUPPORT_LINKS - -static UString GetDirPrefixOf(const UString &src) -{ - UString s (src); - if (!s.IsEmpty()) - { - if (IsPathSepar(s.Back())) - s.DeleteBack(); - int pos = s.ReverseFind_PathSepar(); - s.DeleteFrom((unsigned)(pos + 1)); - } - return s; -} +#endif // Z7_SFX -#endif // SUPPORT_LINKS struct CLinkLevelsInfo { bool IsAbsolute; + bool ParentDirDots_after_NonParent; int LowLevel; int FinalLevel; - void Parse(const UString &path); + void Parse(const UString &path, bool isWSL); }; -void CLinkLevelsInfo::Parse(const UString &path) +void CLinkLevelsInfo::Parse(const UString &path, bool isWSL) { - IsAbsolute = NName::IsAbsolutePath(path); - + IsAbsolute = isWSL ? + IS_PATH_SEPAR(path[0]) : + NName::IsAbsolutePath(path); LowLevel = 0; FinalLevel = 0; + ParentDirDots_after_NonParent = false; + bool nonParentDir = false; UStringVector parts; SplitPathToParts(path, parts); @@ -630,32 +663,41 @@ IsAbsolute = true; continue; } - if (s == L".") + if (s.IsEqualTo(".")) continue; - if (s == L"..") + if (s.IsEqualTo("..")) { + if (IsAbsolute || nonParentDir) + ParentDirDots_after_NonParent = true; level--; if (LowLevel > level) - LowLevel = level; + LowLevel = level; } else + { + nonParentDir = true; level++; + } } FinalLevel = level; } -bool IsSafePath(const UString &path); -bool IsSafePath(const UString &path) +static bool IsSafePath(const UString &path, bool isWSL) { CLinkLevelsInfo levelsInfo; - levelsInfo.Parse(path); + levelsInfo.Parse(path, isWSL); return !levelsInfo.IsAbsolute && levelsInfo.LowLevel >= 0 && levelsInfo.FinalLevel > 0; } +bool IsSafePath(const UString &path); +bool IsSafePath(const UString &path) +{ + return IsSafePath(path, false); // isWSL +} bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include) @@ -685,7 +727,7 @@ if (pathParts2.IsEmpty()) pathParts2.AddNew(); UString &back = pathParts2.Back(); - back += ':'; + back.Add_Colon(); back += item.AltStreamName; bool include2; @@ -749,15 +791,15 @@ NIO::CInFile inFile; NIO::COutFile outFile; - if (!inFile.Open(_CopyFile_Path)) - return SendMessageError_with_LastError("Open error", _CopyFile_Path); + if (!inFile.Open(_copyFile_Path)) + return SendMessageError_with_LastError("Open error", _copyFile_Path); for (;;) { UInt32 num; if (!inFile.Read(buf.Buf, kBufSize, num)) - return SendMessageError_with_LastError("Read error", _CopyFile_Path); + return SendMessageError_with_LastError("Read error", _copyFile_Path); if (num == 0) return S_OK; @@ -771,159 +813,113 @@ HRESULT CArchiveExtractCallback::ReadLink() { - IInArchive *archive = _arc->Archive; + IInArchive * const archive = _arc->Archive; const UInt32 index = _index; - _link.Clear(); - + // _link.Clear(); // _link.Clear() was called already. { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidHardLink, &prop)); + RINOK(archive->GetProperty(index, kpidHardLink, &prop)) if (prop.vt == VT_BSTR) { - _link.isHardLink = true; - // _link.isCopyLink = false; + _link.LinkType = k_LinkType_HardLink; _link.isRelative = false; // RAR5, TAR: hard links are from root folder of archive - _link.linkPath.SetFromBstr(prop.bstrVal); + _link.LinkPath.SetFromBstr(prop.bstrVal); + // 7-Zip 24-: tar handler returned original path (with linux slash in most case) + // 7-Zip 24-: rar5 handler returned path with system slash. + // 7-Zip 25+: tar/rar5 handlers return linux path in most cases. } else if (prop.vt != VT_EMPTY) return E_FAIL; } - /* { NCOM::CPropVariant prop; RINOK(archive->GetProperty(index, kpidCopyLink, &prop)); if (prop.vt == VT_BSTR) { - _link.isHardLink = false; - _link.isCopyLink = true; + _link.LinkType = k_LinkType_CopyLink; _link.isRelative = false; // RAR5: copy links are from root folder of archive - _link.linkPath.SetFromBstr(prop.bstrVal); + _link.LinkPath.SetFromBstr(prop.bstrVal); } else if (prop.vt != VT_EMPTY) return E_FAIL; } */ - { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidSymLink, &prop)); + RINOK(archive->GetProperty(index, kpidSymLink, &prop)) if (prop.vt == VT_BSTR) { - _link.isHardLink = false; - // _link.isCopyLink = false; - _link.isRelative = true; // RAR5, TAR: symbolic links can be relative - _link.linkPath.SetFromBstr(prop.bstrVal); + _link.LinkType = k_LinkType_PureSymLink; + _link.isRelative = true; // RAR5, TAR: symbolic links are relative by default + _link.LinkPath.SetFromBstr(prop.bstrVal); + // 7-Zip 24-: (tar, cpio, xar, ext, iso) handlers returned returned original path (with linux slash in most case) + // 7-Zip 24-: rar5 handler returned path with system slash. + // 7-Zip 25+: all handlers return linux path in most cases. } else if (prop.vt != VT_EMPTY) return E_FAIL; } - NtReparse_Data = NULL; - NtReparse_Size = 0; - - if (_link.linkPath.IsEmpty() && _arc->GetRawProps) + // linux path separator in (_link.LinkPath) is expected for most cases, + // if new handler code is used, and if data in archive is correct. + // NtReparse_Data = NULL; + // NtReparse_Size = 0; + if (!_link.LinkPath.IsEmpty()) + { + REPLACE_SLASHES_from_Linux_to_Sys(_link.LinkPath) + } + else if (_arc->GetRawProps) { const void *data; - UInt32 dataSize; - UInt32 propType; - - _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType); - - // if (dataSize == 1234567) // for debug: unpacking without reparse - if (dataSize != 0) + UInt32 dataSize, propType; + if (_arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType) == S_OK + // && dataSize == 1234567 // for debug: unpacking without reparse + && dataSize) { if (propType != NPropDataType::kRaw) return E_FAIL; - // 21.06: we need kpidNtReparse in linux for wim archives created in Windows - // #ifdef _WIN32 - - NtReparse_Data = data; - NtReparse_Size = dataSize; - - CReparseAttr reparse; - bool isOkReparse = reparse.Parse((const Byte *)data, dataSize); - if (isOkReparse) - { - _link.isHardLink = false; - // _link.isCopyLink = false; - _link.linkPath = reparse.GetPath(); - _link.isJunction = reparse.IsMountPoint(); - - if (reparse.IsSymLink_WSL()) - { - _link.isWSL = true; - _link.isRelative = reparse.IsRelative_WSL(); - } - else - _link.isRelative = reparse.IsRelative_Win(); - - // const AString s = GetAnsiString(_link.linkPath); - // printf("\n_link.linkPath: %s\n", s.Ptr()); - - #ifndef _WIN32 - _link.linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); - #endif - } - // #endif + // NtReparse_Data = data; + // NtReparse_Size = dataSize; + // we ignore error code here, if there is failure of parsing: + _link.Parse_from_WindowsReparseData((const Byte *)data, dataSize); } } - if (_link.linkPath.IsEmpty()) + if (_link.LinkPath.IsEmpty()) return S_OK; - + // (_link.LinkPath) uses system path separator. + // windows: (_link.LinkPath) doesn't contain linux separator (slash). { - #ifdef _WIN32 - _link.linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - - // rar5 uses "\??\" prefix for absolute links - if (_link.linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR)) - { - _link.isRelative = false; - _link.linkPath.DeleteFrontal(4); - } - - for (;;) - // while (NName::IsAbsolutePath(linkPath)) + // _link.LinkPath = "\\??\\r:\\1\\2"; // for debug + // rar5+ returns kpidSymLink absolute link path with "\??\" prefix. + // we normalize such prefix: + if (_link.LinkPath.IsPrefixedBy(STRING_PATH_SEPARATOR "??" STRING_PATH_SEPARATOR)) { - unsigned n = NName::GetRootPrefixSize(_link.linkPath); - if (n == 0) - break; _link.isRelative = false; - _link.linkPath.DeleteFrontal(n); - } - } - - if (_link.linkPath.IsEmpty()) - return S_OK; - - if (!_link.isRelative && _removePathParts.Size() != 0) - { - UStringVector pathParts; - SplitPathToParts(_link.linkPath, pathParts); - bool badPrefix = false; - FOR_VECTOR (i, _removePathParts) - { - if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0) + // we normalize prefix from "\??\" to "\\?\": + _link.LinkPath.ReplaceOneCharAtPos(1, WCHAR_PATH_SEPARATOR); + _link.isWindowsPath = true; + if (_link.LinkPath.IsPrefixedBy_Ascii_NoCase( + STRING_PATH_SEPARATOR + STRING_PATH_SEPARATOR "?" + STRING_PATH_SEPARATOR "UNC" + STRING_PATH_SEPARATOR)) + { + // we normalize prefix from "\\?\UNC\path" to "\\path": + _link.LinkPath.DeleteFrontal(6); + _link.LinkPath.ReplaceOneCharAtPos(0, WCHAR_PATH_SEPARATOR); + } + else { - badPrefix = true; - break; + const unsigned k_prefix_Size = 4; + if (NName::IsDrivePath(_link.LinkPath.Ptr(k_prefix_Size))) + _link.LinkPath.DeleteFrontal(k_prefix_Size); } } - if (!badPrefix) - pathParts.DeleteFrontal(_removePathParts.Size()); - _link.linkPath = MakePathFromParts(pathParts); - } - - /* - if (!_link.linkPath.IsEmpty()) - { - printf("\n_link %s to -> %s\n", GetOemString(_item.Path).Ptr(), GetOemString(_link.linkPath).Ptr()); } - */ - + _link.Normalize_to_RelativeSafe(_removePathParts); return S_OK; } @@ -933,15 +929,15 @@ #ifndef _WIN32 static HRESULT GetOwner(IInArchive *archive, - UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res) + UInt32 index, UInt32 pidName, UInt32 pidId, CProcessedFileInfo::COwnerInfo &res) { { NWindows::NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, pidId, &prop)); + RINOK(archive->GetProperty(index, pidId, &prop)) if (prop.vt == VT_UI4) { res.Id_Defined = true; - res.Id = prop.ulVal; // for debug + res.Id = prop.ulVal; // res.Id++; // for debug // if (pidId == kpidGroupId) res.Id += 7; // for debug // res.Id = 0; // for debug @@ -951,7 +947,7 @@ } { NWindows::NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, pidName, &prop)); + RINOK(archive->GetProperty(index, pidName, &prop)) if (prop.vt == VT_BSTR) { const UString s = prop.bstrVal; @@ -973,7 +969,7 @@ HRESULT CArchiveExtractCallback::Read_fi_Props() { - IInArchive *archive = _arc->Archive; + IInArchive * const archive = _arc->Archive; const UInt32 index = _index; _fi.Attrib_Defined = false; @@ -981,11 +977,11 @@ #ifndef _WIN32 _fi.Owner.Clear(); _fi.Group.Clear(); - #endif + #endif { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidPosixAttrib, &prop)); + RINOK(archive->GetProperty(index, kpidPosixAttrib, &prop)) if (prop.vt == VT_UI4) { _fi.SetFromPosixAttrib(prop.ulVal); @@ -996,7 +992,7 @@ { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidAttrib, &prop)); + RINOK(archive->GetProperty(index, kpidAttrib, &prop)) if (prop.vt == VT_UI4) { _fi.Attrib = prop.ulVal; @@ -1006,9 +1002,9 @@ return E_FAIL; } - RINOK(GetTime(index, kpidCTime, _fi.CTime)); - RINOK(GetTime(index, kpidATime, _fi.ATime)); - RINOK(GetTime(index, kpidMTime, _fi.MTime)); + RINOK(GetTime(index, kpidCTime, _fi.CTime)) + RINOK(GetTime(index, kpidATime, _fi.ATime)) + RINOK(GetTime(index, kpidMTime, _fi.MTime)) #ifndef _WIN32 if (_ntOptions.ExtractOwner) @@ -1057,7 +1053,7 @@ UString &name = pathParts.Back(); if (needColon) - name += (char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':'); + name.Add_Char((char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':')); name += s; } @@ -1065,35 +1061,35 @@ } -void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) +static void GetFiTimesCAM(const CProcessedFileInfo &fi, CFiTimesCAM &pt, const CArc &arc) { pt.CTime_Defined = false; pt.ATime_Defined = false; pt.MTime_Defined = false; - if (Write_MTime) + // if (Write_MTime) { - if (_fi.MTime.Def) + if (fi.MTime.Def) { - _fi.MTime.Write_To_FiTime(pt.MTime); + fi.MTime.Write_To_FiTime(pt.MTime); pt.MTime_Defined = true; } - else if (_arc->MTime.Def) + else if (arc.MTime.Def) { - _arc->MTime.Write_To_FiTime(pt.MTime); + arc.MTime.Write_To_FiTime(pt.MTime); pt.MTime_Defined = true; } } - if (Write_CTime && _fi.CTime.Def) + if (/* Write_CTime && */ fi.CTime.Def) { - _fi.CTime.Write_To_FiTime(pt.CTime); + fi.CTime.Write_To_FiTime(pt.CTime); pt.CTime_Defined = true; } - if (Write_ATime && _fi.ATime.Def) + if (/* Write_ATime && */ fi.ATime.Def) { - _fi.ATime.Write_To_FiTime(pt.ATime); + fi.ATime.Write_To_FiTime(pt.ATime); pt.ATime_Defined = true; } } @@ -1104,31 +1100,75 @@ // 21.04 : we don't change original (_item.PathParts) here UStringVector pathParts = _item.PathParts; - if (!_item.IsDir) - { - if (!pathParts.IsEmpty()) + bool isFinal = true; + // bool is_DirOp = false; + if (!pathParts.IsEmpty()) + { + /* v23: if we extract symlink, and we know that it links to dir: + Linux: we don't create dir item (symlink_from_path) here. + Windows: SetReparseData() will create dir item, if it doesn't exist, + but if we create dir item here, it's not problem. */ + if (!_item.IsDir + #ifdef SUPPORT_LINKS + // #ifndef WIN32 + || !_link.LinkPath.IsEmpty() + // #endif + #endif + ) + { pathParts.DeleteBack(); + isFinal = false; // last path part was excluded + } + // else is_DirOp = true; } if (pathParts.IsEmpty()) - return; + { + /* if (_some_pathParts_wereRemoved && Is_elimPrefix_Mode), + then we can have empty pathParts() here for root folder. + v24.00: fixed: we set timestamps for such folder still. + */ + if (!_some_pathParts_wereRemoved || + !Is_elimPrefix_Mode) + return; + // return; // ignore empty paths case + } + /* + if (is_DirOp) + { + RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract)) + _op_WasReported = true; + } + */ FString fullPathNew; - CreateComplexDirectory(pathParts, fullPathNew); - + CreateComplexDirectory(pathParts, isFinal, fullPathNew); + + /* + if (is_DirOp) + { + RINOK(SetOperationResult( + // _itemFailure ? NArchive::NExtract::NOperationResult::kDataError : + NArchive::NExtract::NOperationResult::kOK + )) + } + */ + if (!_item.IsDir) return; + if (fullPathNew.IsEmpty()) + return; if (_itemFailure) return; CDirPathTime pt; - GetFiTimesCAM(pt); + GetFiTimesCAM(_fi, pt, *_arc); if (pt.IsSomeTimeDefined()) { pt.Path = fullPathNew; - pt.SetDirTime(); + pt.SetDirTime_to_FS_2(); _extractedFolders.Add(pt); } } @@ -1167,7 +1207,7 @@ RINOK(_extractCallback2->AskOverwrite( fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path, _fi.MTime.Def ? &_fi.MTime.FT : NULL, - _curSizeDefined ? &_curSize : NULL, + _curSize_Defined ? &_curSize : NULL, &overwriteResult)) switch (overwriteResult) @@ -1197,7 +1237,7 @@ { if (!AutoRenamePath(fullProcessedPath)) { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) return E_FAIL; } _isRenamed = true; @@ -1207,14 +1247,13 @@ FString existPath (fullProcessedPath); if (!AutoRenamePath(existPath)) { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) return E_FAIL; } // MyMoveFile can rename folders. So it's OK to use it for folders too if (!MyMoveFile(fullProcessedPath, existPath)) { - HRESULT errorCode = GetLastError_noZero_HRESULT(); - RINOK(SendMessageError2(errorCode, kCantRenameFile, existPath, fullProcessedPath)); + RINOK(SendMessageError2_with_LastError(kCantRenameFile, existPath, fullProcessedPath)) return E_FAIL; } } @@ -1225,7 +1264,7 @@ // do we need to delete all files in folder? if (!RemoveDir(fullProcessedPath)) { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)); + RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)) return S_OK; } } @@ -1235,7 +1274,7 @@ if (!DeleteFileAlways(fullProcessedPath)) if (GetLastError() != ERROR_FILE_NOT_FOUND) // check it in linux { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)); + RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)) return S_OK; // return E_FAIL; } @@ -1246,7 +1285,7 @@ { #if defined(_WIN32) && !defined(UNDER_CE) // we need to clear READ-ONLY of parent before creating alt stream - int colonPos = NName::FindAltStreamColon(fullProcessedPath); + const int colonPos = NName::FindAltStreamColon(fullProcessedPath); if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) { FString parentFsPath (fullProcessedPath); @@ -1255,7 +1294,11 @@ if (parentFi.Find(parentFsPath)) { if (parentFi.IsReadOnly()) + { + _altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath; + _altStream_NeedRestore_AttribVal = parentFi.Attrib; SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } } } #endif // defined(_WIN32) && !defined(UNDER_CE) @@ -1267,23 +1310,25 @@ - - - +/* +return: + needExit = false: caller will use (outStreamLoc) and _hashStreamSpec + needExit = true : caller will not use (outStreamLoc) and _hashStreamSpec. +*/ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr &outStreamLoc, bool &needExit) { needExit = true; - RINOK(Read_fi_Props()); + RINOK(Read_fi_Props()) #ifdef SUPPORT_LINKS - IInArchive *archive = _arc->Archive; + IInArchive * const archive = _arc->Archive; #endif const UInt32 index = _index; bool isAnti = false; - RINOK(_arc->IsItem_Anti(index, isAnti)); + RINOK(_arc->IsItem_Anti(index, isAnti)) CorrectPathParts(); UString processedPath (MakePathFromParts(_item.PathParts)); @@ -1309,7 +1354,7 @@ { const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex]; fullProcessedPath = pair.Path; - fullProcessedPath += ':'; + fullProcessedPath.Add_Colon(); UString s (_item.AltStreamName); Correct_AltStream_Name(s); fullProcessedPath += us2fs(s); @@ -1323,7 +1368,7 @@ if (isAnti) RemoveDir(_diskFilePath); #ifdef SUPPORT_LINKS - if (_link.linkPath.IsEmpty()) + if (_link.LinkPath.IsEmpty()) #endif { if (!isAnti) @@ -1333,7 +1378,7 @@ } else if (!_isSplit) { - RINOK(CheckExistFile(fullProcessedPath, needExit)); + RINOK(CheckExistFile(fullProcessedPath, needExit)) if (needExit) return S_OK; needExit = true; @@ -1352,33 +1397,36 @@ #ifdef SUPPORT_LINKS - if (!_link.linkPath.IsEmpty()) + if (!_link.LinkPath.IsEmpty()) { #ifndef UNDER_CE { bool linkWasSet = false; - RINOK(SetFromLinkPath(fullProcessedPath, _link, linkWasSet)); + RINOK(SetLink(fullProcessedPath, _link, linkWasSet)) +/* + // we don't set attributes for placeholder. if (linkWasSet) { - _isSymLinkCreated = _link.IsSymLink(); + _isSymLinkCreated = _link.Is_AnySymLink(); SetAttrib(); // printf("\nlinkWasSet %s\n", GetAnsiString(_diskFilePath)); } +*/ } #endif // UNDER_CE - // if (_CopyFile_Path.IsEmpty()) + // if (_copyFile_Path.IsEmpty()) { needExit = false; return S_OK; } } - if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream) + if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream && !_item.IsDir) { CHardLinkNode h; bool defined; - RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)); + RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)) if (defined) { const int linkIndex = _hardLinks.IDs.FindInSorted2(h); @@ -1389,16 +1437,17 @@ hl = fullProcessedPath; else { - if (!MyCreateHardLink(fullProcessedPath, hl)) - { - HRESULT errorCode = GetLastError_noZero_HRESULT(); - RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, hl)); + bool link_was_Created = false; + RINOK(CreateHardLink2(fullProcessedPath, hl, link_was_Created)) + if (!link_was_Created) return S_OK; - } - // printf("\nHard linkWasSet Archive_Get_HardLinkNode %s\n", GetAnsiString(_diskFilePath)); // _needSetAttrib = true; // do we need to set attribute ? SetAttrib(); + /* if we set (needExit = false) here, _hashStreamSpec will be used, + and hash will be calulated for all hard links files (it's slower). + But "Test" operation also calculates hashes. + */ needExit = false; return S_OK; } @@ -1412,13 +1461,13 @@ // ---------- CREATE WRITE FILE ----- _outFileStreamSpec = new COutFileStream; - CMyComPtr outFileStream_Loc(_outFileStreamSpec); + CMyComPtr outFileStream_Loc(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) + if (!_outFileStreamSpec->Create_ALWAYS_or_Open_ALWAYS(fullProcessedPath, !_isSplit)) { // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) { - RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath)); + RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath)) return S_OK; } } @@ -1427,7 +1476,7 @@ bool is_SymLink_in_Data = false; - if (_curSizeDefined && _curSize > 0 && _curSize < (1 << 12)) + if (_curSize_Defined && _curSize && _curSize < k_LinkDataSize_LIMIT) { if (_fi.IsLinuxSymLink()) { @@ -1449,20 +1498,20 @@ _bufPtrSeqOutStream_Spec->Init(_outMemBuf, _outMemBuf.Size()); outStreamLoc = _bufPtrSeqOutStream; } - else // not reprase + else // not reparse { - if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSizeDefined && _curSize > (1 << 12)) + if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSize_Defined && _curSize > (1 << 12)) { // UInt64 ticks = GetCpuTicks(); _fileLength_that_WasSet = _curSize; bool res = _outFileStreamSpec->File.SetLength(_curSize); - _fileLengthWasSet = res; + _fileLength_WasSet = res; // ticks = GetCpuTicks() - ticks; // printf("\nticks = %10d\n", (unsigned)ticks); if (!res) { - RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath)); + RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath)) } /* @@ -1484,7 +1533,7 @@ res = _outFileStreamSpec->SeekToBegin_bool(); if (!res) { - RINOK(SendMessageError_with_LastError("Cannot seek to begin of file", fullProcessedPath)); + RINOK(SendMessageError_with_LastError("Cannot seek to begin of file", fullProcessedPath)) } } // PreAllocateOutFile @@ -1501,10 +1550,10 @@ if (_isSplit) { - RINOK(_outFileStreamSpec->Seek((Int64)_position, STREAM_SEEK_SET, NULL)); + RINOK(outFileStream_Loc->Seek((Int64)_position, STREAM_SEEK_SET, NULL)) } outStreamLoc = outFileStream_Loc; - } // if not reprase + } // if not reparse _outFileStream = outFileStream_Loc; @@ -1516,7 +1565,7 @@ HRESULT CArchiveExtractCallback::GetItem(UInt32 index) { - #ifndef _SFX + #ifndef Z7_SFX _item._use_baseParentFolder_mode = _use_baseParentFolder_mode; if (_use_baseParentFolder_mode) { @@ -1525,7 +1574,7 @@ _pathMode == NExtract::NPathMode::kAbsPaths) _item._baseParentFolder = -1; } - #endif // _SFX + #endif // Z7_SFX #ifdef SUPPORT_ALT_STREAMS _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon; @@ -1535,13 +1584,13 @@ } -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) { COM_TRY_BEGIN *outStream = NULL; - #ifndef _SFX + #ifndef Z7_SFX if (_hashStream) _hashStreamSpec->ReleaseStream(); _hashStreamWasUsed = false; @@ -1551,34 +1600,36 @@ _bufPtrSeqOutStream.Release(); _encrypted = false; - _position = 0; _isSplit = false; - - _curSize = 0; - _curSizeDefined = false; - _fileLengthWasSet = false; - _fileLength_that_WasSet = 0; - _index = index; - - _diskFilePath.Empty(); - + _curSize_Defined = false; + _fileLength_WasSet = false; _isRenamed = false; - // _fi.Clear(); - - // _is_SymLink_in_Data = false; + _extractMode = false; _is_SymLink_in_Data_Linux = false; - _needSetAttrib = false; _isSymLinkCreated = false; _itemFailure = false; + _some_pathParts_wereRemoved = false; + // _op_WasReported = false; + + _position = 0; + _curSize = 0; + _fileLength_that_WasSet = 0; + _index = index; + +#if defined(_WIN32) && !defined(UNDER_CE) + _altStream_NeedRestore_AttribVal = 0; + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); +#endif + + _diskFilePath.Empty(); #ifdef SUPPORT_LINKS - // _CopyFile_Path.Empty(); + // _copyFile_Path.Empty(); _link.Clear(); #endif - _extractMode = false; switch (askExtractMode) { @@ -1590,16 +1641,17 @@ else _extractMode = true; break; - }; + default: break; + } - IInArchive *archive = _arc->Archive; + IInArchive * const archive = _arc->Archive; - RINOK(GetItem(index)); + RINOK(GetItem(index)) { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidPosition, &prop)); + RINOK(archive->GetProperty(index, kpidPosition, &prop)) if (prop.vt != VT_EMPTY) { if (prop.vt != VT_UI8) @@ -1609,14 +1661,13 @@ } } - #ifdef SUPPORT_LINKS - RINOK(ReadLink()); - #endif // SUPPORT_LINKS - +#ifdef SUPPORT_LINKS + RINOK(ReadLink()) +#endif - RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)); + RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)) - RINOK(GetUnpackSize()); + RINOK(GetUnpackSize()) #ifdef SUPPORT_ALT_STREAMS if (!_ntOptions.AltStreams.Val && _item.IsAltStream) @@ -1632,7 +1683,20 @@ return S_OK; } - #ifndef _SFX +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract + && !_testMode + && _item.IsAltStream + && ZoneBuf.Size() != 0 + && Is_ZoneId_StreamName(_item.AltStreamName)) + if (ZoneMode != NExtract::NZoneIdMode::kOffice + || _item.PathParts.IsEmpty() + || FindExt2(kOfficeExtensions, _item.PathParts.Back())) + return S_OK; +#endif + + + #ifndef Z7_SFX if (_use_baseParentFolder_mode) { if (!pathParts.IsEmpty()) @@ -1651,7 +1715,7 @@ } } else - #endif // _SFX + #endif // Z7_SFX { if (pathParts.IsEmpty()) { @@ -1667,7 +1731,7 @@ unsigned numRemovePathParts = 0; - switch (_pathMode) + switch ((int)_pathMode) { case NExtract::NPathMode::kFullPaths: case NExtract::NPathMode::kCurPaths: @@ -1713,7 +1777,10 @@ return E_FAIL; } else + { numRemovePathParts = _removePathParts.Size(); + _some_pathParts_wereRemoved = true; + } break; } @@ -1734,11 +1801,7 @@ numRemovePathParts = pathParts.Size() - 1; break; } - /* - case NExtract::NPathMode::kFullPaths: case NExtract::NPathMode::kAbsPaths: - break; - */ default: break; } @@ -1747,24 +1810,20 @@ } - #ifndef _SFX + #ifndef Z7_SFX if (ExtractToStreamCallback) { - if (!GetProp) - { - GetProp_Spec = new CGetProp; - GetProp = GetProp_Spec; - } - GetProp_Spec->Arc = _arc; - GetProp_Spec->IndexInArc = index; + CMyComPtr2_Create GetProp; + GetProp->Arc = _arc; + GetProp->IndexInArc = index; UString name (MakePathFromParts(pathParts)); - + // GetProp->BaseName = name; #ifdef SUPPORT_ALT_STREAMS if (_item.IsAltStream) { if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt)) - name += ':'; + name.Add_Colon(); name += _item.AltStreamName; } #endif @@ -1772,7 +1831,7 @@ return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp); } - #endif // _SFX + #endif // Z7_SFX CMyComPtr outStreamLoc; @@ -1784,13 +1843,13 @@ else { bool needExit = true; - RINOK(GetExtractStream(outStreamLoc, needExit)); + RINOK(GetExtractStream(outStreamLoc, needExit)) if (needExit) return S_OK; } } - #ifndef _SFX + #ifndef Z7_SFX if (_hashStream) { if (askExtractMode == NArchive::NExtract::NAskMode::kExtract || @@ -1802,13 +1861,13 @@ _hashStreamWasUsed = true; } } - #endif // _SFX + #endif // Z7_SFX if (outStreamLoc) { /* #ifdef SUPPORT_LINKS - if (!_CopyFile_Path.IsEmpty()) + if (!_copyFile_Path.IsEmpty()) { RINOK(PrepareOperation(askExtractMode)); RINOK(MyCopyFile(outStreamLoc)); @@ -1836,11 +1895,12 @@ -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) { COM_TRY_BEGIN - #ifndef _SFX + #ifndef Z7_SFX + // if (!_op_WasReported) if (ExtractToStreamCallback) return ExtractToStreamCallback->PrepareOperation7(askExtractMode); #endif @@ -1855,10 +1915,13 @@ else _extractMode = true; break; - }; + default: break; + } + + // if (_op_WasReported) return S_OK; return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir), - askExtractMode, _isSplit ? &_position: 0); + askExtractMode, _isSplit ? &_position: NULL); COM_TRY_END } @@ -1875,32 +1938,31 @@ HRESULT hres = S_OK; const UInt64 processedSize = _outFileStreamSpec->ProcessedSize; - if (_fileLengthWasSet && _fileLength_that_WasSet > processedSize) + if (_fileLength_WasSet && _fileLength_that_WasSet > processedSize) { - bool res = _outFileStreamSpec->File.SetLength(processedSize); - _fileLengthWasSet = res; + const bool res = _outFileStreamSpec->File.SetLength(processedSize); + _fileLength_WasSet = res; if (!res) { - HRESULT hres2 = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path)); + const HRESULT hres2 = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path)); if (hres == S_OK) hres = hres2; } } _curSize = processedSize; - _curSizeDefined = true; + _curSize_Defined = true; - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) if (ZoneBuf.Size() != 0 && !_item.IsAltStream) { // if (NFind::DoesFileExist_Raw(tempFilePath)) if (ZoneMode != NExtract::NZoneIdMode::kOffice || - FindExt2(kOfficeExtensions, _diskFilePath)) + FindExt2(kOfficeExtensions, fs2us(_diskFilePath))) { // we must write zone file before setting of timestamps - const FString path = _diskFilePath + k_ZoneId_StreamName; - if (!WriteZoneFile(path, ZoneBuf)) + if (!WriteZoneFile_To_BaseFile(_diskFilePath, ZoneBuf)) { // we can't write it in FAT // SendMessageError_with_LastError("Can't write Zone.Identifier stream", path); @@ -1910,7 +1972,7 @@ #endif CFiTimesCAM t; - GetFiTimesCAM(t); + GetFiTimesCAM(_fi, t, *_arc); // #ifdef _WIN32 if (t.IsSomeTimeDefined()) @@ -1920,91 +1982,292 @@ t.MTime_Defined ? &t.MTime : NULL); // #endif - RINOK(_outFileStreamSpec->Close()); + RINOK(_outFileStreamSpec->Close()) _outFileStream.Release(); + +#if defined(_WIN32) && !defined(UNDER_CE) + if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty()) + { + SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal); + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); + } +#endif + return hres; } #ifdef SUPPORT_LINKS +static bool CheckLinkPath_in_FS_for_pathParts(const FString &path, const UStringVector &v) +{ + FString path2 = path; + FOR_VECTOR (i, v) + { + // if (i == v.Size() - 1) path = path2; // we don't need last part in returned path + path2 += us2fs(v[i]); + NFind::CFileInfo fi; + // printf("\nCheckLinkPath_in_FS_for_pathParts(): %s\n", GetOemString(path2).Ptr()); + if (fi.Find(path2) && fi.IsOsSymLink()) + return false; + path2.Add_PathSepar(); + } + return true; +} -HRESULT CArchiveExtractCallback::SetFromLinkPath( - const FString &fullProcessedPath, - const CLinkInfo &linkInfo, - bool &linkWasSet) +/* +link.isRelative / relative_item_PathPrefix + false / empty + true / item path without last part +*/ +static bool CheckLinkPath_in_FS( + const FString &pathPrefix_in_FS, + const CPostLink &postLink, + const UString &relative_item_PathPrefix) { - linkWasSet = false; - if (!_ntOptions.SymLinks.Val && !linkInfo.isHardLink) - return S_OK; + const CLinkInfo &link = postLink.LinkInfo; + if (postLink.item_PathParts.IsEmpty() || link.LinkPath.IsEmpty()) + return false; + FString path; + { + const UString &s = postLink.item_PathParts[0]; + if (!s.IsEmpty() && !NName::IsAbsolutePath(s)) + path = pathPrefix_in_FS; // item_PathParts is relative. So we use absolutre prefix + } + if (!CheckLinkPath_in_FS_for_pathParts(path, postLink.item_PathParts)) + return false; + path += us2fs(relative_item_PathPrefix); + UStringVector v; + SplitPathToParts(link.LinkPath, v); + // we check target paths: + return CheckLinkPath_in_FS_for_pathParts(path, v); +} - UString relatPath; +static const unsigned k_DangLevel_MAX_for_Link_over_Link = 9; - /* if (linkInfo.isRelative) - linkInfo.linkPath is final link path that must be stored to file link field - else - linkInfo.linkPath is path from root of archive. So we must add _dirPathPrefix_Full before linkPath. - */ - - if (linkInfo.isRelative) - relatPath = GetDirPrefixOf(_item.Path); - relatPath += linkInfo.linkPath; - - if (!IsSafePath(relatPath)) +HRESULT CArchiveExtractCallback::CreateHardLink2( + const FString &newFilePath, const FString &existFilePath, bool &link_was_Created) const +{ + link_was_Created = false; + if (_ntOptions.SymLinks_DangerousLevel <= k_DangLevel_MAX_for_Link_over_Link) { - return SendMessageError2( - 0, // errorCode - "Dangerous link path was ignored", - us2fs(_item.Path), - us2fs(linkInfo.linkPath)); // us2fs(relatPath) + NFind::CFileInfo fi; + if (fi.Find(existFilePath) && fi.IsOsSymLink()) + return SendMessageError2(0, k_HardLink_to_SymLink_Ignored, newFilePath, existFilePath); } + if (!MyCreateHardLink(newFilePath, existFilePath)) + return SendMessageError2_with_LastError(kCantCreateHardLink, newFilePath, existFilePath); + link_was_Created = true; + return S_OK; +} + + + +HRESULT CArchiveExtractCallback::SetLink( + const FString &fullProcessedPath_from, + const CLinkInfo &link, + bool &linkWasSet) // placeholder was created +{ + linkWasSet = false; + if (link.LinkPath.IsEmpty()) + return S_OK; + if (!_ntOptions.SymLinks.Val && link.Is_AnySymLink()) + return S_OK; + CPostLink postLink; + postLink.Index_in_Arc = _index; + postLink.item_IsDir = _item.IsDir; + postLink.item_Path = _item.Path; + postLink.item_PathParts = _item.PathParts; + postLink.item_FileInfo = _fi; + postLink.fullProcessedPath_from = fullProcessedPath_from; + postLink.LinkInfo = link; + _postLinks.Add(postLink); + + // file doesn't exist in most cases. So we don't check for error. + DeleteLinkFileAlways_or_RemoveEmptyDir(fullProcessedPath_from, false); // checkThatFileIsEmpty = false + + NIO::COutFile outFile; + if (!outFile.Create_NEW(fullProcessedPath_from)) + return SendMessageError("Cannot create temporary link file", fullProcessedPath_from); +#if 0 // 1 for debug + // here we can write link path to temporary link file placeholder, + // but empty placeholder is better, because we don't want to get any non-eampty data instead of link file. + AString s; + ConvertUnicodeToUTF8(link.LinkPath, s); + outFile.WriteFull(s, s.Len()); +#endif + linkWasSet = true; + return S_OK; +} + - FString existPath; - if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */ || !linkInfo.isRelative) +// if file/dir is symbolic link it will remove only link itself +HRESULT CArchiveExtractCallback::DeleteLinkFileAlways_or_RemoveEmptyDir( + const FString &path, bool checkThatFileIsEmpty) const +{ + NFile::NFind::CFileInfo fi; + if (fi.Find(path)) // followLink = false { - if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath)) + if (fi.IsDir()) + { + if (RemoveDirAlways_if_Empty(path)) + return S_OK; + } + else { - RINOK(SendMessageError("Incorrect path", us2fs(relatPath))); + // link file placeholder must be empty + if (checkThatFileIsEmpty && !fi.IsOsSymLink() && fi.Size != 0) + return SendMessageError("Temporary link file is not empty", path); + if (DeleteFileAlways(path)) + return S_OK; } + if (GetLastError() != ERROR_FILE_NOT_FOUND) + return SendMessageError_with_LastError( + fi.IsDir() ? + k_CantDelete_Dir_for_SymLink: + k_CantDelete_File_for_SymLink, + path); + } + return S_OK; +} + + +/* +in: + link.LinkPath : must be relative (non-absolute) path in any case !!! + link.isRelative / target path that must stored as created link: + == false / _dirPathPrefix_Full + link.LinkPath + == true / link.LinkPath +*/ +static HRESULT SetLink2(const CArchiveExtractCallback &callback, + const CPostLink &postLink, bool &linkWasSet) +{ + const CLinkInfo &link = postLink.LinkInfo; + const FString &fullProcessedPath_from = postLink.fullProcessedPath_from; // full file path in FS (fullProcessedPath_from) + + const unsigned level = callback._ntOptions.SymLinks_DangerousLevel; + if (level < 20) + { + /* + We want to use additional check for links that can link to directory. + - linux: all symbolic links are files. + - windows: we can have file/directory symbolic link, + but file symbolic link works like directory link in windows. + So we use additional check for all relative links. + + We don't allow decreasing of final level of link. + So if some another extracted file will use this link, + then number of real path parts (after link redirection) cannot be + smaller than number of requested path parts from archive records. + + here we check only (link.LinkPath) without (_item.PathParts). + */ + CLinkLevelsInfo li; + li.Parse(link.LinkPath, link.Is_WSL()); + bool isDang; + UString relativePathPrefix; + if (li.IsAbsolute // unexpected + || li.ParentDirDots_after_NonParent + || (level <= 5 && link.isRelative && li.FinalLevel < 1) // final level lower + || (level <= 5 && link.isRelative && li.LowLevel < 0) // negative temporary levels + ) + isDang = true; + else // if (!isDang) + { + UString path; + if (link.isRelative) + { + // item_PathParts : parts that will be created in output folder. + // we want to get directory prefix of link item. + // so we remove file name (last non-empty part) from PathParts: + UStringVector v = postLink.item_PathParts; + while (!v.IsEmpty()) + { + const unsigned len = v.Back().Len(); + v.DeleteBack(); + if (len) + break; + } + path = MakePathFromParts(v); + NName::NormalizeDirPathPrefix(path); + relativePathPrefix = path; + } + path += link.LinkPath; + /* + path is calculated virtual target path of link + path is relative to root folder of extracted items + if (!link.isRelative), then (path == link.LinkPath) + */ + isDang = false; + if (!IsSafePath(path, link.Is_WSL())) + isDang = true; + } + const char *message = NULL; + if (isDang) + message = "Dangerous link path was ignored"; + else if (level <= k_DangLevel_MAX_for_Link_over_Link + && !CheckLinkPath_in_FS(callback._dirPathPrefix_Full, + postLink, relativePathPrefix)) + message = "Dangerous link via another link was ignored"; + if (message) + return callback.SendMessageError2(0, // errorCode + message, us2fs(postLink.item_Path), us2fs(link.LinkPath)); + } + + FString target; // target path that will be stored to link field + if (link.Is_HardLink() /* || link.IsCopyLink */ || !link.isRelative) + { + // isRelative == false + // all hard links and absolute symbolic links + // relatPath == link.LinkPath + // we get absolute link path for target: + if (!NName::GetFullPath(callback._dirPathPrefix_Full, us2fs(link.LinkPath), target)) + return callback.SendMessageError("Incorrect link path", us2fs(link.LinkPath)); + // (target) is (_dirPathPrefix_Full + relatPath) } else { - existPath = us2fs(linkInfo.linkPath); - // printf("\nlinkPath = : %s\n", GetOemString(linkInfo.linkPath).Ptr()); + // link.isRelative == true + // relative symbolic links only + target = us2fs(link.LinkPath); } - - if (existPath.IsEmpty()) - return SendMessageError("Empty link", fullProcessedPath); + if (target.IsEmpty()) + return callback.SendMessageError("Empty link", fullProcessedPath_from); - if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */) + if (link.Is_HardLink() /* || link.IsCopyLink */) { - // if (linkInfo.isHardLink) + // if (link.isHardLink) { - if (!MyCreateHardLink(fullProcessedPath, existPath)) + RINOK(callback.DeleteLinkFileAlways_or_RemoveEmptyDir(fullProcessedPath_from, true)) // checkThatFileIsEmpty { - HRESULT errorCode = GetLastError_noZero_HRESULT(); - RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, existPath)); + // RINOK(SendMessageError_with_LastError(k_Cant_DeleteTempLinkFile, fullProcessedPath_from)) } + return callback.CreateHardLink2(fullProcessedPath_from, target, linkWasSet); + /* + RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract)) + _op_WasReported = true; + RINOK(SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) linkWasSet = true; return S_OK; + */ } /* // IsCopyLink { NFind::CFileInfo fi; - if (!fi.Find(existPath)) + if (!fi.Find(target)) { - RINOK(SendMessageError2("Cannot find the file for copying", existPath, fullProcessedPath)); + RINOK(SendMessageError2("Cannot find the file for copying", target, fullProcessedPath)); } else { - if (_curSizeDefined && _curSize == fi.Size) - _CopyFile_Path = existPath; + if (_curSize_Defined && _curSize == fi.Size) + _copyFile_Path = target; else { - RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath)); + RINOK(SendMessageError2("File size collision for file copying", target, fullProcessedPath)); } - // RINOK(MyCopyFile(existPath, fullProcessedPath)); + // RINOK(MyCopyFile(target, fullProcessedPath)); } } */ @@ -2018,127 +2281,227 @@ // Windows before Vista doesn't support symbolic links. // we could convert such symbolic links to Junction Points // isJunction = true; - // convertToAbs = true; } */ - if (!_ntOptions.SymLinks_AllowDangerous.Val) - { - #ifdef _WIN32 - if (_item.IsDir) - #endif - if (linkInfo.isRelative) - { - CLinkLevelsInfo levelsInfo; - levelsInfo.Parse(linkInfo.linkPath); - if (levelsInfo.FinalLevel < 1 || levelsInfo.IsAbsolute) - { - return SendMessageError2( - 0, // errorCode - "Dangerous symbolic link path was ignored", - us2fs(_item.Path), - us2fs(linkInfo.linkPath)); - } - } - } +#ifdef _WIN32 + const bool isDir = (postLink.item_IsDir || link.LinkType == k_LinkType_Junction); +#endif - - #ifdef _WIN32 - + +#ifdef _WIN32 CByteBuffer data; - // printf("\nFillLinkData(): %s\n", GetOemString(existPath).Ptr()); - if (!FillLinkData(data, fs2us(existPath), !linkInfo.isJunction, linkInfo.isWSL)) - return SendMessageError("Cannot fill link data", us2fs(_item.Path)); - - /* - if (NtReparse_Size != data.Size() || memcmp(NtReparse_Data, data, data.Size()) != 0) + // printf("\nFillLinkData(): %s\n", GetOemString(target).Ptr()); + if (link.Is_WSL()) { - SendMessageError("reconstructed Reparse is different", fs2us(existPath)); + Convert_WinPath_to_WslLinuxPath(target, !link.isRelative); + FillLinkData_WslLink(data, fs2us(target)); } + else + FillLinkData_WinLink(data, fs2us(target), link.LinkType != k_LinkType_Junction); + if (data.Size() == 0) + return callback.SendMessageError("Cannot fill link data", us2fs(postLink.item_Path)); + /* + if (NtReparse_Size != data.Size() || memcmp(NtReparse_Data, data, data.Size()) != 0) + SendMessageError("reconstructed Reparse is different", fs2us(target)); */ - - CReparseAttr attr; - if (!attr.Parse(data, data.Size())) - { - RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path))); - return S_OK; - } - if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size())) { - RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath)); - return S_OK; + // we check that reparse data is correct, but we ignore attr.MinorError. + CReparseAttr attr; + if (!attr.Parse(data, data.Size())) + return callback.SendMessageError("Internal error for symbolic link file", us2fs(postLink.item_Path)); } - linkWasSet = true; - - return S_OK; - - - #else // ! _WIN32 +#endif - if (!NFile::NIO::SetSymLink(fullProcessedPath, existPath)) + RINOK(callback.DeleteLinkFileAlways_or_RemoveEmptyDir(fullProcessedPath_from, true)) // checkThatFileIsEmpty +#ifdef _WIN32 + if (!NFile::NIO::SetReparseData(fullProcessedPath_from, isDir, data, (DWORD)data.Size())) +#else // ! _WIN32 + if (!NFile::NIO::SetSymLink(fullProcessedPath_from, target)) +#endif // ! _WIN32 { - RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath)); - return S_OK; + return callback.SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath_from); } linkWasSet = true; - return S_OK; - - #endif // ! _WIN32 } -bool CLinkInfo::Parse(const Byte *data, size_t dataSize, bool isLinuxData) -{ - Clear(); - // this->isLinux = isLinuxData; - - if (isLinuxData) - { - isJunction = false; - isHardLink = false; - AString utf; - if (dataSize >= (1 << 12)) - return false; - utf.SetFrom_CalcLen((const char *)data, (unsigned)dataSize); - UString u; - if (!ConvertUTF8ToUnicode(utf, u)) - return false; - linkPath = u; - - // in linux symbolic data: we expect that linux separator '/' is used - // if windows link was created, then we also must use linux separator - if (u.IsEmpty()) - return false; - wchar_t c = u[0]; - isRelative = !IS_PATH_SEPAR(c); - return true; - } +bool CLinkInfo::Parse_from_WindowsReparseData(const Byte *data, size_t dataSize) +{ CReparseAttr reparse; if (!reparse.Parse(data, dataSize)) return false; - isHardLink = false; - // isCopyLink = false; - linkPath = reparse.GetPath(); - isJunction = reparse.IsMountPoint(); - + // const AString s = GetAnsiString(LinkPath); + // printf("\nlinkPath: %s\n", s.Ptr()); + LinkPath = reparse.GetPath(); if (reparse.IsSymLink_WSL()) { - isWSL = true; - isRelative = reparse.IsRelative_WSL(); + LinkType = k_LinkType_WSL; + isRelative = reparse.IsRelative_WSL(); // detected from LinkPath[0] + // LinkPath is original raw name converted to UString from AString + // Linux separator '/' is expected here. + REPLACE_SLASHES_from_Linux_to_Sys(LinkPath) } else - isRelative = reparse.IsRelative_Win(); - - // FIXME !!! - #ifndef _WIN32 - linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); - #endif - + { + LinkType = reparse.IsMountPoint() ? k_LinkType_Junction : k_LinkType_PureSymLink; + isRelative = reparse.IsRelative_Win(); // detected by (Flags == Z7_WIN_SYMLINK_FLAG_RELATIVE) + isWindowsPath = true; + // LinkPath is original windows link path from raparse data with \??\ prefix removed. + // windows '\\' separator is expected here. + // linux '/' separator is not expected here. + // we translate both types of separators to system separator. + LinkPath.Replace( +#if WCHAR_PATH_SEPARATOR == L'\\' + L'/' +#else + L'\\' +#endif + , WCHAR_PATH_SEPARATOR); + } + // (LinkPath) uses system path separator. + // windows: (LinkPath) doesn't contain linux separator (slash). + return true; +} + + +bool CLinkInfo::Parse_from_LinuxData(const Byte *data, size_t dataSize) +{ + // Clear(); // *this object was cleared by constructor already. + LinkType = k_LinkType_PureSymLink; + AString utf; + if (dataSize >= k_LinkDataSize_LIMIT) + return false; + utf.SetFrom_CalcLen((const char *)data, (unsigned)dataSize); + UString u; + if (!ConvertUTF8ToUnicode(utf, u)) + return false; + if (u.IsEmpty()) + return false; + const wchar_t c = u[0]; + isRelative = (c != L'/'); + // linux path separator is expected + REPLACE_SLASHES_from_Linux_to_Sys(u) + LinkPath = u; + // (LinkPath) uses system path separator. + // windows: (LinkPath) doesn't contain linux separator (slash). return true; } + +// in/out: (LinkPath) uses system path separator +// in/out: windows: (LinkPath) doesn't contain linux separator (slash). +// out: (LinkPath) is relative path, and LinkPath[0] is not path separator +// out: isRelative changed to false, if any prefix was removed. +// note: absolute windows links "c:\" to root will be reduced to empty string: +void CLinkInfo::Remove_AbsPathPrefixes() +{ + while (!LinkPath.IsEmpty()) + { + unsigned n = 0; + if (!Is_WSL()) + { + n = +#ifndef _WIN32 + isWindowsPath ? + NName::GetRootPrefixSize_WINDOWS(LinkPath) : +#endif + NName::GetRootPrefixSize(LinkPath); +/* + // "c:path" will be ignored later as "Dangerous absolute path" + // so check is not required + if (n == 0 +#ifndef _WIN32 + && isWindowsPath +#endif + && NName::IsDrivePath2(LinkPath)) + n = 2; +*/ + } + if (n == 0) + { + if (!IS_PATH_SEPAR(LinkPath[0])) + break; + n = 1; + } + isRelative = false; // (LinkPath) will be treated as relative to root folder of archive + LinkPath.DeleteFrontal(n); + } +} + + +/* + it removes redundant separators, if there are double separators, + but it keeps double separators at start of string //name/. + in/out: system path separator is used + windows: slash character (linux separator) is not treated as separator + windows: (path) doesn't contain linux separator (slash). +*/ +static void RemoveRedundantPathSeparators(UString &path) +{ + wchar_t *dest = path.GetBuf(); + const wchar_t * const start = dest; + const wchar_t *src = dest; + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + // if (IS_PATH_SEPAR(c)) // for Windows: we can change (/) to (\). + if (c == WCHAR_PATH_SEPARATOR) + { + if (dest - start >= 2 && dest[-1] == WCHAR_PATH_SEPARATOR) + continue; + // c = WCHAR_PATH_SEPARATOR; // for Windows: we can change (/) to (\). + } + *dest++ = c; + } + *dest = 0; + path.ReleaseBuf_SetLen((unsigned)(dest - path.Ptr())); +} + + +// in/out: (LinkPath) uses system path separator +// in/out: windows: (LinkPath) doesn't contain linux separator (slash). +// out: (LinkPath) is relative path, and LinkPath[0] is not path separator +void CLinkInfo::Normalize_to_RelativeSafe(UStringVector &removePathParts) +{ + // We WILL NOT WRITE original absolute link path from archive to filesystem. + // So here we remove all root prefixes from (LinkPath). + // If we see any absolute root prefix, then we suppose that this prefix is virtual prefix + // that shows that link is relative to root folder of archive + RemoveRedundantPathSeparators(LinkPath); + // LinkPath = "\\\\?\\r:test\\test2"; // for debug + Remove_AbsPathPrefixes(); + // (LinkPath) now is relative: + // if (isRelative == false), then (LinkPath) is relative to root folder of archive + // if (isRelative == true ), then (LinkPath) is relative to current item + if (LinkPath.IsEmpty() || isRelative || removePathParts.Size() == 0) + return; + + // if LinkPath is prefixed by _removePathParts, we remove these paths + UStringVector pathParts; + SplitPathToParts(LinkPath, pathParts); + bool badPrefix = false; + { + FOR_VECTOR (i, removePathParts) + { + if (i >= pathParts.Size() + || CompareFileNames(removePathParts[i], pathParts[i]) != 0) + { + badPrefix = true; + break; + } + } + } + if (!badPrefix) + pathParts.DeleteFrontal(removePathParts.Size()); + LinkPath = MakePathFromParts(pathParts); + Remove_AbsPathPrefixes(); +} + #endif // SUPPORT_LINKS @@ -2146,18 +2509,18 @@ { HRESULT res = S_OK; - #ifdef SUPPORT_LINKS +#ifdef SUPPORT_LINKS size_t reparseSize = 0; bool repraseMode = false; bool needSetReparse = false; - CLinkInfo linkInfo; + CLinkInfo link; if (_bufPtrSeqOutStream) { repraseMode = true; reparseSize = _bufPtrSeqOutStream_Spec->GetPos(); - if (_curSizeDefined && reparseSize == _outMemBuf.Size()) + if (_curSize_Defined && reparseSize == _outMemBuf.Size()) { /* CReparseAttr reparse; @@ -2165,15 +2528,19 @@ needSetReparse = reparse.Parse(_outMemBuf, reparseSize, errorCode); if (needSetReparse) { - UString linkPath = reparse.GetPath(); + UString LinkPath = reparse.GetPath(); #ifndef _WIN32 - linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); + LinkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); #endif } */ - needSetReparse = linkInfo.Parse(_outMemBuf, reparseSize, _is_SymLink_in_Data_Linux); + needSetReparse = _is_SymLink_in_Data_Linux ? + link.Parse_from_LinuxData(_outMemBuf, reparseSize) : + link.Parse_from_WindowsReparseData(_outMemBuf, reparseSize); if (!needSetReparse) res = SendMessageError_with_LastError("Incorrect reparse stream", us2fs(_item.Path)); + // (link.LinkPath) uses system path separator. + // windows: (link.LinkPath) doesn't contain linux separator (slash). } else { @@ -2181,75 +2548,86 @@ } if (!needSetReparse && _outFileStream) { - HRESULT res2 = WriteStream(_outFileStream, _outMemBuf, reparseSize); + const HRESULT res2 = WriteStream(_outFileStream, _outMemBuf, reparseSize); if (res == S_OK) res = res2; } _bufPtrSeqOutStream.Release(); } - #endif // SUPPORT_LINKS - - - HRESULT res2 = CloseFile(); +#endif // SUPPORT_LINKS + const HRESULT res2 = CloseFile(); if (res == S_OK) res = res2; + RINOK(res) - RINOK(res); - - #ifdef SUPPORT_LINKS +#ifdef SUPPORT_LINKS if (repraseMode) { _curSize = reparseSize; - _curSizeDefined = true; - - #ifdef SUPPORT_LINKS + _curSize_Defined = true; if (needSetReparse) { + // empty file was created so we must delete it. // in Linux : we must delete empty file before symbolic link creation // in Windows : we can create symbolic link even without file deleting if (!DeleteFileAlways(_diskFilePath)) { - RINOK(SendMessageError_with_LastError("can't delete file", _diskFilePath)); + RINOK(SendMessageError_with_LastError("can't delete file", _diskFilePath)) } { - /* - // for DEBUG ONLY: we can extract sym links as WSL links - // to elimanate (non-admin) errors for sym links. - #ifdef _WIN32 - if (!linkInfo.isHardLink && !linkInfo.isJunction) - linkInfo.isWSL = true; - #endif - */ bool linkWasSet = false; - RINOK(SetFromLinkPath(_diskFilePath, linkInfo, linkWasSet)); + // link.LinkPath = "r:\\1\\2"; // for debug + // link.isJunction = true; // for debug + link.Normalize_to_RelativeSafe(_removePathParts); + RINOK(SetLink(_diskFilePath, link, linkWasSet)) +/* + // we don't set attributes for placeholder. if (linkWasSet) - _isSymLinkCreated = linkInfo.IsSymLink(); + _isSymLinkCreated = true; // link.IsSymLink(); else +*/ _needSetAttrib = false; } - /* - if (!NFile::NIO::SetReparseData(_diskFilePath, _item.IsDir, )) - { - res = SendMessageError_with_LastError(kCantCreateSymLink, _diskFilePath); - } - */ } - #endif } - #endif +#endif // SUPPORT_LINKS return res; } -void CArchiveExtractCallback::SetAttrib() +static void SetAttrib_Base(const FString &path, const CProcessedFileInfo &fi, + const CArchiveExtractCallback &callback) { - #ifndef _WIN32 +#ifndef _WIN32 + if (fi.Owner.Id_Defined && + fi.Group.Id_Defined) + { + if (my_chown(path, fi.Owner.Id, fi.Group.Id) != 0) + callback.SendMessageError_with_LastError("Cannot set owner", path); + } +#endif + + if (fi.Attrib_Defined) + { + // const AString s = GetAnsiString(_diskFilePath); + // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); + if (!SetFileAttrib_PosixHighDetect(path, fi.Attrib)) + { + // do we need error message here in Windows and in posix? + callback.SendMessageError_with_LastError("Cannot set file attribute", path); + } + } +} + +void CArchiveExtractCallback::SetAttrib() const +{ +#ifndef _WIN32 // Linux now doesn't support permissions for symlinks if (_isSymLinkCreated) return; - #endif +#endif if (_itemFailure || _diskFilePath.IsEmpty() @@ -2257,38 +2635,48 @@ || !_extractMode) return; - #ifndef _WIN32 - if (_fi.Owner.Id_Defined && - _fi.Group.Id_Defined) - { - if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0) - { - SendMessageError_with_LastError("Cannot set owner", _diskFilePath); - } - } - #endif + SetAttrib_Base(_diskFilePath, _fi, *this); +} + - if (_fi.Attrib_Defined) +#ifdef Z7_USE_SECURITY_CODE +HRESULT CArchiveExtractCallback::SetSecurityInfo(UInt32 indexInArc, const FString &path) const +{ + if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) { - // const AString s = GetAnsiString(_diskFilePath); - // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); - bool res = SetFileAttrib_PosixHighDetect(_diskFilePath, _fi.Attrib); - if (!res) + const void *data; + UInt32 dataSize; + UInt32 propType; + _arc->GetRawProps->GetRawProp(indexInArc, kpidNtSecure, &data, &dataSize, &propType); + if (dataSize != 0) { - // do we need error message here in Windows and in posix? - SendMessageError_with_LastError("Cannot set file attribute", _diskFilePath); + if (propType != NPropDataType::kRaw) + return E_FAIL; + if (CheckNtSecure((const Byte *)data, dataSize)) + { + SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION; + if (_saclEnabled) + securInfo |= SACL_SECURITY_INFORMATION; + // if (! + ::SetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(const Byte *)(data)); + { + // RINOK(SendMessageError_with_LastError("SetFileSecurity FAILS", path)) + } + } } } + return S_OK; } +#endif // Z7_USE_SECURITY_CODE -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 opRes)) { COM_TRY_BEGIN // printf("\nCArchiveExtractCallback::SetOperationResult: %d %s\n", opRes, GetAnsiString(_diskFilePath)); - #ifndef _SFX + #ifndef Z7_SFX if (ExtractToStreamCallback) { GetUnpackSize(); @@ -2296,7 +2684,7 @@ } #endif - #ifndef _SFX + #ifndef Z7_SFX if (_hashStreamWasUsed) { @@ -2308,41 +2696,23 @@ #endif , _item.Path); _curSize = _hashStreamSpec->GetSize(); - _curSizeDefined = true; + _curSize_Defined = true; _hashStreamSpec->ReleaseStream(); _hashStreamWasUsed = false; } - #endif // _SFX + #endif // Z7_SFX - RINOK(CloseReparseAndFile()); + RINOK(CloseReparseAndFile()) - #ifdef _USE_SECURITY_CODE - if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) - { - const void *data; - UInt32 dataSize; - UInt32 propType; - _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType); - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - if (CheckNtSecure((const Byte *)data, dataSize)) - { - SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION; - if (_saclEnabled) - securInfo |= SACL_SECURITY_INFORMATION; - ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)(const Byte *)(data)); - } - } - } - #endif // _USE_SECURITY_CODE +#ifdef Z7_USE_SECURITY_CODE + RINOK(SetSecurityInfo(_index, _diskFilePath)) +#endif - if (!_curSizeDefined) + if (!_curSize_Defined) GetUnpackSize(); - if (_curSizeDefined) + if (_curSize_Defined) { #ifdef SUPPORT_ALT_STREAMS if (_item.IsAltStream) @@ -2364,7 +2734,7 @@ if (_needSetAttrib) SetAttrib(); - RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))); + RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))) return S_OK; @@ -2373,7 +2743,7 @@ -STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) +Z7_COM7F_IMF(CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) { if (_folderArchiveExtractCallback2) { @@ -2383,9 +2753,9 @@ if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1) { CReadArcItem item; - RINOK(_arc->GetItem(index, item)); + RINOK(_arc->GetItem(index, item)) s = item.Path; - RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)); + RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)) } else { @@ -2401,19 +2771,21 @@ } -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (!_cryptoGetTextPassword) { RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, - &_cryptoGetTextPassword)); + &_cryptoGetTextPassword)) } return _cryptoGetTextPassword->CryptoGetTextPassword(password); COM_TRY_END } +#ifndef Z7_SFX + // ---------- HASH functions ---------- FString CArchiveExtractCallback::Hash_GetFullFilePath() @@ -2435,13 +2807,13 @@ } -STDMETHODIMP CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; if (propID == kpidSize) { - RINOK(GetItem(index)); + RINOK(GetItem(index)) const FString fullProcessedPath = Hash_GetFullFilePath(); NFile::NFind::CFileInfo fi; if (fi.Find_FollowLink(fullProcessedPath)) @@ -2454,7 +2826,7 @@ } -STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode) +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) { COM_TRY_BEGIN *inStream = NULL; @@ -2462,7 +2834,7 @@ if (mode != NUpdateNotifyOp::kHashRead) return E_FAIL; - RINOK(GetItem(index)); + RINOK(GetItem(index)) const FString fullProcessedPath = Hash_GetFullFilePath(); CInFileStream *inStreamSpec = new CInFileStream; @@ -2470,7 +2842,7 @@ inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime); if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite)) { - RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)); + RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)) return S_OK; } *inStream = inStreamRef.Detach(); @@ -2479,8 +2851,8 @@ } -STDMETHODIMP CArchiveExtractCallback::ReportOperation( - UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */) +Z7_COM7F_IMF(CArchiveExtractCallback::ReportOperation( + UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */)) { // COM_TRY_BEGIN return S_OK; @@ -2488,6 +2860,79 @@ } +Z7_COM7F_IMF(CArchiveExtractCallback::RequestMemoryUse( + UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path, + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +{ + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + const UInt64 memLimit = _ntOptions.MemLimit; + if (memLimit != (UInt64)(Int64)-1) + { + // we overwrite allowedSize + *allowedSize = memLimit; + if (requiredSize <= memLimit) + { + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; + return S_OK; + } + *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded; + if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc; + flags |= NRequestMemoryUseFlags::k_SLimit_Exceeded + | NRequestMemoryUseFlags::k_AllowedSize_WasForced; + } + } + + if (!_requestMemoryUseCallback) + { + _extractCallback2.QueryInterface(IID_IArchiveRequestMemoryUseCallback, + &_requestMemoryUseCallback); + if (!_requestMemoryUseCallback) + { + // keep default (answerFlags) from caller or (answerFlags) that was set in this function + return S_OK; + } + } + +#if 0 + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + if (requiredSize <= *allowedSize) + { + // it's expected, that *answerFlags was set to NRequestMemoryAnswerFlags::k_Allow already, + // because it's default answer for (requiredSize <= *allowedSize) case. + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; // optional code + } + else + { + // we clear *answerFlags, because we want to disable dafault "Allow", if it's set. + // *answerFlags = 0; + /* + NRequestMemoryAnswerFlags::k_SkipArc | + NRequestMemoryAnswerFlags::k_Limit_Exceeded; + */ + } +#endif + + UString s; + if (!path + && indexType == NArchive::NEventIndexType::kInArcIndex + && index != (UInt32)(Int32)-1 + && _arc) + { + RINOK(_arc->GetItem_Path(index, s)) + path = s.Ptr(); + } + + return _requestMemoryUseCallback->RequestMemoryUse( + flags, indexType, index, path, + requiredSize, allowedSize, answerFlags); +} + +#endif // Z7_SFX + + + // ------------ After Extracting functions ------------ void CDirPathSortPair::SetNumSlashes(const FChar *s) @@ -2506,14 +2951,57 @@ } -bool CDirPathTime::SetDirTime() const +bool CFiTimesCAM::SetDirTime_to_FS(CFSTR path) const +{ + // it's same function for dir and for file + return NDir::SetDirTime(path, + CTime_Defined ? &CTime : NULL, + ATime_Defined ? &ATime : NULL, + MTime_Defined ? &MTime : NULL); +} + + +#ifdef SUPPORT_LINKS + +bool CFiTimesCAM::SetLinkFileTime_to_FS(CFSTR path) const { - return NDir::SetDirTime(Path, + // it's same function for dir and for file + return NDir::SetLinkFileTime(path, CTime_Defined ? &CTime : NULL, ATime_Defined ? &ATime : NULL, MTime_Defined ? &MTime : NULL); } +HRESULT CArchiveExtractCallback::SetPostLinks() const +{ + FOR_VECTOR (i, _postLinks) + { + const CPostLink &link = _postLinks[i]; + bool linkWasSet = false; + RINOK(SetLink2(*this, link, linkWasSet)) + if (linkWasSet) + { +#ifdef _WIN32 + // Linux now doesn't support permissions for symlinks + SetAttrib_Base(link.fullProcessedPath_from, link.item_FileInfo, *this); +#endif + + CFiTimesCAM pt; + GetFiTimesCAM(link.item_FileInfo, pt, *_arc); + if (pt.IsSomeTimeDefined()) + pt.SetLinkFileTime_to_FS(link.fullProcessedPath_from); + +#ifdef Z7_USE_SECURITY_CODE + // we set security information after timestamps setting + RINOK(SetSecurityInfo(link.Index_in_Arc, link.fullProcessedPath_from)) +#endif + } + } + return S_OK; +} + +#endif + HRESULT CArchiveExtractCallback::SetDirsTimes() { @@ -2538,7 +3026,7 @@ for (i = 0; i < pairs.Size(); i++) { const CDirPathTime &dpt = _extractedFolders[pairs[i].Index]; - if (!dpt.SetDirTime()) + if (!dpt.SetDirTime_to_FS_2()) { // result = E_FAIL; // do we need error message here in Windows and in posix? @@ -2570,10 +3058,20 @@ HRESULT CArchiveExtractCallback::CloseArc() { + // we call CloseReparseAndFile() here because we can have non-closed file in some cases? HRESULT res = CloseReparseAndFile(); - HRESULT res2 = SetDirsTimes(); - if (res == S_OK) - res = res2; +#ifdef SUPPORT_LINKS + { + const HRESULT res2 = SetPostLinks(); + if (res == S_OK) + res = res2; + } +#endif + { + const HRESULT res2 = SetDirsTimes(); + if (res == S_OK) + res = res2; + } _arc = NULL; return res; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.h 2022-06-09 16:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveExtractCallback.h 2025-08-02 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ArchiveExtractCallback.h -#ifndef __ARCHIVE_EXTRACT_CALLBACK_H -#define __ARCHIVE_EXTRACT_CALLBACK_H +#ifndef ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H +#define ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H #include "../../../Common/MyCom.h" #include "../../../Common/MyLinux.h" @@ -21,20 +21,18 @@ #include "HashCalc.h" -#ifndef _SFX +#ifndef Z7_SFX -class COutStreamWithHash: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _calculate; CMyComPtr _stream; UInt64 _size; - bool _calculate; public: IHashCalc *_hash; - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(bool calculate = true) @@ -54,7 +52,6 @@ { CBoolPair NtSecurity; CBoolPair SymLinks; - CBoolPair SymLinks_AllowDangerous; CBoolPair HardLinks; CBoolPair AltStreams; bool ReplaceColonForAltStream; @@ -68,15 +65,20 @@ bool PreserveATime; bool OpenShareForWrite; + unsigned SymLinks_DangerousLevel; + + UInt64 MemLimit; + CExtractNtOptions(): ReplaceColonForAltStream(false), WriteToAltStreamIfColon(false), ExtractOwner(false), PreserveATime(false), - OpenShareForWrite(false) + OpenShareForWrite(false), + SymLinks_DangerousLevel(5), + MemLimit((UInt64)(Int64)-1) { SymLinks.Val = true; - SymLinks_AllowDangerous.Val = false; HardLinks.Val = true; AltStreams.Val = true; @@ -89,28 +91,10 @@ } }; -#ifndef _SFX - -class CGetProp: - public IGetProp, - public CMyUnknownImp -{ -public: - const CArc *Arc; - UInt32 IndexInArc; - // UString Name; // relative path - - MY_UNKNOWN_IMP1(IGetProp) - INTERFACE_IGetProp(;) -}; -#endif - -#ifndef _SFX +#ifndef Z7_SFX #ifndef UNDER_CE - #define SUPPORT_LINKS - #endif #endif @@ -183,53 +167,79 @@ ATime_Defined | MTime_Defined; } + bool SetDirTime_to_FS(CFSTR path) const; +#ifdef SUPPORT_LINKS + bool SetLinkFileTime_to_FS(CFSTR path) const; +#endif }; struct CDirPathTime: public CFiTimesCAM { FString Path; - bool SetDirTime() const; + bool SetDirTime_to_FS_2() const { return SetDirTime_to_FS(Path); } }; #ifdef SUPPORT_LINKS +enum ELinkType +{ + k_LinkType_HardLink, + k_LinkType_PureSymLink, + k_LinkType_Junction, + k_LinkType_WSL + // , k_LinkType_CopyLink; +}; + + struct CLinkInfo { - // bool isCopyLink; - bool isHardLink; - bool isJunction; + ELinkType LinkType; bool isRelative; - bool isWSL; - UString linkPath; + // if (isRelative == false), then (LinkPath) is relative to root folder of archive + // if (isRelative == true ), then (LinkPath) is relative to current item + bool isWindowsPath; + UString LinkPath; + + bool Is_HardLink() const { return LinkType == k_LinkType_HardLink; } + bool Is_AnySymLink() const { return LinkType != k_LinkType_HardLink; } - bool IsSymLink() const { return !isHardLink; } + bool Is_WSL() const { return LinkType == k_LinkType_WSL; } CLinkInfo(): - // IsCopyLink(false), - isHardLink(false), - isJunction(false), + LinkType(k_LinkType_PureSymLink), isRelative(false), - isWSL(false) + isWindowsPath(false) {} void Clear() { - // IsCopyLink = false; - isHardLink = false; - isJunction = false; + LinkType = k_LinkType_PureSymLink; isRelative = false; - isWSL = false; - linkPath.Empty(); + isWindowsPath = false; + LinkPath.Empty(); } - bool Parse(const Byte *data, size_t dataSize, bool isLinuxData); + bool Parse_from_WindowsReparseData(const Byte *data, size_t dataSize); + bool Parse_from_LinuxData(const Byte *data, size_t dataSize); + void Normalize_to_RelativeSafe(UStringVector &removePathParts); +private: + void Remove_AbsPathPrefixes(); }; #endif // SUPPORT_LINKS + +struct CProcessedFileInfo +{ + CArcTime CTime; + CArcTime ATime; + CArcTime MTime; + UInt32 Attrib; + bool Attrib_Defined; + #ifndef _WIN32 struct COwnerInfo @@ -246,67 +256,17 @@ } }; + COwnerInfo Owner; + COwnerInfo Group; #endif - -class CArchiveExtractCallback: - public IArchiveExtractCallback, - public IArchiveExtractCallbackMessage, - public ICryptoGetTextPassword, - public ICompressProgressInfo, - public IArchiveUpdateCallbackFile, - public IArchiveGetDiskProperty, - public CMyUnknownImp -{ - const CArc *_arc; - CExtractNtOptions _ntOptions; - - const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) - CMyComPtr _extractCallback2; - CMyComPtr _compressProgress; - CMyComPtr _cryptoGetTextPassword; - CMyComPtr _callbackMessage; - CMyComPtr _folderArchiveExtractCallback2; - - FString _dirPathPrefix; - FString _dirPathPrefix_Full; - NExtract::NPathMode::EEnum _pathMode; - NExtract::NOverwriteMode::EEnum _overwriteMode; - bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; - - #ifndef _SFX - - CMyComPtr ExtractToStreamCallback; - CGetProp *GetProp_Spec; - CMyComPtr GetProp; - - #endif - - CReadArcItem _item; - FString _diskFilePath; - UInt64 _position; - bool _isSplit; - - bool _extractMode; - - bool Write_CTime; - bool Write_ATime; - bool Write_MTime; - - bool _encrypted; - - struct CProcessedFileInfo + void Clear() { - CArcTime CTime; - CArcTime ATime; - CArcTime MTime; - UInt32 Attrib; - bool Attrib_Defined; - - #ifndef _WIN32 - COwnerInfo Owner; - COwnerInfo Group; - #endif +#ifndef _WIN32 + Attrib_Defined = false; + Owner.Clear(); +#endif + } bool IsReparse() const { @@ -337,20 +297,143 @@ #endif Attrib_Defined = true; } - } _fi; +}; - // bool _is_SymLink_in_Data; - bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX +#ifdef SUPPORT_LINKS + +struct CPostLink +{ + UInt32 Index_in_Arc; + bool item_IsDir; // _item.IsDir + UString item_Path; // _item.Path; + UStringVector item_PathParts; // _item.PathParts; + CProcessedFileInfo item_FileInfo; // _fi + FString fullProcessedPath_from; // full file path in FS + CLinkInfo LinkInfo; +}; + +/* +struct CPostLinks +{ + void Clear() + { + Links.Clear(); + } +}; +*/ + +#endif // SUPPORT_LINKS + + + +class CArchiveExtractCallback Z7_final: + public IArchiveExtractCallback, + public IArchiveExtractCallbackMessage2, + public ICryptoGetTextPassword, + public ICompressProgressInfo, +#ifndef Z7_SFX + public IArchiveUpdateCallbackFile, + public IArchiveGetDiskProperty, + public IArchiveRequestMemoryUseCallback, +#endif + public CMyUnknownImp +{ + /* IArchiveExtractCallback, */ + Z7_COM_QI_BEGIN2(IArchiveExtractCallbackMessage2) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + Z7_COM_QI_ENTRY(ICompressProgressInfo) +#ifndef Z7_SFX + Z7_COM_QI_ENTRY(IArchiveUpdateCallbackFile) + Z7_COM_QI_ENTRY(IArchiveGetDiskProperty) + Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) +#ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + Z7_IFACE_COM7_IMP(IArchiveGetDiskProperty) + Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) +#endif + + // bool Write_CTime; + // bool Write_ATime; + // bool Write_MTime; + bool _stdOutMode; + bool _testMode; + bool _removePartsForAltStreams; +public: + bool Is_elimPrefix_Mode; +private: + + const CArc *_arc; +public: + CExtractNtOptions _ntOptions; +private: + bool _encrypted; + bool _isSplit; + bool _curSize_Defined; + bool _fileLength_WasSet; + + bool _isRenamed; + bool _extractMode; + bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX. + // _is_SymLink_in_Data_Linux is detected from Windows/Linux part of attributes of file. bool _needSetAttrib; bool _isSymLinkCreated; bool _itemFailure; + bool _some_pathParts_wereRemoved; - UInt32 _index; + bool _multiArchives; + bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + bool _saclEnabled; +#endif + + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; + + CMyComPtr _extractCallback2; + const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) + // CMyComPtr _compressProgress; + // CMyComPtr _callbackMessage; + CMyComPtr _folderArchiveExtractCallback2; + CMyComPtr _cryptoGetTextPassword; + + FString _dirPathPrefix; +public: + FString _dirPathPrefix_Full; +private: + + #ifndef Z7_SFX + + CMyComPtr ExtractToStreamCallback; + CMyComPtr _requestMemoryUseCallback; + + #endif + + CReadArcItem _item; + FString _diskFilePath; + + CProcessedFileInfo _fi; + + UInt64 _position; UInt64 _curSize; - bool _curSizeDefined; - bool _fileLengthWasSet; UInt64 _fileLength_that_WasSet; + UInt32 _index; + +// #ifdef SUPPORT_ALT_STREAMS +#if defined(_WIN32) && !defined(UNDER_CE) + DWORD _altStream_NeedRestore_AttribVal; + FString _altStream_NeedRestore_Attrib_for_parentFsPath; +#endif +// #endif COutFileStream *_outFileStreamSpec; CMyComPtr _outFileStream; @@ -359,32 +442,20 @@ CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec; CMyComPtr _bufPtrSeqOutStream; - - #ifndef _SFX - + #ifndef Z7_SFX COutStreamWithHash *_hashStreamSpec; CMyComPtr _hashStream; bool _hashStreamWasUsed; - #endif - - bool _removePartsForAltStreams; - UStringVector _removePathParts; - - #ifndef _SFX bool _use_baseParentFolder_mode; UInt32 _baseParentFolder; - #endif + #endif - bool _stdOutMode; - bool _testMode; - bool _multiArchives; + UStringVector _removePathParts; - CMyComPtr _localProgress; UInt64 _packTotal; - UInt64 _progressTotal; - bool _progressTotal_Defined; + // bool _progressTotal_Defined; CObjectVector _extractedFolders; @@ -392,30 +463,28 @@ // CObjectVector _delayedSymLinks; #endif - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) - bool _saclEnabled; - #endif - - void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); + void CreateComplexDirectory( + const UStringVector &dirPathParts, bool isFinal, FString &fullPath); HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); HRESULT GetUnpackSize(); FString Hash_GetFullFilePath(); - void SetAttrib(); + void SetAttrib() const; public: - HRESULT SendMessageError(const char *message, const FString &path); - HRESULT SendMessageError_with_LastError(const char *message, const FString &path); - HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); + HRESULT SendMessageError(const char *message, const FString &path) const; + HRESULT SendMessageError_with_Error(HRESULT errorCode, const char *message, const FString &path) const; + HRESULT SendMessageError_with_LastError(const char *message, const FString &path) const; + HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2) const; + HRESULT SendMessageError2_with_LastError(const char *message, const FString &path1, const FString &path2) const; -public: - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) NExtract::NZoneIdMode::EEnum ZoneMode; CByteBuffer ZoneBuf; - #endif +#endif - CLocalProgress *LocalProgressSpec; + CMyComPtr2_Create LocalProgressSpec; UInt64 NumFolders; UInt64 NumFiles; @@ -425,23 +494,6 @@ FString DirPathPrefix_for_HashFiles; - MY_UNKNOWN_IMP5( - IArchiveExtractCallbackMessage, - ICryptoGetTextPassword, - ICompressProgressInfo, - IArchiveUpdateCallbackFile, - IArchiveGetDiskProperty - ) - - INTERFACE_IArchiveExtractCallback(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IArchiveUpdateCallbackFile(;) - INTERFACE_IArchiveGetDiskProperty(;) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - CArchiveExtractCallback(); void InitForMulti(bool multiArchives, @@ -453,16 +505,16 @@ _multiArchives = multiArchives; _pathMode = pathMode; _overwriteMode = overwriteMode; - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) ZoneMode = zoneMode; - #else +#else UNUSED_VAR(zoneMode) - #endif +#endif _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; } - #ifndef _SFX + #ifndef Z7_SFX void SetHashMethods(IHashCalc *hash) { @@ -488,23 +540,32 @@ UInt64 packSize); - #ifdef SUPPORT_LINKS +#ifdef SUPPORT_LINKS private: CHardLinks _hardLinks; + CObjectVector _postLinks; CLinkInfo _link; + // const void *NtReparse_Data; + // UInt32 NtReparse_Size; - // FString _CopyFile_Path; + // FString _copyFile_Path; // HRESULT MyCopyFile(ISequentialOutStream *outStream); - HRESULT Link(const FString &fullProcessedPath); HRESULT ReadLink(); + HRESULT SetLink( + const FString &fullProcessedPath_from, + const CLinkInfo &linkInfo, + bool &linkWasSet); + HRESULT SetPostLinks() const; public: - // call PrepareHardLinks() after Init() + HRESULT CreateHardLink2(const FString &newFilePath, + const FString &existFilePath, bool &link_was_Created) const; + HRESULT DeleteLinkFileAlways_or_RemoveEmptyDir(const FString &path, bool checkThatFileIsEmpty) const; HRESULT PrepareHardLinks(const CRecordVector *realIndices); // NULL means all items +#endif - #endif - +private: #ifdef SUPPORT_ALT_STREAMS CObjectVector _renamedFiles; @@ -512,7 +573,8 @@ // call it after Init() - #ifndef _SFX +public: + #ifndef Z7_SFX void SetBaseParentFolderIndex(UInt32 indexInArc) { _baseParentFolder = indexInArc; @@ -533,28 +595,16 @@ HRESULT Read_fi_Props(); void CorrectPathParts(); - void GetFiTimesCAM(CFiTimesCAM &pt); void CreateFolders(); - bool _isRenamed; HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit); HRESULT GetExtractStream(CMyComPtr &outStreamLoc, bool &needExit); HRESULT GetItem(UInt32 index); HRESULT CloseFile(); HRESULT CloseReparseAndFile(); - HRESULT CloseReparseAndFile2(); HRESULT SetDirsTimes(); - - const void *NtReparse_Data; - UInt32 NtReparse_Size; - - #ifdef SUPPORT_LINKS - HRESULT SetFromLinkPath( - const FString &fullProcessedPath, - const CLinkInfo &linkInfo, - bool &linkWasSet); - #endif + HRESULT SetSecurityInfo(UInt32 indexInArc, const FString &path) const; }; @@ -584,6 +634,8 @@ bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); -void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf); +bool Is_ZoneId_StreamName(const wchar_t *s); +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf); +bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf); #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveName.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveName.cpp 2021-01-26 12:24:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -2,154 +2,175 @@ #include "StdAfx.h" +#include "../../../../C/Sort.h" + #include "../../../Common/Wildcard.h" +#include "../../../Common/StringToInt.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" -#include "ExtractingFilePath.h" #include "ArchiveName.h" +#include "ExtractingFilePath.h" using namespace NWindows; using namespace NFile; -static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName) + +static const char *g_ArcExts = + "7z" + "\0" "zip" + "\0" "tar" + "\0" "wim" + "\0"; + +static const char *g_HashExts = + "sha256" + "\0"; + + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NFind::CFileInfo *fi, + UString &baseName) { - FString resultName = fi.Name; - if (!fi.IsDir() && !keepName) + bool keepName = isHash; + /* + if (paths.Size() == 1) { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) - { - FString archiveName2 = resultName.Left((unsigned)dotPos); - if (archiveName2.ReverseFind_Dot() < 0) - resultName = archiveName2; - } + const UString &name = paths[0]; + if (name.Len() > 4) + if (CompareFileNames(name.RightPtr(4), L".tar") == 0) + keepName = true; } - return Get_Correct_FsFile_Name(fs2us(resultName)); -} + */ -static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName) -{ - FString resultName ("Archive"); - if (fromPrev) + UString name ("Archive"); + NFind::CFileInfo fi3; + if (paths.Size() > 1) + fi = NULL; + if (!fi && paths.Size() != 0) { - FString dirPrefix; - if (NDir::GetOnlyDirPrefix(path, dirPrefix)) + const UString &path = paths.Front(); + if (paths.Size() == 1) { - if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) - { - #if defined(_WIN32) && !defined(UNDER_CE) - if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) - resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter - else - #endif - { - dirPrefix.DeleteBack(); - NFind::CFileInfo fi; - if (fi.Find(dirPrefix)) - resultName = fi.Name; - } - } + if (fi3.Find(us2fs(path))) + fi = &fi3; } - } - else - { - NFind::CFileInfo fi; - if (fi.Find(path)) + else { - resultName = fi.Name; - if (!fi.IsDir() && !keepName) + // we try to use name of parent folder + FString dirPrefix; + if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix)) { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) + if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) { - FString name2 = resultName.Left((unsigned)dotPos); - if (name2.ReverseFind_Dot() < 0) - resultName = name2; + #if defined(_WIN32) && !defined(UNDER_CE) + if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) + { + if (path != fs2us(dirPrefix)) + name = dirPrefix[dirPrefix.Len() - 3]; // only letter + } + else + #endif + { + dirPrefix.DeleteBack(); + if (!dirPrefix.IsEmpty()) + { + const int slash = dirPrefix.ReverseFind_PathSepar(); + if (slash >= 0 && slash != (int)dirPrefix.Len() - 1) + name = dirPrefix.Ptr(slash + 1); + else if (fi3.Find(dirPrefix)) + name = fs2us(fi3.Name); + } + } } } } } - return resultName; -} - -UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi) -{ - bool keepName = false; - /* - if (paths.Size() == 1) - { - const UString &name = paths[0]; - if (name.Len() > 4) - if (CompareFileNames(name.RightPtr(4), L".tar") == 0) - keepName = true; - } - */ - - UString name; if (fi) - name = CreateArchiveName(*fi, keepName); - else { - if (paths.IsEmpty()) - return L"archive"; - bool fromPrev = (paths.Size() > 1); - name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName))); + name = fs2us(fi->Name); + if (!fi->IsDir() && !keepName) + { + const int dotPos = name.Find(L'.'); + if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0) + name.DeleteFrom((unsigned)dotPos); + } } + name = Get_Correct_FsFile_Name(name); - UStringVector names; - + CRecordVector ids; + bool simple_IsAllowed = true; + // for (int y = 0; y < 10000; y++) // for debug { + // ids.Clear(); + UString n; + FOR_VECTOR (i, paths) { - NFind::CFileInfo fi2; - const NFind::CFileInfo *fp; - if (fi && paths.Size() == 1) - fp = fi; - else + const UString &a = paths[i]; + const int slash = a.ReverseFind_PathSepar(); + // if (name.Len() >= a.Len() - slash + 1) continue; + const wchar_t *s = a.Ptr(slash + 1); + if (!IsPath1PrefixedByPath2(s, name)) + continue; + s += name.Len(); + const char *exts = isHash ? g_HashExts : g_ArcExts; + + for (;;) { - if (!fi2.Find(us2fs(paths[i]))) + const char *ext = exts; + const unsigned len = MyStringLen(ext); + if (len == 0) + break; + exts += len + 1; + n = s; + if (n.Len() <= len) + continue; + if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext)) + continue; + n.DeleteFrom(n.Len() - len); + if (n.Back() != '.') + continue; + n.DeleteBack(); + if (n.IsEmpty()) + { + simple_IsAllowed = false; + break; + } + if (n.Len() < 2) + continue; + if (n[0] != '_') + continue; + const wchar_t *end; + const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end); + if (*end != 0) continue; - fp = &fi2; + ids.Add(v); + break; } - names.Add(fs2us(fp->Name)); } } - UString postfix; - UInt32 index = 1; - - for (;;) + baseName = name; + if (!simple_IsAllowed) { - // we don't want cases when we include archive to itself. - // so we find first available name for archive - const UString name2 = name + postfix; - const UString name2_zip = name2 + L".zip"; - const UString name2_7z = name2 + L".7z"; - const UString name2_tar = name2 + L".tar"; - const UString name2_wim = name2 + L".wim"; - - unsigned i = 0; - - for (i = 0; i < names.Size(); i++) + HeapSort(ids.NonConstData(), ids.Size()); + UInt32 v = 2; + const unsigned num = ids.Size(); + for (unsigned i = 0; i < num; i++) { - const UString &fname = names[i]; - if ( 0 == CompareFileNames(fname, name2_zip) - || 0 == CompareFileNames(fname, name2_7z) - || 0 == CompareFileNames(fname, name2_tar) - || 0 == CompareFileNames(fname, name2_wim)) + const UInt32 id = ids[i]; + if (id > v) break; + if (id == v) + v = id + 1; } - - if (i == names.Size()) - break; - index++; - postfix = "_"; - postfix.Add_UInt32(index); + name.Add_Char('_'); + name.Add_UInt32(v); } - - name += postfix; return name; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveName.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveName.h 2018-12-22 10:00:52.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveName.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,16 @@ // ArchiveName.h -#ifndef __ARCHIVE_NAME_H -#define __ARCHIVE_NAME_H +#ifndef ZIP7_INC_ARCHIVE_NAME_H +#define ZIP7_INC_ARCHIVE_NAME_H #include "../../../Windows/FileFind.h" -UString CreateArchiveName(const UStringVector &paths, const NWindows::NFile::NFind::CFileInfo *fi = NULL); +/* (fi != NULL) only if (paths.Size() == 1) */ + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NWindows::NFile::NFind::CFileInfo *fi, + UString &baseName); #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 2022-04-06 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 2024-04-02 12:00:00.000000000 +0000 @@ -6,14 +6,54 @@ #include "../../../Windows/FileName.h" #include "../../../Windows/PropVariant.h" +#include "../../../Windows/System.h" -#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" #include "ArchiveOpenCallback.h" +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include +#endif + + +#ifdef DEBUG_VOLUMES + #define PRF(x) x +#else + #define PRF(x) +#endif + using namespace NWindows; -STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) +HRESULT COpenCallbackImp::Init2(const FString &folderPrefix, const FString &fileName) +{ + Volumes.Init(); + FileNames.Clear(); + FileNames_WasUsed.Clear(); + FileSizes.Clear(); + _subArchiveMode = false; + // TotalSize = 0; + PasswordWasAsked = false; + _folderPrefix = folderPrefix; + if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName)) + { + // throw 20121118; + return GetLastError_noZero_HRESULT(); + } + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetSubArchiveName(const wchar_t *name)) +{ + _subArchiveMode = true; + _subArchiveName = name; + // TotalSize = 0; + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)) { COM_TRY_BEGIN if (ReOpenCallback) @@ -24,7 +64,7 @@ COM_TRY_END } -STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)) { COM_TRY_BEGIN if (ReOpenCallback) @@ -36,7 +76,7 @@ } -STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -45,6 +85,7 @@ { case kpidName: prop = _subArchiveName; break; // case kpidSize: prop = _subArchiveSize; break; // we don't use it now + default: break; } else switch (propID) @@ -57,30 +98,190 @@ case kpidCTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.CTime); break; case kpidATime: PropVariant_SetFrom_FiTime(prop, _fileInfo.ATime); break; case kpidMTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.MTime); break; + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -struct CInFileStreamVol: public CInFileStream + +// ---------- CInFileStreamVol ---------- + +Z7_class_final(CInFileStreamVol): + public IInStream + , public IStreamGetSize + , public CMyUnknownImp { - unsigned FileNameIndex; + Z7_IFACES_IMP_UNK_3( + IInStream, + ISequentialInStream, + IStreamGetSize) +public: + unsigned FileIndex; COpenCallbackImp *OpenCallbackImp; CMyComPtr OpenCallbackRef; - + + HRESULT EnsureOpen() + { + return OpenCallbackImp->Volumes.EnsureOpen(FileIndex); + } + ~CInFileStreamVol() { if (OpenCallbackRef) - OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false; + OpenCallbackImp->AtCloseFile(FileIndex); } }; +void CMultiStreams::InsertToList(unsigned index) +{ + { + CSubStream &s = Streams[index]; + s.Next = Head; + s.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; +} + +// s must bee in List +void CMultiStreams::RemoveFromList(CSubStream &s) +{ + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; +} + +void CMultiStreams::CloseFile(unsigned index) +{ + CSubStream &s = Streams[index]; + if (s.Stream) + { + s.Stream.Release(); + RemoveFromList(s); + // s.InFile->Close(); + // s.IsOpen = false; + #ifdef DEBUG_VOLUMES + static int numClosing = 0; + numClosing++; + printf("\nCloseFile %u, total_closes = %u, num_open_files = %u\n", index, numClosing, NumListItems); + #endif + } +} + +void CMultiStreams::Init() +{ + Head = -1; + Tail = -1; + NumListItems = 0; + Streams.Clear(); +} + +CMultiStreams::CMultiStreams(): + Head(-1), + Tail(-1), + NumListItems(0) +{ + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + PRF(printf("\nNumOpenFiles_Limit = %u\n", NumOpenFiles_AllowedMax)); +} + + +HRESULT CMultiStreams::PrepareToOpenNew() +{ + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + if (Tail == -1) + return E_FAIL; + CMultiStreams::CSubStream &tailStream = Streams[(unsigned)Tail]; + RINOK(InStream_GetPos(tailStream.Stream, tailStream.LocalPos)) + CloseFile((unsigned)Tail); + return S_OK; +} + + +HRESULT CMultiStreams::EnsureOpen(unsigned index) +{ + CMultiStreams::CSubStream &s = Streams[index]; + if (s.Stream) + { + if ((int)index != Head) + { + RemoveFromList(s); + InsertToList(index); + } + } + else + { + RINOK(PrepareToOpenNew()) + { + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(s.Path)) + return GetLastError_noZero_HRESULT(); + s.FileSpec = inFile; + s.Stream = s.FileSpec; + InsertToList(index); + } + // s.IsOpen = true; + if (s.LocalPos != 0) + { + RINOK(s.Stream->Seek((Int64)s.LocalPos, STREAM_SEEK_SET, &s.LocalPos)) + } + #ifdef DEBUG_VOLUMES + static int numOpens = 0; + numOpens++; + printf("\n-- %u, ReOpen, total_reopens = %u, num_open_files = %u\n", index, numOpens, NumListItems); + #endif + } + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStreamVol::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n== %u, Read =%u \n", FileIndex, size)); + return s.Stream->Read(data, size, processedSize); +} + +Z7_COM7F_IMF(CInFileStreamVol::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + // if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n-- %u, Seek seekOrigin=%u Seek =%u\n", FileIndex, seekOrigin, (unsigned)offset)); + return s.Stream->Seek(offset, seekOrigin, newPosition); +} + +Z7_COM7F_IMF(CInFileStreamVol::GetSize(UInt64 *size)) +{ + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + return s.FileSpec->GetSize(size); +} + + // from ArchiveExtractCallback.cpp bool IsSafePath(const UString &path); -STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) +Z7_COM7F_IMF(COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)) { COM_TRY_BEGIN *inStream = NULL; @@ -89,13 +290,13 @@ return S_FALSE; if (Callback) { - RINOK(Callback->Open_CheckBreak()); + RINOK(Callback->Open_CheckBreak()) } UString name2 = name; - #ifndef _SFX + #ifndef Z7_SFX #ifdef _WIN32 name2.Replace(L'/', WCHAR_PATH_SEPARATOR); @@ -112,7 +313,7 @@ if (name2.Find(L'*') >= 0) return S_FALSE; { - int startPos = 0; + unsigned startPos = 0; if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\")) startPos = 3; if (name2.Find(L'?', startPos) >= 0) @@ -130,16 +331,32 @@ return S_FALSE; if (_fileInfo.IsDir()) return S_FALSE; - CInFileStreamVol *inFile = new CInFileStreamVol; - CMyComPtr inStreamTemp = inFile; - if (!inFile->Open(fullPath)) + + CMultiStreams::CSubStream s; + { - return GetLastError_noZero_HRESULT(); + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return GetLastError_noZero_HRESULT(); + RINOK(Volumes.PrepareToOpenNew()) + s.FileSpec = inFile; + s.Stream = s.FileSpec; + s.Path = fullPath; + // s.Size = _fileInfo.Size; + // s.IsOpen = true; } + const unsigned fileIndex = Volumes.Streams.Add(s); + Volumes.InsertToList(fileIndex); + FileSizes.Add(_fileInfo.Size); FileNames.Add(name2); - inFile->FileNameIndex = FileNames_WasUsed.Add(true); + FileNames_WasUsed.Add(true); + + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr inStreamTemp = inFile; + inFile->FileIndex = fileIndex; inFile->OpenCallbackImp = this; inFile->OpenCallbackRef = this; // TotalSize += _fileInfo.Size; @@ -148,14 +365,16 @@ COM_TRY_END } -#ifndef _NO_CRYPTO -STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) + +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(COpenCallbackImp::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (ReOpenCallback) { - CMyComPtr getTextPassword; - ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getTextPassword, ReOpenCallback) if (getTextPassword) return getTextPassword->CryptoGetTextPassword(password); } @@ -166,3 +385,14 @@ COM_TRY_END } #endif + +// IProgress +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 /* total */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 * /* completed */)) +{ + return S_OK; +} diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.h 2021-03-06 09:02:02.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ArchiveOpenCallback.h 2024-03-12 18:00:00.000000000 +0000 @@ -1,112 +1,177 @@ // ArchiveOpenCallback.h -#ifndef __ARCHIVE_OPEN_CALLBACK_H -#define __ARCHIVE_OPEN_CALLBACK_H +#ifndef ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H +#define ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H #include "../../../Common/MyCom.h" #include "../../../Windows/FileFind.h" -#include "../../../Windows/FileIO.h" -#ifndef _NO_CRYPTO +#include "../../Common/FileStreams.h" + +#ifndef Z7_NO_CRYPTO #include "../../IPassword.h" #endif #include "../../Archive/IArchive.h" -#ifdef _NO_CRYPTO +Z7_PURE_INTERFACES_BEGIN + +#ifdef Z7_NO_CRYPTO -#define INTERFACE_IOpenCallbackUI_Crypto(x) +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) #else -#define INTERFACE_IOpenCallbackUI_Crypto(x) \ - virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \ - /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; */ \ - /* virtual bool Open_WasPasswordAsked() x; */ \ - /* virtual void Open_Clear_PasswordWasAsked_Flag() x; */ \ +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) \ + virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x \ + /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x */ \ + /* virtual bool Open_WasPasswordAsked() x */ \ + /* virtual void Open_Clear_PasswordWasAsked_Flag() x */ \ #endif -#define INTERFACE_IOpenCallbackUI(x) \ - virtual HRESULT Open_CheckBreak() x; \ - virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_Finished() x; \ - INTERFACE_IOpenCallbackUI_Crypto(x) +#define Z7_IFACEN_IOpenCallbackUI(x) \ + virtual HRESULT Open_CheckBreak() x \ + virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_Finished() x \ + Z7_IFACEM_IOpenCallbackUI_Crypto(x) + +Z7_IFACE_DECL_PURE(IOpenCallbackUI) + +Z7_PURE_INTERFACES_END + -struct IOpenCallbackUI +class CMultiStreams Z7_final { - INTERFACE_IOpenCallbackUI(=0) +public: + struct CSubStream + { + CMyComPtr Stream; + CInFileStream *FileSpec; + FString Path; + // UInt64 Size; + UInt64 LocalPos; + int Next; // next older + int Prev; // prev newer + // bool IsOpen; + + CSubStream(): + FileSpec(NULL), + // Size(0), + LocalPos(0), + Next(-1), + Prev(-1) + // IsOpen(false) + {} + }; + + CObjectVector Streams; +private: + // we must use critical section here, if we want to access from different volumnes simultaneously + int Head; // newest + int Tail; // oldest + unsigned NumListItems; + unsigned NumOpenFiles_AllowedMax; +public: + + CMultiStreams(); + void Init(); + HRESULT PrepareToOpenNew(); + void InsertToList(unsigned index); + void RemoveFromList(CSubStream &s); + void CloseFile(unsigned index); + HRESULT EnsureOpen(unsigned index); }; -class COpenCallbackImp: + +/* + We need COpenCallbackImp class for multivolume processing. + Also we use it as proxy from COM interfaces (IArchiveOpenCallback) to internal (IOpenCallbackUI) interfaces. + If archive is multivolume: + COpenCallbackImp object will exist after Open stage. + COpenCallbackImp object will be deleted when last reference + from each volume object (CInFileStreamVol) will be closed (when archive will be closed). +*/ + +class COpenCallbackImp Z7_final: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, public IArchiveOpenSetSubArchiveName, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif + public IProgress, // IProgress is used for 7zFM public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + Z7_COM_QI_ENTRY(IArchiveOpenSetSubArchiveName) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + // Z7_COM_QI_ENTRY(IProgress) // the code doesn't require it + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + Z7_IFACE_COM7_IMP(IProgress) +public: + Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName) +private: + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + + bool _subArchiveMode; + public: - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenVolumeCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSetSubArchiveName) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif + bool PasswordWasAsked; + UStringVector FileNames; + CBoolVector FileNames_WasUsed; + CRecordVector FileSizes; - STDMETHOD(SetSubArchiveName(const wchar_t *name)) + void AtCloseFile(unsigned fileIndex) { - _subArchiveMode = true; - _subArchiveName = name; - // TotalSize = 0; - return S_OK; + FileNames_WasUsed[fileIndex] = false; + Volumes.CloseFile(fileIndex); } + /* we have two ways to Callback from this object + 1) IArchiveOpenCallback * ReOpenCallback - for ReOpen function, when IOpenCallbackUI is not available + 2) IOpenCallbackUI *Callback - for usual callback + we can't transfer IOpenCallbackUI pointer via internal interface, + so we use ReOpenCallback to callback without IOpenCallbackUI. + */ + + /* we use Callback/ReOpenCallback only at Open stage. + So the CMyComPtr reference counter is not required, + and we don't want additional reference to unused object, + if COpenCallbackImp is not closed + */ + IArchiveOpenCallback *ReOpenCallback; + // CMyComPtr ReOpenCallback; + IOpenCallbackUI *Callback; + // CMyComPtr Callback_Ref; + private: FString _folderPrefix; - NWindows::NFile::NFind::CFileInfo _fileInfo; - bool _subArchiveMode; UString _subArchiveName; + NWindows::NFile::NFind::CFileInfo _fileInfo; public: - UStringVector FileNames; - CBoolVector FileNames_WasUsed; - CRecordVector FileSizes; + CMultiStreams Volumes; - bool PasswordWasAsked; - - IOpenCallbackUI *Callback; - CMyComPtr ReOpenCallback; // UInt64 TotalSize; - COpenCallbackImp(): _subArchiveMode(false), Callback(NULL) {} + COpenCallbackImp(): + _subArchiveMode(false), + PasswordWasAsked(false), + ReOpenCallback(NULL), + Callback(NULL) {} - HRESULT Init2(const FString &folderPrefix, const FString &fileName) - { - FileNames.Clear(); - FileNames_WasUsed.Clear(); - FileSizes.Clear(); - _subArchiveMode = false; - // TotalSize = 0; - PasswordWasAsked = false; - _folderPrefix = folderPrefix; - if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName)) - { - // throw 20121118; - return GetLastError_noZero_HRESULT(); - } - return S_OK; - } + HRESULT Init2(const FString &folderPrefix, const FString &fileName); bool SetSecondFileInfo(CFSTR newName) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Bench.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Bench.cpp 2021-12-25 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.cpp 2025-06-30 16:00:00.000000000 +0000 @@ -2,12 +2,9 @@ #include "StdAfx.h" -#include "../../../../C/CpuArch.h" - // #include #ifndef _WIN32 - #define USE_POSIX_TIME #define USE_POSIX_TIME2 #endif // _WIN32 @@ -31,24 +28,27 @@ #else #include #endif +#define BENCH_ALLOCA_VALUE(index) (((index) * 64 * 21) & 0x7FF) #endif #include "../../../../C/7zCrc.h" #include "../../../../C/RotateDefs.h" +#include "../../../../C/CpuArch.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #include "../../../Windows/Thread.h" #endif -#include "../../../Windows/FileIO.h" #include "../../../Windows/FileFind.h" +#include "../../../Windows/FileIO.h" #include "../../../Windows/SystemInfo.h" -#include "../../../Common/IntToString.h" #include "../../../Common/MyBuffer2.h" +#include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Common/Wildcard.h" #include "../../Common/MethodProps.h" #include "../../Common/StreamObjects.h" @@ -58,7 +58,7 @@ using namespace NWindows; -#ifndef _7ZIP_ST +#ifndef Z7_ST static const UInt32 k_LZMA = 0x030101; #endif @@ -104,9 +104,9 @@ // static const size_t kAdditionalSize = (size_t)1 << 32; // for debug static const size_t kAdditionalSize = (size_t)1 << 16; -static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const size_t kCompressedAdditionalSize = 1 << 10; -static const UInt32 kMaxMethodPropSize = (1 << 6); +static const UInt32 kMaxMethodPropSize = 1 << 6; #define ALLOC_WITH_HRESULT(_buffer_, _size_) \ @@ -122,35 +122,43 @@ public: CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); } void Init() { A1 = 362436069; A2 = 521288629;} - MY_FORCE_INLINE + Z7_FORCE_INLINE UInt32 GetRnd() { +#if 0 + // for debug: + return 0x0c080400; + // return 0; +#else return Salt ^ ( ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ) ); +#endif } }; -MY_NO_INLINE -static void RandGen(Byte *buf, size_t size) +static const size_t k_RandBuf_AlignMask = 4 - 1; + +Z7_NO_INLINE +static void RandGen_BufAfterPad(Byte *buf, size_t size) { CBaseRandomGenerator RG; - const size_t size4 = size & ~((size_t)3); - size_t i; - for (i = 0; i < size4; i += 4) + for (size_t i = 0; i < size; i += 4) { const UInt32 v = RG.GetRnd(); - SetUi32(buf + i, v); + SetUi32a(buf + i, v) } + /* UInt32 v = RG.GetRnd(); for (; i < size; i++) { buf[i] = (Byte)v; v >>= 8; } + */ } @@ -158,14 +166,14 @@ { static UInt32 GetVal(UInt32 &res, unsigned numBits) { - UInt32 val = res & (((UInt32)1 << numBits) - 1); + const UInt32 val = res & (((UInt32)1 << numBits) - 1); res >>= numBits; return val; } static UInt32 GetLen(UInt32 &r) { - UInt32 len = GetVal(r, 2); + const unsigned len = (unsigned)GetVal(r, 2); return GetVal(r, 1 + len); } @@ -255,16 +263,14 @@ }; -class CBenchmarkInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CBenchmarkInStream + , ISequentialInStream +) const Byte *Data; size_t Pos; size_t Size; - public: - MY_UNKNOWN_IMP void Init(const Byte *data, size_t size) { Data = data; @@ -272,10 +278,9 @@ Pos = 0; } bool WasFinished() const { return Pos == Size; } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { const UInt32 kMaxBlockSize = (1 << 20); if (size > kMaxBlockSize) @@ -284,7 +289,7 @@ if (size > remain) size = (UInt32)remain; - if (size != 0) + if (size) memcpy(data, Data + Pos, size); Pos += size; @@ -293,11 +298,14 @@ return S_OK; } -class CBenchmarkOutStream: + +class CBenchmarkOutStream Z7_final: public ISequentialOutStream, - public CMidAlignedBuffer, - public CMyUnknownImp + public CMyUnknownImp, + public CMidAlignedBuffer { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) // bool _overflow; public: size_t Pos; @@ -328,12 +336,9 @@ size_t GetPos() const { return Pos; } // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t curSize = Size() - Pos; if (curSize > size) @@ -357,27 +362,24 @@ } -class CCrcOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CCrcOutStream + , ISequentialOutStream +) public: bool CalcCrc; UInt32 Crc; UInt64 Pos; - MY_UNKNOWN_IMP - - CCrcOutStream(): CalcCrc(true) {}; + CCrcOutStream(): CalcCrc(true) {} void Init() { Crc = CRC_INIT_VAL; Pos = 0; } void Calc(const void *data, size_t size) { Crc = CrcUpdate(Crc, data, size); } - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (CalcCrc) Calc(data, size); @@ -394,7 +396,7 @@ #ifdef USE_POSIX_TIME #ifdef USE_POSIX_TIME2 timeval v; - if (gettimeofday(&v, 0) == 0) + if (gettimeofday(&v, NULL) == 0) return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec; return (UInt64)time(NULL) * 1000000; #else @@ -531,9 +533,9 @@ #endif } -class CBenchProgressStatus +class CBenchProgressStatus Z7_final { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSection CS; #endif public: @@ -541,14 +543,14 @@ bool EncodeMode; void SetResult(HRESULT res) { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSectionLock lock(CS); #endif Res = res; } HRESULT GetResult() { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSectionLock lock(CS); #endif return Res; @@ -580,22 +582,22 @@ dest.UserTime = UserTime.GetUserTime(); } -class CBenchProgressInfo: +class CBenchProgressInfo Z7_final: public ICompressProgressInfo, public CMyUnknownImp, public CBenchInfoCalc { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ICompressProgressInfo) public: CBenchProgressStatus *Status; IBenchCallback *Callback; CBenchProgressInfo(): Callback(NULL) {} - MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { HRESULT res = Status->GetResult(); if (res != S_OK) @@ -760,13 +762,20 @@ return MyMultDiv64(numUnits, GlobalFreq, GlobalTime); } +static UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity) +{ + return complexity >= 0 ? + size * (UInt32)complexity : + size / (UInt32)(-complexity); +} + struct CBenchProps { bool LzmaRatingMode; - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; unsigned KeySize; @@ -777,21 +786,23 @@ void SetLzmaCompexity(); - UInt64 GeComprCommands(UInt64 unpackSize) + UInt64 GetNumCommands_Enc(UInt64 unpackSize) const { const UInt32 kMinSize = 100; if (unpackSize < kMinSize) unpackSize = kMinSize; - return unpackSize * EncComplex; + return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex); } - UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize) + UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const { - return (packSize * DecComplexCompr + unpackSize * DecComplexUnc); + return + GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) + + GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc); } - UInt64 GetCompressRating(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); - UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); + UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const; + UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const; }; void CBenchProps::SetLzmaCompexity() @@ -802,11 +813,11 @@ LzmaRatingMode = true; } -UInt64 CBenchProps::GetCompressRating(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) +UInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const { if (dictSize < (1 << kBenchMinDicLogSize)) dictSize = (1 << kBenchMinDicLogSize); - UInt64 encComplex = EncComplex; + Int32 encComplex = EncComplex; if (LzmaRatingMode) { /* @@ -822,13 +833,13 @@ const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits); encComplex = 870 + ((t * t * 5) >> (2 * kSubBits)); } - const UInt64 numCommands = (UInt64)size * encComplex; + const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex); return MyMultDiv64(numCommands, freq, elapsedTime); } -UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) +UInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const { - const UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations; + const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations; return MyMultDiv64(numCommands, freq, elapsedTime); } @@ -838,18 +849,18 @@ { CBenchProps props; props.SetLzmaCompexity(); - return props.GetCompressRating(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); + return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); } UInt64 CBenchInfo::GetRating_LzmaDec() const { CBenchProps props; props.SetLzmaCompexity(); - return props.GetDecompressRating(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); + return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); } -#ifndef _7ZIP_ST +#ifndef Z7_ST #define NUM_CPU_LEVELS_MAX 3 @@ -860,14 +871,27 @@ unsigned NumCoreThreads; unsigned NumCores; // unsigned DivideNum; + +#ifdef _WIN32 + unsigned NumGroups; +#endif + UInt32 Sizes[NUM_CPU_LEVELS_MAX]; void SetLevels(unsigned numCores, unsigned numCoreThreads); DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const; bool NeedAffinity() const { return NumBundleThreads != 0; } +#ifdef _WIN32 + bool NeedGroupsMode() const { return NumGroups > 1; } +#endif + WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const { +#ifdef _WIN32 + if (NeedGroupsMode()) // we need fix for bundleIndex usage + return thread.Create_With_Group(startAddress, parameter, bundleIndex % NumGroups); +#endif if (NeedAffinity()) { CCpuSet cpuSet; @@ -881,6 +905,9 @@ NumBundleThreads(0), NumLevels(0), NumCoreThreads(1) +#ifdef _WIN32 + , NumGroups(0) +#endif // DivideNum(1) {} }; @@ -988,15 +1015,22 @@ +enum E_CheckCrcMode +{ + k_CheckCrcMode_Never = 0, + k_CheckCrcMode_Always = 1, + k_CheckCrcMode_FirstPass = 2 +}; + class CEncoderInfo; -class CEncoderInfo +class CEncoderInfo Z7_final { - CLASS_NO_COPY(CEncoderInfo) + Z7_CLASS_NO_COPY(CEncoderInfo) public: - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::CThread thread[2]; NSynchronization::CManualResetEvent ReadyEvent; UInt32 NumDecoderSubThreads; @@ -1004,6 +1038,7 @@ UInt32 EncoderIndex; UInt32 NumEncoderInternalThreads; CAffinityMode AffinityMode; + bool IsGlobalMtMode; // if more than one benchmark encoder threads #endif CMyComPtr _encoder; @@ -1024,14 +1059,17 @@ HRESULT Set_Key_and_IV(ICryptoProperties *cp) { - RINOK(cp->SetKey(_key, KeySize)); + RINOK(cp->SetKey(_key, KeySize)) return cp->SetInitVector(_iv, sizeof(_iv)); } Byte _psw[16]; - bool CheckCrc_Enc; - bool CheckCrc_Dec; + bool CheckCrc_Enc; /* = 1, if we want to check packed data crcs after each pass + used for filter and usual coders */ + bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass + used only for filter */ + E_CheckCrcMode CheckCrcMode_Dec; struct CDecoderInfo { @@ -1079,13 +1117,15 @@ HRESULT Decode(UInt32 decoderIndex); CEncoderInfo(): - #ifndef _7ZIP_ST + #ifndef Z7_ST Common(NULL), + IsGlobalMtMode(true), #endif Salt(0), KeySize(0), CheckCrc_Enc(true), - CheckCrc_Dec(true), + UseRealData_Enc(true), + CheckCrcMode_Dec(k_CheckCrcMode_Always), outStreamSpec(NULL), callback(NULL), printCallback(NULL), @@ -1093,7 +1133,7 @@ propStreamSpec(NULL) {} - #ifndef _7ZIP_ST + #ifndef Z7_ST static THREAD_FUNC_DECL EncodeThreadFunction(void *param) { @@ -1115,7 +1155,7 @@ if (res != S_OK) encoder->progressInfoSpec[0]->Status->SetResult(res); encoder->ReadyEvent.Set(); - return 0; + return THREAD_FUNC_RET_ZERO; } static THREAD_FUNC_DECL DecodeThreadFunction(void *param) @@ -1124,11 +1164,12 @@ #ifdef USE_ALLOCA alloca(decoder->AllocaSize); + // printf("\nalloca=%d\n", (unsigned)decoder->AllocaSize); #endif CEncoderInfo *encoder = decoder->Encoder; encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex); - return 0; + return THREAD_FUNC_RET_ZERO; } HRESULT CreateEncoderThread() @@ -1184,17 +1225,30 @@ const COneMethodInfo &method = _method; // we need extra space, if input data is already compressed - const size_t kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); + const size_t kCompressedBufferSize = _encoderFilter ? + kBufferSize : + GetBenchCompressedSize(kBufferSize); if (kCompressedBufferSize < kBufferSize) return E_FAIL; uncompressedDataPtr = fileData; - - if (!fileData) + if (fileData) { - ALLOC_WITH_HRESULT(&rg, kBufferSize); - + #if !defined(Z7_ST) + if (IsGlobalMtMode) + { + /* we copy the data to local buffer of thread to eliminate + using of shared buffer by different threads */ + ALLOC_WITH_HRESULT(&rg, kBufferSize) + memcpy((Byte *)rg, fileData, kBufferSize); + uncompressedDataPtr = (const Byte *)rg; + } + #endif + } + else + { + ALLOC_WITH_HRESULT(&rg, kBufferSize) // DWORD ttt = GetTickCount(); if (generateDictBits == 0) rg.GenerateSimpleRandom(Salt); @@ -1211,12 +1265,6 @@ crc = CrcCalc((const Byte *)rg, rg.Size()); uncompressedDataPtr = (const Byte *)rg; } - - if (_encoderFilter) - { - ALLOC_WITH_HRESULT(&rgCopy, kBufferSize); - } - if (!outStream) { @@ -1226,6 +1274,15 @@ ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize) + if (_encoderFilter) + { + /* we try to reduce the number of memcpy() in main encoding loop. + so we copy data to temp buffers here */ + ALLOC_WITH_HRESULT(&rgCopy, kBufferSize) + memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize); + memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize); + } + if (!propStream) { propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream; @@ -1247,22 +1304,28 @@ if (scp) { const UInt64 reduceSize = kBufferSize; - - /* in posix new thread uses same affinity as parent thread, + /* in posix : new thread uses same affinity as parent thread, so we don't need to send affinity to coder in posix */ - UInt64 affMask; - #if !defined(_7ZIP_ST) && defined(_WIN32) + UInt64 affMask = 0; + UInt32 affinityGroup = (UInt32)(Int32)-1; + // UInt64 affinityInGroup = 0; +#if !defined(Z7_ST) && defined(_WIN32) { CCpuSet cpuSet; - affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet); + if (AffinityMode.NeedGroupsMode()) // we need fix for affinityInGroup also + affinityGroup = EncoderIndex % AffinityMode.NumGroups; + else + affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet); } - #else - affMask = 0; - #endif - // affMask <<= 3; // debug line: to test no affinity in coder; - // affMask = 0; - - RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, (affMask != 0 ? &affMask : NULL))); +#endif + // affMask <<= 3; // debug line: to test no affinity in coder + // affMask = 0; // for debug + // affinityGroup = 0; // for debug + // affinityInGroup = 1; // for debug + RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, + affMask != 0 ? &affMask : NULL, + affinityGroup != (UInt32)(Int32)-1 ? &affinityGroup : NULL, + /* affinityInGroup != 0 ? &affinityInGroup : */ NULL)) } else { @@ -1274,7 +1337,7 @@ coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps); if (writeCoderProps) { - RINOK(writeCoderProps->WriteCoderProperties(propStream)); + RINOK(writeCoderProps->WriteCoderProperties(propStream)) } { @@ -1282,7 +1345,7 @@ coder.QueryInterface(IID_ICryptoSetPassword, &sp); if (sp) { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) // we must call encoding one time to calculate password key for key cache. // it must be after WriteCoderProperties! @@ -1304,7 +1367,7 @@ CMyComPtr crcStream = crcStreamSpec; crcStreamSpec->Init(); - RINOK(_encoder->Code(inStream, crcStream, 0, 0, NULL)); + RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL)) } } } @@ -1314,19 +1377,22 @@ } -static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size) +static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc) { while (size != 0) { - UInt32 cur = (UInt32)1 << 31; + UInt32 cur = crc ? 1 << 17 : 1 << 24; if (cur > size) cur = (UInt32)size; UInt32 processed = filter->Filter(data, cur); - data += processed; - // if (processed > size) (in AES filter), we must fill last block with zeros. - // but it is not important for benchmark. So we just copy that data without filtering. + /* if (processed > size) (in AES filter), we must fill last block with zeros. + but it is not important for benchmark. So we just copy that data without filtering. + if (processed == 0) then filter can't process more */ if (processed > size || processed == 0) - break; + processed = (UInt32)size; + if (crc) + *crc = CrcUpdate(*crc, data, processed); + data += processed; size -= processed; } } @@ -1336,11 +1402,11 @@ { // printf("\nCEncoderInfo::Generate\n"); - RINOK(Generate()); + RINOK(Generate()) // printf("\n2222\n"); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (Common) { Results[0] = S_OK; @@ -1375,7 +1441,7 @@ if (cp) { - RINOK(Set_Key_and_IV(cp)); + RINOK(Set_Key_and_IV(cp)) } compressedSize = 0; @@ -1384,20 +1450,32 @@ // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec; UInt64 prev = 0; - const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFF); - bool useCrc = (mask < NumIterations); + + const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF); + const bool useCrc = (mask < NumIterations); bool crcPrev_defined = false; UInt32 crcPrev = 0; - UInt64 i = NumIterations; + + bool useRealData_Enc = UseRealData_Enc; + bool data_Was_Changed = false; + if (useRealData_Enc) + { + /* we want memcpy() for each iteration including first iteration. + So results will be equal for different number of iterations */ + data_Was_Changed = true; + } + + const UInt64 numIterations = NumIterations; + UInt64 i = numIterations; // printCallback->NewLine(); while (i != 0) { i--; - if (printCallback && bi.UnpackSize - prev >= (1 << 24)) + if (printCallback && bi.UnpackSize - prev >= (1 << 26)) { - RINOK(printCallback->CheckBreak()); prev = bi.UnpackSize; + RINOK(printCallback->CheckBreak()) } /* @@ -1411,21 +1489,33 @@ if (_encoderFilter) { - // if (needRealData) - memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize); + Byte *filterData = rgCopy; + if (i == numIterations - 1 || calcCrc || useRealData_Enc) + { + // printf("\nfilterData = (Byte *)*outStreamSpec;\n"); + filterData = (Byte *)*outStreamSpec; + if (data_Was_Changed) + { + // printf("\nmemcpy(filterData, uncompressedDataPtr\n"); + memcpy(filterData, uncompressedDataPtr, kBufferSize); + } + data_Was_Changed = true; + } _encoderFilter->Init(); - My_FilterBench(_encoderFilter, (Byte *)*outStreamSpec, kBufferSize); if (calcCrc) { + // printf("\nInitCrc\n"); outStreamSpec->InitCrc(); - outStreamSpec->Calc((Byte *)*outStreamSpec, kBufferSize); } + // printf("\nMy_FilterBench\n"); + My_FilterBench(_encoderFilter, filterData, kBufferSize, + calcCrc ? &outStreamSpec->Crc : NULL); } else { outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations inStreamSpec->Init(uncompressedDataPtr, kBufferSize); - RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])); + RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])) if (!inStreamSpec->WasFinished()) return E_FAIL; if (compressedSize != outStreamSpec->Pos) @@ -1461,7 +1551,7 @@ info.PackSize = compressedSize; // printf("\n%7d\n", encoder.compressedSize); - RINOK(callback->SetEncodeResult(info, true)); + RINOK(callback->SetEncodeResult(info, true)) printCallback->NewLine(); } */ @@ -1489,6 +1579,8 @@ else coder = decoder; + // printf("\ndecoderIndex = %d, stack = %p", decoderIndex, &coder); + CMyComPtr setDecProps; coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps); if (!setDecProps && propStreamSpec->GetPos() != 0) @@ -1501,13 +1593,13 @@ pi->BenchInfo.UnpackSize = 0; pi->BenchInfo.PackSize = 0; - #ifndef _7ZIP_ST + #ifndef Z7_ST { CMyComPtr setCoderMt; coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); if (setCoderMt) { - RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)); + RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)) } } #endif @@ -1517,7 +1609,7 @@ if (scp) { const UInt64 reduceSize = _uncompressedDataSize; - RINOK(_method.SetCoderProps(scp, &reduceSize)); + RINOK(_method.SetCoderProps(scp, &reduceSize)) } CMyComPtr cp; @@ -1528,7 +1620,7 @@ RINOK(setDecProps->SetDecoderProperties2( /* (const Byte *)*propStreamSpec, */ propsData, - (UInt32)propStreamSpec->GetPos())); + (UInt32)propStreamSpec->GetPos())) } { @@ -1536,7 +1628,7 @@ coder.QueryInterface(IID_ICryptoSetPassword, &sp); if (sp) { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) } } @@ -1544,7 +1636,7 @@ if (cp) { - RINOK(Set_Key_and_IV(cp)); + RINOK(Set_Key_and_IV(cp)) } CMyComPtr setFinishMode; @@ -1559,32 +1651,38 @@ decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); } - const UInt64 numIterations = this->NumIterations; - const UInt32 mask = (CheckCrc_Dec ? 0 : 0xFFF); + const UInt64 numIterations = NumIterations; + const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec; for (UInt64 i = 0; i < numIterations; i++) { - if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 24)) + if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26)) { - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) prev = pi->BenchInfo.UnpackSize; } const UInt64 outSize = kBufferSize; - bool calcCrc = false; - if (((UInt32)i & mask) == 0) - calcCrc = true; + bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never); + crcOutStreamSpec->Init(); - + if (_decoderFilter) { - if (calcCrc) // for pure filter speed test without multi-iteration consistency - // if (needRealData) - memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize); - _decoderFilter->Init(); - My_FilterBench(_decoderFilter, (Byte *)rgCopy, compressedSize); + Byte *filterData = (Byte *)*outStreamSpec; if (calcCrc) - crcOutStreamSpec->Calc((const Byte *)rgCopy, compressedSize); + { + calcCrc = (i == 0); + if (checkCrcMode == k_CheckCrcMode_Always) + { + calcCrc = true; + memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize); + filterData = rgCopy; + } + } + _decoderFilter->Init(); + My_FilterBench(_decoderFilter, filterData, compressedSize, + calcCrc ? &crcOutStreamSpec->Crc : NULL); } else { @@ -1593,10 +1691,10 @@ if (setFinishMode) { - RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))); + RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))) } - RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex])); + RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex])) if (setFinishMode) { @@ -1609,7 +1707,7 @@ if (getInStreamProcessedSize) { UInt64 processed; - RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)); + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) if (processed != compressedSize) return S_FALSE; } @@ -1652,7 +1750,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST // ---------- CBenchThreadsFlusher ---------- @@ -1696,7 +1794,7 @@ return res; } -#endif // _7ZIP_ST +#endif // Z7_ST @@ -1714,7 +1812,7 @@ static HRESULT MethodBench( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 complexInCommands, - #ifndef _7ZIP_ST + #ifndef Z7_ST bool oldLzmaBenchMode, UInt32 numThreads, const CAffinityMode *affinityMode, @@ -1731,10 +1829,11 @@ COneMethodInfo method = method2; UInt64 methodId; UInt32 numStreams; + bool isFilter; const int codecIndex = FindMethod_Index( EXTERNAL_CODECS_LOC_VARS method.MethodName, true, - methodId, numStreams); + methodId, numStreams, isFilter); if (codecIndex < 0) return E_NOTIMPL; if (numStreams != 1) @@ -1743,7 +1842,7 @@ UInt32 numEncoderThreads = 1; UInt32 numSubDecoderThreads = 1; - #ifndef _7ZIP_ST + #ifndef Z7_ST numEncoderThreads = numThreads; if (oldLzmaBenchMode) @@ -1759,7 +1858,7 @@ } } - bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity(); + const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity(); #endif @@ -1771,10 +1870,10 @@ for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; - encoder.callback = (i == 0) ? callback : 0; + encoder.callback = (i == 0) ? callback : NULL; encoder.printCallback = printCallback; - #ifndef _7ZIP_ST + #ifndef Z7_ST encoder.EncoderIndex = i; encoder.NumEncoderInternalThreads = numSubDecoderThreads; encoder.AffinityMode = *affinityMode; @@ -1794,15 +1893,12 @@ { CCreatedCoder cod; - RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod)); + RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod)) encoder._encoder = cod.Coder; if (!encoder._encoder && !encoder._encoderFilter) return E_NOTIMPL; } - encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30; - encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30; - SetPseudoRand(encoder._iv, sizeof(encoder._iv), 17); SetPseudoRand(encoder._key, sizeof(encoder._key), 51); SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123); @@ -1811,11 +1907,27 @@ { CCreatedCoder cod; CMyComPtr &decoder = encoder._decoders[j]; - RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)); + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)) decoder = cod.Coder; if (!encoder._decoderFilter && !decoder) return E_NOTIMPL; } + + encoder.UseRealData_Enc = + encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30; + + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + if (benchProps->DecComplexCompr + + benchProps->DecComplexUnc <= 30) + encoder.CheckCrcMode_Dec = + k_CheckCrcMode_FirstPass; // for filters + // k_CheckCrcMode_Never; // for debug + // k_CheckCrcMode_Always; // for debug + if (fileData) + { + encoder.UseRealData_Enc = true; + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + } } UInt32 crc = 0; @@ -1837,7 +1949,7 @@ status.Res = S_OK; status.EncodeMode = true; - #ifndef _7ZIP_ST + #ifndef Z7_ST CBenchThreadsFlusher encoderFlusher; if (mtEncMode) { @@ -1853,12 +1965,26 @@ for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; - encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands); + encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands); // encoder.NumIterations = 3; - encoder.Salt = g_CrcTable[i & 0xFF]; - encoder.Salt ^= (g_CrcTable[(i >> 8) & 0xFF] << 3); + { +#if 0 + #define kCrcPoly 0xEDB88320 + UInt32 r = i; + unsigned num = numEncoderThreads < 256 ? 8 : 16; + do + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + while (--num); + encoder.Salt = r; +#else + UInt32 salt0 = g_CrcTable[(Byte)i]; + UInt32 salt1 = g_CrcTable[(Byte)(i >> 8)]; + encoder.Salt = salt0 ^ (salt1 << 3); +#endif + } + // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread - // printf(" %8x", encoder.Salt); + // printf("\n encoder index = %d, Salt = %8x\n", i, encoder.Salt); encoder.KeySize = benchProps->KeySize; @@ -1877,14 +2003,15 @@ bpi->BenchInfo.NumIterations = numEncoderThreads; } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (mtEncMode) { #ifdef USE_ALLOCA - encoder.AllocaSize = (i * 16 * 21) & 0x7FF; + encoder.AllocaSize = BENCH_ALLOCA_VALUE(i); #endif encoder.Common = &encoderFlusher.Common; + encoder.IsGlobalMtMode = numEncoderThreads > 1; RINOK(encoder.CreateEncoderThread()) } #endif @@ -1892,35 +2019,35 @@ if (printCallback) { - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (mtEncMode) { for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; - WRes wres = encoder.ReadyEvent.Lock(); + const WRes wres = encoder.ReadyEvent.Lock(); if (wres != 0) return HRESULT_FROM_WIN32(wres); - RINOK(encoder.Results[0]); + RINOK(encoder.Results[0]) } CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0]; bpi->SetStartTime(); - WRes wres = encoderFlusher.StartAndWait(); + const WRes wres = encoderFlusher.StartAndWait(); if (status.Res == 0 && wres != 0) return HRESULT_FROM_WIN32(wres); } else #endif { - RINOK(encoders[0].Encode()); + RINOK(encoders[0].Encode()) } - RINOK(status.Res); + RINOK(status.Res) CBenchInfo info; @@ -1931,13 +2058,13 @@ for (i = 0; i < numEncoderThreads; i++) { - CEncoderInfo &encoder = encoders[i]; + const CEncoderInfo &encoder = encoders[i]; info.UnpackSize += encoder.kBufferSize; info.PackSize += encoder.compressedSize; // printf("\n%7d\n", encoder.compressedSize); } - RINOK(callback->SetEncodeResult(info, true)); + RINOK(callback->SetEncodeResult(info, true)) @@ -1948,7 +2075,7 @@ status.EncodeMode = false; const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads; - #ifndef _7ZIP_ST + #ifndef Z7_ST const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity(); #endif @@ -1957,7 +2084,7 @@ CEncoderInfo &encoder = encoders[i]; /* - #ifndef _7ZIP_ST + #ifndef Z7_ST // encoder.affinityMode = *affinityMode; if (encoder.NumEncoderInternalThreads != 1) encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads; @@ -1967,7 +2094,11 @@ if (i == 0) { - encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands); + encoder.NumIterations = GetNumIterations( + benchProps->GetNumCommands_Dec( + encoder.compressedSize, + encoder.kBufferSize), + complexInCommands); CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; bpi->Callback = callback; bpi->BenchInfo.NumIterations = numDecoderThreads; @@ -1976,31 +2107,31 @@ else encoder.NumIterations = encoders[0].NumIterations; - #ifndef _7ZIP_ST + #ifndef Z7_ST { - int numSubThreads = method.Get_NumThreads(); + const int numSubThreads = method.Get_NumThreads(); encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads; } if (mtDecoderMode) { for (UInt32 j = 0; j < numSubDecoderThreads; j++) { - HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) + const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) #ifdef USE_ALLOCA - , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF + , BENCH_ALLOCA_VALUE(i * numSubDecoderThreads + j) #endif ); - RINOK(res); + RINOK(res) } } else #endif { - RINOK(encoder.Decode(0)); + RINOK(encoder.Decode(0)) } } - #ifndef _7ZIP_ST + #ifndef Z7_ST if (mtDecoderMode) { WRes wres = 0; @@ -2009,26 +2140,26 @@ for (UInt32 j = 0; j < numSubDecoderThreads; j++) { CEncoderInfo &encoder = encoders[i]; - WRes wres2 = encoder.thread[j]. + const WRes wres2 = encoder.thread[j]. // Wait(); // later we can get thread times from thread in UNDER_CE Wait_Close(); if (wres == 0 && wres2 != 0) wres = wres2; - HRESULT res2 = encoder.Results[j]; + const HRESULT res2 = encoder.Results[j]; if (res == 0 && res2 != 0) res = res2; } if (wres != 0) return HRESULT_FROM_WIN32(wres); - RINOK(res); + RINOK(res) } - #endif // _7ZIP_ST + #endif // Z7_ST - RINOK(status.Res); + RINOK(status.Res) encoders[0].progressInfoSpec[0]->SetFinishTime(info); /* - #ifndef _7ZIP_ST + #ifndef Z7_ST #ifdef UNDER_CE if (mtDecoderMode) for (i = 0; i < numEncoderThreads; i++) @@ -2048,13 +2179,13 @@ for (i = 0; i < numEncoderThreads; i++) { - CEncoderInfo &encoder = encoders[i]; + const CEncoderInfo &encoder = encoders[i]; info.UnpackSize += encoder.kBufferSize; info.PackSize += encoder.compressedSize; } - // RINOK(callback->SetDecodeResult(info, false)); // why we called before 21.03 ?? - RINOK(callback->SetDecodeResult(info, true)); + // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ?? + RINOK(callback->SetDecodeResult(info, true)) return S_OK; } @@ -2123,7 +2254,7 @@ const int btMode = (algo == 0 ? 0 : 1); UInt32 numBigThreads = numThreads; - bool lzmaMt = (totalBench || (numThreads > 1 && btMode)); + const bool lzmaMt = (totalBench || (numThreads > 1 && btMode)); if (btMode) { if (!totalBench && lzmaMt) @@ -2159,35 +2290,70 @@ }; +// for debug: define it to test hash calling with unaligned data +// #define Z7_BENCH_HASH_ALIGN_BUF_OFFSET 3 + HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size) { Size = size; Data = data; if (!data || CreateLocalBuf) { - ALLOC_WITH_HRESULT(&Buffer, size) - Data = Buffer; + Byte *buf; + const size_t size2 = (size + k_RandBuf_AlignMask) & ~(size_t)k_RandBuf_AlignMask; + if (size2 < size) + return E_OUTOFMEMORY; +#ifdef Z7_BENCH_HASH_ALIGN_BUF_OFFSET + ALLOC_WITH_HRESULT(&Buffer, size2 + Z7_BENCH_HASH_ALIGN_BUF_OFFSET) + buf = Buffer + Z7_BENCH_HASH_ALIGN_BUF_OFFSET; +#else + ALLOC_WITH_HRESULT(&Buffer, size2) + buf = Buffer; +#endif + Data = buf; + if (!data) + RandGen_BufAfterPad(buf, size); + else if (size != 0) // (CreateLocalBuf == true) + memcpy(buf, data, size); } - if (!data) - RandGen(Buffer, size); - else if (CreateLocalBuf && size != 0) - memcpy(Buffer, data, size); return S_OK; } +#if 1 +#define HashUpdate(hf, data, size) hf->Update(data, size) +#else +// for debug: +static void HashUpdate(IHasher *hf, const void *data, UInt32 size) +{ + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 8; + // UInt32 size2 = size / 2; + if (size2 == 0) + size2 = 1; + hf->Update(data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +} +#endif + + HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, const UInt32 *checkSum, IHasher *hf, IBenchPrintCallback *callback) { MY_ALIGN(16) - Byte hash[64]; - memset(hash, 0, sizeof(hash)); + UInt32 hash32[64 / 4]; + memset(hash32, 0, sizeof(hash32)); CheckSum_Res = 0; const UInt32 hashSize = hf->GetDigestSize(); - if (hashSize > sizeof(hash)) + if (hashSize > sizeof(hash32)) return S_FALSE; const Byte *buf = Data; @@ -2197,7 +2363,7 @@ UInt64 prev = 0; UInt64 cur = 0; - for (UInt64 i = 0; i < numIterations; i++) + do { hf->Init(); size_t pos = 0; @@ -2206,17 +2372,17 @@ const size_t rem = size - pos; const UInt32 kStep = ((UInt32)1 << 31); const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep; - hf->Update(buf + pos, curSize); + HashUpdate(hf, buf + pos, curSize); pos += curSize; } while (pos != size); - hf->Final(hash); + hf->Final((Byte *)(void *)hash32); UInt32 sum = 0; for (UInt32 j = 0; j < hashSize; j += 4) { sum = rotlFixed(sum, 11); - sum += GetUi32(hash + j); + sum += GetUi32((const Byte *)(const void *)hash32 + j); } if (checkSum) { @@ -2234,10 +2400,12 @@ if (cur - prev >= ((UInt32)1 << 30)) { prev = cur; - RINOK(callback->CheckBreak()); + RINOK(callback->CheckBreak()) } } } + while (--numIterations); + CheckSum_Res = checkSum_Prev; return S_OK; } @@ -2266,7 +2434,7 @@ EXTERN_C_END -#ifndef _7ZIP_ST +#ifndef Z7_ST struct CBaseThreadInfo { @@ -2300,12 +2468,12 @@ { p->CallbackRes = p->Callback->CheckBreak(); if (p->CallbackRes != S_OK) - return 0; + break; } sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp); } p->ValRes = sum; - return 0; + return THREAD_FUNC_RET_ZERO; } struct CFreqThreads @@ -2349,7 +2517,7 @@ HRESULT Res; UInt32 CheckSum_Res; - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CManualResetEvent ReadyEvent; UInt32 ThreadIndex; CBenchSyncCommon *Common; @@ -2433,7 +2601,7 @@ alloca(p->AllocaSize); #endif p->Process(); - return 0; + return THREAD_FUNC_RET_ZERO; } @@ -2478,13 +2646,15 @@ #endif +/* static UInt32 CrcCalc1(const Byte *buf, size_t size) { - UInt32 crc = CRC_INIT_VAL;; + UInt32 crc = CRC_INIT_VAL; for (size_t i = 0; i < size; i++) crc = CRC_UPDATE_BYTE(crc, buf[i]); return CRC_GET_DIGEST(crc); } +*/ /* static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG) @@ -2497,34 +2667,30 @@ static bool CrcInternalTest() { CAlignedBuffer buffer; - const size_t kBufferSize0 = (1 << 8); - const size_t kBufferSize1 = (1 << 10); - const unsigned kCheckSize = (1 << 5); - buffer.Alloc(kBufferSize0 + kBufferSize1); + const size_t kBufSize = 1 << 11; + const size_t kCheckSize = 1 << 6; + buffer.Alloc(kBufSize); if (!buffer.IsAllocated()) return false; Byte *buf = (Byte *)buffer; - size_t i; - for (i = 0; i < kBufferSize0; i++) - buf[i] = (Byte)i; - UInt32 crc1 = CrcCalc1(buf, kBufferSize0); - if (crc1 != 0x29058C73) - return false; - RandGen(buf + kBufferSize0, kBufferSize1); - for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++) - for (unsigned j = 0; j < kCheckSize; j++) - if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j)) - return false; - return true; + RandGen_BufAfterPad(buf, kBufSize); + UInt32 sum = 0; + for (size_t i = 0; i < kBufSize - kCheckSize * 2; i += kCheckSize - 1) + for (size_t j = 0; j < kCheckSize; j++) + { + sum = rotlFixed(sum, 11); + sum += CrcCalc(buf + i + j, j); + } + return sum == 0x28462c7c; } struct CBenchMethod { unsigned Weight; unsigned DictBits; - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; const char *Name; // unsigned KeySize; }; @@ -2563,6 +2729,9 @@ // { 10, 22, 1655, 0, 1830, "PPMDZip:x5" }, { 10, 22, 1655, 0, 1830, "PPMD:x5" }, + // { 2, 0, -16, 0, -16, "Swap2" }, + { 2, 0, -16, 0, -16, "Swap4" }, + // { 2, 0, 3, 0, 4, "Delta:1" }, // { 2, 0, 3, 0, 4, "Delta:2" }, // { 2, 0, 3, 0, 4, "Delta:3" }, @@ -2570,8 +2739,10 @@ // { 2, 0, 3, 0, 4, "Delta:8" }, // { 2, 0, 3, 0, 4, "Delta:32" }, - { 2, 0, 4, 0, 4, "BCJ" }, - + { 2, 0, 2, 0, 2, "BCJ" }, + { 2, 0, 1, 0, 1, "ARM64" }, + { 2, 0, 1, 0, 1, "RISCV" }, + // { 10, 0, 18, 0, 18, "AES128CBC:1" }, // { 10, 0, 21, 0, 21, "AES192CBC:1" }, { 10, 0, 24, 0, 24, "AES256CBC:1" }, @@ -2587,13 +2758,13 @@ // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" }, // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" }, - // { 1, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:3" }, - // { 1, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:3" }, - { 1, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:3" } - - // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:3" }, - // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:3" }, - // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:3" }, + // { 1, 0, CMPLX(6), 0, -2, "AES128CBC:3" }, + // { 1, 0, CMPLX(7), 0, -2, "AES192CBC:3" }, + { 1, 0, CMPLX(8), 0, -2, "AES256CBC:3" } + + // { 1, 0, CMPLX(1), 0, -2, "AES128CTR:3" }, + // { 1, 0, CMPLX(1), 0, -2, "AES192CTR:3" }, + // { 1, 0, CMPLX(1), 0, -2, "AES256CTR:3" }, }; struct CBenchHash @@ -2607,22 +2778,37 @@ // #define ARM_CRC_MUL 100 #define ARM_CRC_MUL 1 +#define k_Hash_Complex_Mult 256 + static const CBenchHash g_Hash[] = { - { 1, 1820, 0x21e207bb, "CRC32:1" }, - { 10, 558, 0x21e207bb, "CRC32:4" }, - { 10, 339, 0x21e207bb, "CRC32:8" } , + { 20, 256, 0x21e207bb, "CRC32:12" } , { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" }, { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" }, - { 10, 512, 0x41b901d1, "CRC64" }, - - { 10, 5100, 0x7913ba03, "SHA256:1" }, - { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, - - { 10, 2340, 0xff769021, "SHA1:1" }, + { 10, 256, 0x41b901d1, "CRC64" }, + { 5, 64, 0x43eac94f, "XXH64" }, + { 2, 2340, 0x3398a904, "MD5" }, + { 10, 2340, 0xff769021, "SHA1:1" }, { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" }, - - { 2, 5500, 0x85189d02, "BLAKE2sp" } + { 10, 5100, 0x7913ba03, "SHA256:1" }, + { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, + { 5, 3200, 0xe7aeb394, "SHA512:1" }, + { 2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" }, + // { 10, 3428, 0x1cc99b18, "SHAKE128" }, + // { 10, 4235, 0x74eaddc3, "SHAKE256" }, + // { 10, 4000, 0xdf3e6863, "SHA3-224" }, + { 5, 4200, 0xcecac10d, "SHA3-256" }, + // { 10, 5538, 0x4e5d9163, "SHA3-384" }, + // { 10, 8000, 0x96a58289, "SHA3-512" }, + { 2, 4096, 0x85189d02, "BLAKE2sp:1" }, + { 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast + { 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast +#if 0 + , { 2, 2048, 0x85189d02, "BLAKE2sp:4" } // sse2-way1 + , { 2, 1024, 0x85189d02, "BLAKE2sp:5" } // sse2-way2 + , { 2, 1024, 0x85189d02, "BLAKE2sp:6" } // avx2-way2 + , { 2, 1024, 0x85189d02, "BLAKE2sp:7" } // avx2-way4 +#endif }; static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) @@ -2656,6 +2842,8 @@ static const unsigned kFieldSize_Rating = 6; static const unsigned kFieldSize_EU = 5; static const unsigned kFieldSize_Effec = 5; +static const unsigned kFieldSize_CrcSpeed = 8; + static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating; static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec; @@ -2796,7 +2984,7 @@ { AString s; // s.Add_UInt32(ti.numProcessThreads); - unsigned numSysThreads = ti.GetNumSystemThreads(); + const unsigned numSysThreads = ti.GetNumSystemThreads(); if (ti.GetNumProcessThreads() != numSysThreads) { // if (ti.numProcessThreads != ti.numSysThreads) @@ -2826,11 +3014,40 @@ } #endif } +#ifdef _WIN32 + if (ti.Groups.GroupSizes.Size() > 1 || + (ti.Groups.GroupSizes.Size() == 1 + && ti.Groups.NumThreadsTotal != numSysThreads)) + { + s += " : "; + s.Add_UInt32(ti.Groups.GroupSizes.Size()); + s += " groups : "; + if (ti.Groups.NumThreadsTotal == numSysThreads) + { + s.Add_UInt32(ti.Groups.NumThreadsTotal); + s += " c : "; + } + UInt32 minSize, maxSize; + ti.Groups.Get_GroupSize_Min_Max(minSize, maxSize); + if (minSize == maxSize) + { + s.Add_UInt32(ti.Groups.GroupSizes[0]); + s += " c/g"; + } + else + FOR_VECTOR (i, ti.Groups.GroupSizes) + { + if (i != 0) + s.Add_Char(' '); + s.Add_UInt32(ti.Groups.GroupSizes[i]); + } + } +#endif return s; } -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES #ifdef _WIN32 extern bool g_LargePagesMode; @@ -2875,7 +3092,7 @@ f.Print(" ?"); f.Print(" MB"); - #ifdef _7ZIP_LARGE_PAGES + #ifdef Z7_LARGE_PAGES { AString s; Add_LargePages_String(s); @@ -2890,30 +3107,34 @@ -struct CBenchCallbackToPrint: public IBenchCallback +struct CBenchCallbackToPrint Z7_final: public IBenchCallback { - CBenchProps BenchProps; - CTotalBenchRes EncodeRes; - CTotalBenchRes DecodeRes; - IBenchPrintCallback *_file; - UInt64 DictSize; - + bool NeedPrint; bool Use2Columns; - unsigned NameFieldSize; - bool ShowFreq; - UInt64 CpuFreq; + unsigned NameFieldSize; unsigned EncodeWeight; unsigned DecodeWeight; + UInt64 CpuFreq; + UInt64 DictSize; + + IBenchPrintCallback *_file; + CBenchProps BenchProps; + CTotalBenchRes EncodeRes; + CTotalBenchRes DecodeRes; + + CBenchInfo BenchInfo_Results[2]; + CBenchCallbackToPrint(): + NeedPrint(true), Use2Columns(false), - NameFieldSize(0), ShowFreq(false), - CpuFreq(0), + NameFieldSize(0), EncodeWeight(1), - DecodeWeight(1) + DecodeWeight(1), + CpuFreq(0) {} void Init() { EncodeRes.Init(); DecodeRes.Init(); } @@ -2921,8 +3142,8 @@ void NewLine(); HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); - HRESULT SetEncodeResult(const CBenchInfo &info, bool final); - HRESULT SetDecodeResult(const CBenchInfo &info, bool final); + HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override; + HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override; }; HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq) @@ -2934,10 +3155,13 @@ HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) + if (final) + BenchInfo_Results[0] = info; if (final) + if (NeedPrint) { - UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); + const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); PrintResults(_file, info, EncodeWeight, rating, ShowFreq, CpuFreq, &EncodeRes); @@ -2951,10 +3175,13 @@ HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) + if (final) + BenchInfo_Results[1] = info; if (final) + if (NeedPrint) { - UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); + const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); if (Use2Columns) _file->Print(kSep); else @@ -2996,10 +3223,22 @@ f.Print(s); } + +static bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name) +{ + UString wildc = GetUnicodeString(mask); + UString bname = GetUnicodeString(name); + wildc.MakeLower_Ascii(); + bname.MakeLower_Ascii(); + return DoesWildcardMatchName(wildc, bname); +} + + static HRESULT TotalBench( DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, UInt64 complexInCommands, - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 numThreads, const CAffinityMode *affinityMode, #endif @@ -3008,9 +3247,11 @@ const Byte *fileData, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) { const CBenchMethod &bench = g_Bench[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); { unsigned keySize = 32; @@ -3025,7 +3266,7 @@ COneMethodInfo method; NCOM::CPropVariant propVariant; propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) size_t unpackSize2 = unpackSize; if (!forceUnpackSize && bench.DictBits == 0) @@ -3034,10 +3275,10 @@ callback->EncodeWeight = bench.Weight; callback->DecodeWeight = bench.Weight; - HRESULT res = MethodBench( + const HRESULT res = MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, - #ifndef _7ZIP_ST + #ifndef Z7_ST false, numThreads, affinityMode, #endif method, @@ -3054,7 +3295,7 @@ } else { - RINOK(res); + RINOK(res) } callback->NewLine(); @@ -3080,7 +3321,7 @@ {} HRESULT FreqBench(IBenchPrintCallback *_file - #ifndef _7ZIP_ST + #ifndef Z7_ST , const CAffinityMode *affinityMode #endif ); @@ -3088,7 +3329,7 @@ HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file - #ifndef _7ZIP_ST + #ifndef Z7_ST , const CAffinityMode *affinityMode #endif ) @@ -3100,7 +3341,7 @@ if (numThreads == 0) numThreads = 1; - #ifdef _7ZIP_ST + #ifdef Z7_ST numThreads = 1; #endif @@ -3117,7 +3358,7 @@ CBenchInfoCalc progressInfoSpec; - #ifndef _7ZIP_ST + #ifndef Z7_ST bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity(); @@ -3150,7 +3391,7 @@ return HRESULT_FROM_WIN32(wres); for (i = 0; i < numThreads; i++) { - RINOK(threads.Items[i].CallbackRes); + RINOK(threads.Items[i].CallbackRes) } } else @@ -3158,21 +3399,23 @@ { progressInfoSpec.SetStartTime(); UInt32 sum = g_BenchCpuFreqTemp; - for (UInt64 k = numIterations; k > 0; k--) + UInt64 k = numIterations; + do { sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp); if (_file) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) } } + while (--k); res += sum; } if (res == 0x12345678) if (_file) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) } CBenchInfo info; @@ -3193,7 +3436,7 @@ 0, // weight rating, showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL); - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) } return S_OK; @@ -3215,7 +3458,7 @@ const UInt32 *checkSum, const COneMethodInfo &method, IBenchPrintCallback *_file, - #ifndef _7ZIP_ST + #ifndef Z7_ST const CAffinityMode *affinityMode, #endif bool showRating, @@ -3225,7 +3468,7 @@ if (numThreads == 0) numThreads = 1; - #ifdef _7ZIP_ST + #ifdef Z7_ST numThreads = 1; #endif @@ -3249,14 +3492,14 @@ */ const size_t bsize = (bufferSize == 0 ? 1 : bufferSize); - UInt64 numIterations = complexInCommands * 256 / complexity / bsize; + UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize; if (numIterations == 0) numIterations = 1; CBenchInfoCalc progressInfoSpec; CBenchInfo info; - #ifndef _7ZIP_ST + #ifndef Z7_ST bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity(); if (mtEncMode) @@ -3275,14 +3518,14 @@ { CCrcInfo &ci = threads.Items[i]; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher)); + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher)) if (!ci.Hasher) return E_NOTIMPL; CMyComPtr scp; ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - RINOK(method.SetCoderProps(scp)); + RINOK(method.SetCoderProps(scp)) } ci.Callback = _file; @@ -3297,7 +3540,7 @@ } #ifdef USE_ALLOCA - ci.AllocaSize = (i * 16 * 21) & 0x7FF; + ci.AllocaSize = BENCH_ALLOCA_VALUE(i); #endif } @@ -3320,7 +3563,7 @@ WRes wres = ci.ReadyEvent.Lock(); if (wres != 0) return HRESULT_FROM_WIN32(wres); - RINOK(ci.Res); + RINOK(ci.Res) } progressInfoSpec.SetStartTime(); @@ -3333,7 +3576,7 @@ for (i = 0; i < numThreads; i++) { - RINOK(threads.Items[i].Res); + RINOK(threads.Items[i].Res) if (i != 0) if (threads.Items[i].CheckSum_Res != threads.Items[i - 1].CheckSum_Res) @@ -3345,20 +3588,20 @@ { CMyComPtr hasher; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)); + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)) if (!hasher) return E_NOTIMPL; CMyComPtr scp; hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - RINOK(method.SetCoderProps(scp)); + RINOK(method.SetCoderProps(scp)) } CCrcInfo_Base crcib; crcib.CreateLocalBuf = false; - RINOK(crcib.Generate(fileData, bufferSize)); + RINOK(crcib.Generate(fileData, bufferSize)) progressInfoSpec.SetStartTime(); - RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file)); + RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file)) progressInfoSpec.SetFinishTime(info); } @@ -3382,7 +3625,7 @@ benchWeight, rating, showFreq, cpuFreq, encodeRes); } - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) } speed = info.GetSpeed(unpSizeThreads); @@ -3395,20 +3638,23 @@ static HRESULT TotalBench_Hash( DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, UInt64 complexInCommands, UInt32 numThreads, size_t bufSize, const Byte *fileData, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback, - #ifndef _7ZIP_ST + #ifndef Z7_ST const CAffinityMode *affinityMode, #endif CTotalBenchRes *encodeRes, bool showFreq, UInt64 cpuFreq) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) { const CBenchHash &bench = g_Hash[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; @@ -3417,11 +3663,11 @@ COneMethodInfo method; NCOM::CPropVariant propVariant; propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) UInt64 speed, usage; - HRESULT res = CrcBench( + const HRESULT res = CrcBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads, bufSize, fileData, @@ -3430,7 +3676,7 @@ (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL, method, printCallback, - #ifndef _7ZIP_ST + #ifndef Z7_ST affinityMode, #endif true, // showRating @@ -3441,7 +3687,7 @@ } else { - RINOK(res); + RINOK(res) } callback->NewLine(); } @@ -3451,7 +3697,8 @@ struct CTempValues { UInt64 *Values; - CTempValues(UInt32 num) { Values = new UInt64[num]; } + CTempValues(): Values(NULL) {} + void Alloc(UInt32 num) { Values = new UInt64[num]; } ~CTempValues() { delete []Values; } }; @@ -3482,6 +3729,29 @@ } +static void Print_Delimiter(IBenchPrintCallback &f) +{ + f.Print(" |"); +} + +static void Print_Pow(IBenchPrintCallback &f, unsigned pow) +{ + char s[16]; + ConvertUInt32ToString(pow, s); + unsigned pos = MyStringLen(s); + s[pos++] = ':'; + s[pos] = 0; + PrintLeft(f, s, kFieldSize_SmallName); // 4 +} + +static void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f, + UInt64 usage, UInt64 speed) +{ + PrintUsage(f, usage, kFieldSize_Usage); + PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed); +} + + HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS IBenchPrintCallback *printCallback, @@ -3491,16 +3761,17 @@ bool multiDict, IBenchFreqCallback *freqCallback) { + // for (int y = 0; y < 10000; y++) if (!CrcInternalTest()) return E_FAIL; UInt32 numCPUs = 1; - UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; + size_t ramSize = (size_t)sizeof(size_t) << 29; NSystem::CProcessAffinity threadsInfo; threadsInfo.InitST(); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0) numCPUs = threadsInfo.GetNumProcessThreads(); @@ -3521,7 +3792,7 @@ } */ - bool ramSize_Defined = NSystem::GetRamSize(ramSize); + const bool ramSize_Defined = NSystem::GetRamSize(ramSize); UInt32 numThreadsSpecified = numCPUs; bool needSetComplexity = false; @@ -3533,9 +3804,13 @@ UInt64 complexInCommands = kComplexInCommands; UInt32 numThreads_Start = 1; - #ifndef _7ZIP_ST +#ifndef Z7_ST CAffinityMode affinityMode; - #endif +#ifdef _WIN32 + if (threadsInfo.IsGroupMode && threadsInfo.Groups.GroupSizes.Size() > 1) + affinityMode.NumGroups = threadsInfo.Groups.GroupSizes.Size(); +#endif +#endif COneMethodInfo method; @@ -3597,7 +3872,7 @@ // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here - ALLOC_WITH_HRESULT(&fileDataBuffer, len); + ALLOC_WITH_HRESULT(&fileDataBuffer, len) use_fileData = true; { @@ -3616,7 +3891,7 @@ if (name.IsEqualTo("time")) { - RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)); + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) needSetComplexity = true; testTimeMs *= 1000; continue; @@ -3624,7 +3899,7 @@ if (name.IsEqualTo("timems")) { - RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)); + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) needSetComplexity = true; continue; } @@ -3632,7 +3907,7 @@ if (name.IsEqualTo("tic")) { UInt32 v; - RINOK(ParsePropToUInt32(UString(), propVariant, v)); + RINOK(ParsePropToUInt32(UString(), propVariant, v)) if (v >= 64) return E_INVALIDARG; complexInCommands = (UInt64)1 << v; @@ -3644,7 +3919,7 @@ isFixedDict = true; if (isCurrent_fixedDict || name.IsEqualTo("ds")) { - RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog)); + RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog)) if (startDicLog > 32) return E_INVALIDARG; startDicLog_Defined = true; @@ -3653,17 +3928,17 @@ if (name.IsEqualTo("mts")) { - RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start)); + RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start)) continue; } if (name.IsEqualTo("af")) { UInt32 bundle; - RINOK(ParsePropToUInt32(UString(), propVariant, bundle)); + RINOK(ParsePropToUInt32(UString(), propVariant, bundle)) if (bundle > 0 && bundle < numCPUs) { - #ifndef _7ZIP_ST + #ifndef Z7_ST affinityMode.SetLevels(numCPUs, 2); affinityMode.NumBundleThreads = bundle; #endif @@ -3674,7 +3949,7 @@ if (name.IsEqualTo("freq")) { UInt32 freq32 = 0; - RINOK(ParsePropToUInt32(UString(), propVariant, freq32)); + RINOK(ParsePropToUInt32(UString(), propVariant, freq32)) if (freq32 == 0) return E_INVALIDARG; specifiedFreq = (UInt64)freq32 * 1000000; @@ -3691,7 +3966,7 @@ if (name.IsPrefixedBy_Ascii_NoCase("mt")) { - UString s = name.Ptr(2); + const UString s = name.Ptr(2); if (s.IsEqualTo("*") || (s.IsEmpty() && propVariant.vt == VT_BSTR @@ -3700,13 +3975,13 @@ multiThreadTests = true; continue; } - #ifndef _7ZIP_ST - RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)); + #ifndef Z7_ST + RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)) #endif continue; } - RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)) } } @@ -3714,13 +3989,13 @@ { AString s; - #ifndef _WIN32 +#if 1 || !defined(Z7_MSC_VER_ORIGINAL) || (Z7_MSC_VER_ORIGINAL >= 1900) s += "Compiler: "; GetCompiler(s); printCallback->Print(s); printCallback->NewLine(); s.Empty(); - #endif +#endif GetSystemInfoText(s); printCallback->Print(s); @@ -3744,7 +4019,7 @@ for (int jj = 0;; jj++) { if (printCallback) - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) UInt64 start = ::GetTimeCount(); UInt32 sum = (UInt32)start; @@ -3760,7 +4035,7 @@ start = 1; const UInt64 freq = GetFreq(); // mips is constant in some compilers - const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, freq, start); + const UInt64 hzVal = MyMultDiv64(numMilCommands * 1000000, freq, start); const UInt64 mipsVal = numMilCommands * freq / start; if (printCallback) { @@ -3776,7 +4051,7 @@ } if (freqCallback) { - RINOK(freqCallback->AddCpuFreq(1, hz, kBenchmarkUsageMult)); + RINOK(freqCallback->AddCpuFreq(1, hzVal, kBenchmarkUsageMult)) } if (jj >= 1) @@ -3806,20 +4081,33 @@ } if (freqCallback) { - RINOK(freqCallback->FreqsFinished(1)); + RINOK(freqCallback->FreqsFinished(1)) } } - if (numThreadsSpecified >= 2) if (printCallback || freqCallback) + for (unsigned test = 0; test < 3; test++) { + if (numThreadsSpecified < 2) + { + // if (test == 1) + break; + } + if (test == 2 && numThreadsSpecified <= numCPUs) + break; if (printCallback) printCallback->NewLine(); - /* it can show incorrect frequency for HT threads. - so we reduce freq test to (numCPUs / 2) */ + /* it can show incorrect frequency for HT threads. */ - UInt32 numThreads = numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2: numThreadsSpecified; + UInt32 numThreads = numThreadsSpecified; + if (test < 2) + { + if (numThreads >= numCPUs) + numThreads = numCPUs; + if (test == 0) + numThreads /= 2; + } if (numThreads < 1) numThreads = 1; @@ -3830,17 +4118,24 @@ printCallback->Print(s); printCallback->Print("T CPU Freq (MHz):"); } - UInt64 numMilCommands = 1 << 10; + UInt64 numMilCommands = 1 << + #ifdef _DEBUG + 7; + #else + 10; + #endif + if (specifiedFreq != 0) { while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) numMilCommands >>= 1; } - for (int jj = 0;; jj++) + // for (int jj = 0;; jj++) + for (;;) { if (printCallback) - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) { // PrintLeft(f, "CPU", kFieldSize_Name); @@ -3855,16 +4150,16 @@ fb.showFreq = true; fb.specifiedFreq = 1; - HRESULT res = fb.FreqBench(NULL /* printCallback */ - #ifndef _7ZIP_ST + const HRESULT res = fb.FreqBench(NULL /* printCallback */ + #ifndef Z7_ST , &affinityMode #endif ); - RINOK(res); + RINOK(res) if (freqCallback) { - RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes)); + RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes)) } if (printCallback) @@ -3889,7 +4184,7 @@ } // if (jj >= 1) { - bool needStop = (numMilCommands >= (1 << + const bool needStop = (numMilCommands >= (1 << #ifdef _DEBUG 7 #else @@ -3903,7 +4198,7 @@ } if (freqCallback) { - RINOK(freqCallback->FreqsFinished(numThreads)); + RINOK(freqCallback->FreqsFinished(numThreads)) } } @@ -3923,10 +4218,12 @@ UInt64 dict = (UInt64)1 << startDicLog; const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict)); - const int level = method.GetLevel(); + const unsigned level = method.GetLevel(); - if (method.MethodName.IsEmpty()) - method.MethodName = "LZMA"; + AString &methodName = method.MethodName; + const AString original_MethodName = methodName; + if (methodName.IsEmpty()) + methodName = "LZMA"; if (benchCallback) { @@ -3949,7 +4246,7 @@ return MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, - #ifndef _7ZIP_ST + #ifndef Z7_ST true, numThreadsSpecified, &affinityMode, #endif @@ -3958,13 +4255,28 @@ kOldLzmaDictBits, printCallback, benchCallback, &benchProps); } - AString methodName (method.MethodName); if (methodName.IsEqualTo_Ascii_NoCase("CRC")) methodName = "crc32"; - method.MethodName = methodName; + CMethodId hashID; - - if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID)) + const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID); + int codecIndex = -1; + bool isFilter = false; + if (!isHashMethod) + { + UInt32 numStreams; + codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName, + true, // encode + hashID, numStreams, isFilter); + // we can allow non filter for BW tests + if (!isFilter) codecIndex = -1; + } + + CBenchCallbackToPrint callback; + callback.Init(); + callback._file = printCallback; + + if (isHashMethod || codecIndex != -1) { if (!printCallback) return S_FALSE; @@ -3981,17 +4293,27 @@ dict64 = fileDataBuffer.Size(); } - // methhodName.RemoveChar(L'-'); - UInt32 complexity = 10000; + for (;;) + { + const int index = method.FindProp(NCoderPropID::kDictionarySize); + if (index < 0) + break; + method.Props.Delete((unsigned)index); + } + + // methodName.RemoveChar(L'-'); + Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method const UInt32 *checkSum = NULL; + int benchIndex = -1; + + if (isHashMethod) { - unsigned i; - for (i = 0; i < ARRAY_SIZE(g_Hash); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) { const CBenchHash &h = g_Hash[i]; AString benchMethod (h.Name); AString benchProps; - int propPos = benchMethod.Find(':'); + const int propPos = benchMethod.Find(':'); if (propPos >= 0) { benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); @@ -4000,45 +4322,80 @@ if (AreSameMethodNames(benchMethod, methodName)) { - bool isMainMathed = method.PropsString.IsEmpty(); - if (isMainMathed) - isMainMathed = !checkSum - || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8")); const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); - if (sameProps || isMainMathed) + /* + bool isMainMethod = method.PropsString.IsEmpty(); + if (isMainMethod) + isMainMethod = !checkSum + || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8")); + if (sameProps || isMainMethod) + */ { - complexity = h.Complex; + complexity = (Int32)h.Complex; checkSum = &h.CheckSum; if (sameProps) break; + /* + if property. is not specified, we use the complexity + for latest fastest method (crc32:64) + */ } } } - if (!checkSum) - return E_NOTIMPL; + // if (!checkSum) return E_NOTIMPL; + } + else + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) + { + const CBenchMethod &bench = g_Bench[i]; + AString benchMethod (bench.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) + { + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); + // bool isMainMethod = method.PropsString.IsEmpty(); + // if (sameProps || isMainMethod) + { + benchIndex = (int)i; + if (sameProps) + break; + } + } + } + // if (benchIndex < 0) return E_NOTIMPL; } { - UInt64 usage = 1 << 20; + /* we count usage only for crc and filter. non-filters are not supported */ + UInt64 usage = (1 << 20); UInt64 bufSize = dict64; + UInt32 numBlocks = isHashMethod ? 1 : 3; if (use_fileData) { usage += fileDataBuffer.Size(); if (bufSize > fileDataBuffer.Size()) bufSize = fileDataBuffer.Size(); - #ifndef _7ZIP_ST - if (numThreadsSpecified != 1) - usage += bufSize * numThreadsSpecified * (k_Crc_CreateLocalBuf_For_File ? 1 : 0); - #endif + if (isHashMethod) + { + numBlocks = 0; + #ifndef Z7_ST + if (numThreadsSpecified != 1) + numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0); + #endif + } } - else - usage += numThreadsSpecified * bufSize; + usage += numThreadsSpecified * bufSize * numBlocks; Print_Usage_and_Threads(f, usage, numThreadsSpecified); } - - f.NewLine(); - - const unsigned kFieldSize_CrcSpeed = 7; + CUIntVector numThreadsVector; { unsigned nt = numThreads_Start; @@ -4047,136 +4404,225 @@ if (nt > numThreadsSpecified) break; numThreadsVector.Add(nt); - unsigned next = nt * 2; - UInt32 ntHalf= numThreadsSpecified / 2; + const unsigned next = nt * 2; + const UInt32 ntHalf= numThreadsSpecified / 2; if (ntHalf > nt && ntHalf < next) numThreadsVector.Add(ntHalf); if (numThreadsSpecified > nt && numThreadsSpecified < next) numThreadsVector.Add(numThreadsSpecified); nt = next; } + } + + unsigned numColumns = isHashMethod ? 1 : 2; + CTempValues speedTotals; + CTempValues usageTotals; + { + const unsigned numItems = numThreadsVector.Size() * numColumns; + speedTotals.Alloc(numItems); + usageTotals.Alloc(numItems); + for (unsigned i = 0; i < numItems; i++) { - f.NewLine(); - f.Print("THRD"); - FOR_VECTOR (ti, numThreadsVector) - { - PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed); - } + speedTotals.Values[i] = 0; + usageTotals.Values[i] = 0; } + } + + f.NewLine(); + for (unsigned line = 0; line < 3; line++) + { + f.NewLine(); + f.Print(line == 0 ? "THRD" : line == 1 ? " " : "Size"); + FOR_VECTOR (ti, numThreadsVector) { - f.NewLine(); - f.Print(" "); - FOR_VECTOR (ti, numThreadsVector) + if (ti != 0) + Print_Delimiter(f); + if (line == 0) { - PrintRight(f, "Usage", kFieldSize_Usage + 1); - PrintRight(f, "BW", kFieldSize_CrcSpeed + 1); + PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1)); + PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed); } - } - { - f.NewLine(); - f.Print("Size"); - FOR_VECTOR (ti, numThreadsVector) + else { - PrintRight(f, "%", kFieldSize_Usage + 1); - PrintRight(f, "MB/s", kFieldSize_CrcSpeed + 1); + for (unsigned c = 0; c < numColumns; c++) + { + PrintRight(f, line == 1 ? "Usage" : "%", kFieldSize_Usage + 1); + PrintRight(f, line == 1 ? "BW" : "MB/s", kFieldSize_CrcSpeed + 1); + } } } } - - f.NewLine(); f.NewLine(); - CTempValues speedTotals(numThreadsVector.Size()); - CTempValues usageTotals(numThreadsVector.Size()); - { - FOR_VECTOR (ti, numThreadsVector) - { - speedTotals.Values[ti] = 0; - usageTotals.Values[ti] = 0; - } - } - UInt64 numSteps = 0; - for (UInt32 i = 0; i < numIterations; i++) - { - unsigned pow = 10; // kNumHashDictBits - if (startDicLog_Defined) - pow = startDicLog; - for (;; pow++) - { - const UInt64 bufSize = (UInt64)1 << pow; - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos++] = ' '; - s[pos] = 0; - PrintRight(f, s, 4); - - size_t dataSize = fileDataBuffer.Size(); - if (dataSize > bufSize || !use_fileData) - dataSize = (size_t)bufSize; - + // for (UInt32 iter = 0; iter < numIterations; iter++) + // { + unsigned pow = 10; // kNumHashDictBits + if (startDicLog_Defined) + pow = startDicLog; + + // #define NUM_SUB_BITS 2 + // pow <<= NUM_SUB_BITS; + for (;; pow++) + { + const UInt64 bufSize = (UInt64)1 << pow; + // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS); + // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS); + + size_t dataSize = fileDataBuffer.Size(); + if (dataSize > bufSize || !use_fileData) + dataSize = (size_t)bufSize; + + for (UInt32 iter = 0; iter < numIterations; iter++) + { + Print_Pow(f, pow); + // PrintNumber(f, bufSize >> 10, 4); + FOR_VECTOR (ti, numThreadsVector) { - RINOK(f.CheckBreak()); - const UInt32 t = numThreadsVector[ti]; - UInt64 speed = 0; - UInt64 usage = 0; - - HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, - t, + RINOK(f.CheckBreak()) + const UInt32 numThreads = numThreadsVector[ti]; + if (isHashMethod) + { + UInt64 speed = 0; + UInt64 usage = 0; + const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, + numThreads, dataSize, (const Byte *)fileDataBuffer, speed, usage, - complexity, + (UInt32)complexity, 1, // benchWeight, (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL, method, &f, - #ifndef _7ZIP_ST + #ifndef Z7_ST &affinityMode, #endif false, // showRating NULL, false, 0); - - RINOK(res); - - PrintUsage(f, usage, kFieldSize_Usage); - PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed); - speedTotals.Values[ti] += speed; - usageTotals.Values[ti] += usage; + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + Bench_BW_Print_Usage_Speed(f, usage, speed); + speedTotals.Values[ti] += speed; + usageTotals.Values[ti] += usage; + } + else + { + { + unsigned keySize = 32; + if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16; + else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24; + callback.BenchProps.KeySize = keySize; + } + + COneMethodInfo method2 = method; + unsigned bench_DictBits; + + if (benchIndex >= 0) + { + const CBenchMethod &bench = g_Bench[benchIndex]; + callback.BenchProps.EncComplex = bench.EncComplex; + callback.BenchProps.DecComplexUnc = bench.DecComplexUnc; + callback.BenchProps.DecComplexCompr = bench.DecComplexCompr; + bench_DictBits = bench.DictBits; + // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug + } + else + { + bench_DictBits = kOldLzmaDictBits; // = 32 default + if (isFilter) + { + const unsigned k_UnknownCoderComplexity = 4; + callback.BenchProps.EncComplex = k_UnknownCoderComplexity; + callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity; + } + else + { + callback.BenchProps.EncComplex = 1 << 10; + callback.BenchProps.DecComplexUnc = 1 << 6; + } + callback.BenchProps.DecComplexCompr = 0; + } + callback.NeedPrint = false; + + if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA")) + { + const NCOM::CPropVariant propVariant = (UInt32)pow; + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) + } + + const HRESULT res = MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + false, // oldLzmaBenchMode + numThreadsVector[ti], + &affinityMode, + #endif + method2, + dataSize, (const Byte *)fileDataBuffer, + bench_DictBits, + printCallback, + &callback, + &callback.BenchProps); + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + for (unsigned i = 0; i < 2; i++) + { + const CBenchInfo &bi = callback.BenchInfo_Results[i]; + const UInt64 usage = bi.GetUsage(); + const UInt64 speed = bi.GetUnpackSizeSpeed(); + usageTotals.Values[ti * 2 + i] += usage; + speedTotals.Values[ti * 2 + i] += speed; + Bench_BW_Print_Usage_Speed(f, usage, speed); + } + } } f.NewLine(); numSteps++; - if (dataSize >= dict64) - break; } + if (dataSize >= dict64) + break; } + if (numSteps != 0) { - f.NewLine(); f.Print("Avg:"); for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++) { - PrintUsage(f, usageTotals.Values[ti] / numSteps, kFieldSize_Usage); - PrintNumber(f, speedTotals.Values[ti] / numSteps / 1000000, kFieldSize_CrcSpeed); + if (ti != 0) + Print_Delimiter(f); + for (unsigned i = 0; i < numColumns; i++) + Bench_BW_Print_Usage_Speed(f, + usageTotals.Values[ti * numColumns + i] / numSteps, + speedTotals.Values[ti * numColumns + i] / numSteps); } f.NewLine(); } + return S_OK; } bool use2Columns = false; - bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*")); + bool totalBenchMode = false; bool onlyHashBench = false; - if (method.MethodName.IsEqualTo_Ascii_NoCase("hash")) + if (methodName.IsEqualTo_Ascii_NoCase("hash")) { onlyHashBench = true; + methodName = "*"; totalBenchMode = true; } + else if (methodName.Find('*') >= 0) + totalBenchMode = true; // ---------- Threads loop ---------- for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++) @@ -4207,10 +4653,6 @@ } } - CBenchCallbackToPrint callback; - callback.Init(); - callback._file = printCallback; - IBenchPrintCallback &f = *printCallback; if (threadsPassIndex > 0) @@ -4221,6 +4663,8 @@ if (!dictIsDefined && !onlyHashBench) { + // we use dicSizeLog and dicSizeLog_Main for data size. + // also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize. const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); unsigned dicSizeLog = dicSizeLog_Main; @@ -4230,7 +4674,7 @@ if (ramSize_Defined) for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(numThreads, level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) + if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) break; dict = (UInt64)1 << dicSizeLog; @@ -4246,7 +4690,7 @@ Print_Usage_and_Threads(f, onlyHashBench ? GetBenchMemoryUsage_Hash(numThreads, dict) : - GetBenchMemoryUsage(numThreads, level, dict, totalBenchMode), + GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode), numThreads); f.NewLine(); @@ -4355,12 +4799,12 @@ fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); fb.specifiedFreq = specifiedFreq; - HRESULT res = fb.FreqBench(printCallback - #ifndef _7ZIP_ST + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST , &affinityMode #endif ); - RINOK(res); + RINOK(res) cpuFreq = fb.CpuFreqRes; callback.NewLine(); @@ -4390,9 +4834,9 @@ dataSize = (size_t)dict; } - HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS - complexInCommands, - #ifndef _7ZIP_ST + const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + #ifndef Z7_ST numThreads, &affinityMode, #endif @@ -4400,7 +4844,7 @@ dataSize, (const Byte *)fileDataBuffer, printCallback, &callback); - RINOK(res); + RINOK(res) } { @@ -4418,14 +4862,16 @@ dataSize = (size_t)dict; } - HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads, + const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + numThreads, dataSize, (const Byte *)fileDataBuffer, printCallback, &callback, - #ifndef _7ZIP_ST + #ifndef Z7_ST &affinityMode, #endif &callback.EncodeRes, true, cpuFreq); - RINOK(res); + RINOK(res) } callback.NewLine(); @@ -4439,12 +4885,12 @@ fb.showFreq = (specifiedFreq != 0); fb.specifiedFreq = specifiedFreq; - HRESULT res = fb.FreqBench(printCallback - #ifndef _7ZIP_ST + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST , &affinityMode #endif ); - RINOK(res); + RINOK(res) callback.NewLine(); } } @@ -4455,12 +4901,12 @@ if (!methodName.IsEqualTo_Ascii_NoCase("LZMA")) { unsigned i; - for (i = 0; i < ARRAY_SIZE(g_Bench); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) { const CBenchMethod &h = g_Bench[i]; AString benchMethod (h.Name); AString benchProps; - int propPos = benchMethod.Find(':'); + const int propPos = benchMethod.Find(':'); if (propPos >= 0) { benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); @@ -4470,19 +4916,21 @@ if (AreSameMethodNames(benchMethod, methodName)) { if (benchProps.IsEmpty() - || (benchProps == "x5" && method.PropsString.IsEmpty()) + || (benchProps.IsEqualTo("x5") && method.PropsString.IsEmpty()) || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps)) { callback.BenchProps.EncComplex = h.EncComplex; callback.BenchProps.DecComplexCompr = h.DecComplexCompr; - callback.BenchProps.DecComplexUnc = h.DecComplexUnc;; + callback.BenchProps.DecComplexUnc = h.DecComplexUnc; needSetComplexity = false; break; } } } - if (i == ARRAY_SIZE(g_Bench)) + /* + if (i == Z7_ARRAY_SIZE(g_Bench)) return E_NOTIMPL; + */ } if (needSetComplexity) callback.BenchProps.SetLzmaCompexity(); @@ -4499,12 +4947,7 @@ pow--; for (; GetDictSizeFromLog(pow) <= dict; pow++) { - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos] = 0; - PrintLeft(f, s, kFieldSize_SmallName); + Print_Pow(f, pow); callback.DictSize = (UInt64)1 << pow; COneMethodInfo method2 = method; @@ -4515,7 +4958,7 @@ // method2 can have two different dictionary size properties. // And last property is main. NCOM::CPropVariant propVariant = (UInt32)pow; - RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)); + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) } size_t uncompressedDataSize; @@ -4532,10 +4975,10 @@ uncompressedDataSize += kAdditionalSize; } - HRESULT res = MethodBench( + const HRESULT res = MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, - #ifndef _7ZIP_ST + #ifndef Z7_ST true, numThreads, &affinityMode, #endif @@ -4543,7 +4986,7 @@ uncompressedDataSize, (const Byte *)fileDataBuffer, kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps); f.NewLine(); - RINOK(res); + RINOK(res) if (!multiDict) break; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Bench.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Bench.h 2021-07-15 08:35:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Bench.h 2023-04-06 08:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Bench.h -#ifndef __7ZIP_BENCH_H -#define __7ZIP_BENCH_H +#ifndef ZIP7_INC_7ZIP_BENCH_H +#define ZIP7_INC_7ZIP_BENCH_H #include "../../../Windows/System.h" @@ -71,32 +71,31 @@ }; +const unsigned kBenchMinDicLogSize = 18; + +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench); -struct IBenchCallback +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IBenchCallback) { // virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; }; - - -const unsigned kBenchMinDicLogSize = 18; - -UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench); - -struct IBenchPrintCallback +DECLARE_INTERFACE(IBenchPrintCallback) { virtual void Print(const char *s) = 0; virtual void NewLine() = 0; virtual HRESULT CheckBreak() = 0; }; -struct IBenchFreqCallback +DECLARE_INTERFACE(IBenchFreqCallback) { virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) = 0; virtual HRESULT FreqsFinished(unsigned numThreads) = 0; }; +Z7_PURE_INTERFACES_END HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS @@ -113,7 +112,7 @@ void GetCpuName(AString &s); void AddCpuFeatures(AString &s); -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES void Add_LargePages_String(AString &s); #else // #define Add_LargePages_String diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall.cpp 2022-05-26 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -51,7 +51,7 @@ { UString s2 ('\"'); s2 += s; - s2 += '\"'; + s2.Add_Char('\"'); return s2; } @@ -83,7 +83,7 @@ const WRes wres = process.Create(imageName, params, NULL); // curDir); if (wres != 0) { - HRESULT hres = HRESULT_FROM_WIN32(wres); + const HRESULT hres = HRESULT_FROM_WIN32(wres); ErrorMessageHRESULT(hres, imageName); return hres; } @@ -92,7 +92,7 @@ else if (event != NULL) { HANDLE handles[] = { process, *event }; - ::WaitForMultipleObjects(ARRAY_SIZE(handles), handles, FALSE, INFINITE); + ::WaitForMultipleObjects(Z7_ARRAY_SIZE(handles), handles, FALSE, INFINITE); } return S_OK; } @@ -155,14 +155,14 @@ event.Close(); } - params += '#'; + params.Add_Char('#'); params += mappingName; - params += ':'; + params.Add_Colon(); char temp[32]; ConvertUInt64ToString(totalSize, temp); params += temp; - params += ':'; + params.Add_Colon(); params += eventName; LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize); @@ -175,7 +175,7 @@ FOR_VECTOR (i, names) { const UString &s = names[i]; - unsigned len = s.Len() + 1; + const unsigned len = s.Len() + 1; wmemcpy(cur, (const wchar_t *)s, len); cur += len; } @@ -197,7 +197,7 @@ CFileMapping fileMapping; NSynchronization::CManualResetEvent event; params += kIncludeSwitch; - RINOK(CreateMap(names, fileMapping, event, params)); + RINOK(CreateMap(names, fileMapping, event, params)) if (!arcType.IsEmpty()) { @@ -336,7 +336,7 @@ if (totalMode) params += " -mm=*"; AddLagePagesSwitch(params); - HRESULT result = Call7zGui(params, false, NULL); + const HRESULT result = Call7zGui(params, false, NULL); if (result != S_OK) ErrorMessageHRESULT(result); MY_TRY_FINISH_VOID diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall.h 2022-05-26 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // CompressCall.h -#ifndef __COMPRESS_CALL_H -#define __COMPRESS_CALL_H +#ifndef ZIP7_INC_COMPRESS_CALL_H +#define ZIP7_INC_COMPRESS_CALL_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall2.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall2.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/CompressCall2.cpp 2022-06-06 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/CompressCall2.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -2,6 +2,8 @@ #include "StdAfx.h" +#ifndef Z7_EXTERNAL_CODECS + #include "../../../Common/MyException.h" #include "../../UI/Common/EnumDirItems.h" @@ -33,7 +35,7 @@ throw CSystemException(res); } -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #define CREATE_CODECS \ CCodecs *codecs = new CCodecs; \ @@ -42,10 +44,10 @@ Codecs_AddHashArcHandler(codecs); #define LOAD_EXTERNAL_CODECS \ - CExternalCodecs __externalCodecs; \ - __externalCodecs.GetCodecs = codecs; \ - __externalCodecs.GetHashers = codecs; \ - ThrowException_if_Error(__externalCodecs.Load()); + CExternalCodecs _externalCodecs; \ + _externalCodecs.GetCodecs = codecs; \ + _externalCodecs.GetHashers = codecs; \ + ThrowException_if_Error(_externalCodecs.Load()); #else @@ -66,7 +68,7 @@ { UString s2 ('\"'); s2 += s; - s2 += '\"'; + s2.Add_Char('\"'); return s2; } @@ -321,3 +323,5 @@ MY_TRY_FINISH } + +#endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/DefaultName.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DefaultName.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/DefaultName.h 2013-01-17 09:52:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DefaultName.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // DefaultName.h -#ifndef __DEFAULT_NAME_H -#define __DEFAULT_NAME_H +#ifndef ZIP7_INC_DEFAULT_NAME_H +#define ZIP7_INC_DEFAULT_NAME_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/DirItem.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DirItem.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/DirItem.h 2022-05-13 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/DirItem.h 2024-02-10 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // DirItem.h -#ifndef __DIR_ITEM_H -#define __DIR_ITEM_H +#ifndef ZIP7_INC_DIR_ITEM_H +#define ZIP7_INC_DIR_ITEM_H #ifdef _WIN32 #include "../../../Common/MyLinux.h" @@ -72,15 +72,15 @@ }; +Z7_PURE_INTERFACES_BEGIN -#define INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT ScanError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x; \ +#define Z7_IFACEN_IDirItemsCallback(x) \ + virtual HRESULT ScanError(const FString &path, DWORD systemError) x \ + virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x \ -struct IDirItemsCallback -{ - INTERFACE_IDirItemsCallback(=0) -}; +Z7_IFACE_DECL_PURE(IDirItemsCallback) + +Z7_PURE_INTERFACES_END struct CArcTime @@ -260,6 +260,8 @@ int OwnerGroupIndex; #endif + // bool Attrib_IsDefined; + CDirItem(): PhyParent(-1) , LogParent(-1) @@ -269,6 +271,7 @@ , OwnerNameIndex(-1) , OwnerGroupIndex(-1) #endif + // , Attrib_IsDefined(true) { } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.cpp 2022-06-27 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.cpp 2025-06-20 10:00:00.000000000 +0000 @@ -18,7 +18,7 @@ #include "../../../Windows/FileName.h" #if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif @@ -183,7 +183,7 @@ , ExcludeDirItems(false) , ExcludeFileItems(false) , ShareForWrite(false) - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE , ReadSecure(false) #endif #ifndef _WIN32 @@ -191,13 +191,13 @@ #endif , Callback(NULL) { - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } -#ifdef _USE_SECURITY_CODE +#ifdef Z7_USE_SECURITY_CODE HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) { @@ -236,7 +236,7 @@ if (res) { if (secureSize != TempSecureBuf.Size()) - errorCode = ERROR_INVALID_FUNCTION;; + errorCode = ERROR_INVALID_FUNCTION; } else errorCode = GetLastError(); @@ -253,7 +253,7 @@ return AddError(path, errorCode); } -#endif // _USE_SECURITY_CODE +#endif // Z7_USE_SECURITY_CODE HRESULT CDirItems::EnumerateOneDir(const FString &phyPrefix, CObjectVector &files) @@ -277,7 +277,7 @@ files.Add(fi); if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) { - RINOK(ScanProgress(phyPrefix)); + RINOK(ScanProgress(phyPrefix)) } } @@ -287,14 +287,12 @@ CObjectVector entries; - for (unsigned ttt = 0; ; ttt++) + for (;;) { bool found; NFind::CDirEntry de; if (!enumerator.Next(de, found)) - { return AddError(phyPrefix); - } if (!found) break; entries.Add(de); @@ -309,7 +307,7 @@ { const FString path = phyPrefix + de.Name; { - RINOK(AddError(path)); + RINOK(AddError(path)) continue; } } @@ -318,7 +316,7 @@ if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) { - RINOK(ScanProgress(phyPrefix)); + RINOK(ScanProgress(phyPrefix)) } } @@ -332,10 +330,10 @@ HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) { - RINOK(ScanProgress(phyPrefix)); + RINOK(ScanProgress(phyPrefix)) CObjectVector files; - RINOK(EnumerateOneDir(phyPrefix, files)); + RINOK(EnumerateOneDir(phyPrefix, files)) FOR_VECTOR (i, files) { @@ -361,10 +359,10 @@ if (CanIncludeItem(fi.IsDir())) { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (ReadSecure) { - RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)); + RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)) } #endif AddDirFileInfo(phyParent, logParent, secureIndex, fi); @@ -372,14 +370,14 @@ if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) { - RINOK(ScanProgress(phyPrefix)); + RINOK(ScanProgress(phyPrefix)) } if (fi.IsDir()) { const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2)); - RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2)) } } return S_OK; @@ -412,6 +410,11 @@ const int phyParent = phyPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, fs2us(phyPrefix)); const int logParent = logPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, logPrefix); + #ifdef _WIN32 + const bool phyPrefix_isAltStreamPrefix = + NFile::NName::IsAltStreamPrefixWithColon(fs2us(phyPrefix)); + #endif + FOR_VECTOR (i, filePaths) { const FString &filePath = filePaths[i]; @@ -419,7 +422,7 @@ const FString phyPath = phyPrefix + filePath; if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM)) { - RINOK(AddError(phyPath)); + RINOK(AddError(phyPath)) continue; } if (requestedPaths) @@ -437,20 +440,28 @@ if (CanIncludeItem(fi.IsDir())) { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (ReadSecure) { - RINOK(AddSecurityItem(phyPath, secureIndex)); + RINOK(AddSecurityItem(phyPath, secureIndex)) } #endif + #ifdef _WIN32 + if (phyPrefix_isAltStreamPrefix && fi.IsAltStream) + { + const int pos = fi.Name.Find(FChar(':')); + if (pos >= 0) + fi.Name.DeleteFrontal((unsigned)pos + 1); + } + #endif AddDirFileInfo(phyParentCur, logParent, secureIndex, fi); } if (fi.IsDir()) { const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; - unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); - RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2)); + const unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2)) } } @@ -625,10 +636,10 @@ if (dirItems.CanIncludeItem(fi.IsDir())) { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (dirItems.ReadSecure) { - RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)); + RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)) } #endif #if !defined(UNDER_CE) @@ -654,19 +665,19 @@ if (dirItemIndex >= 0) { CDirItem &dirItem = dirItems.Items[(unsigned)dirItemIndex]; - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) if (dirItem.ReparseData.Size() != 0) return S_OK; } #if defined(_WIN32) - if (needAltStreams && dirItems.ScanAltStreams) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) { RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix + fi.Name, // with (fi.Name) newParts, // with (fi.Name) addAllSubStreams, - dirItems)); + dirItems)) } #endif @@ -787,7 +798,7 @@ enterToSubFolders = true; } - RINOK(dirItems.ScanProgress(phyPrefix)); + RINOK(dirItems.ScanProgress(phyPrefix)) // try direct_names case at first if (addParts.IsEmpty() && !enterToSubFolders) @@ -818,7 +829,7 @@ bool needAltStreams = true; #endif - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE bool needSecurity = true; #endif @@ -838,7 +849,7 @@ /* // do we need to ignore security info for "\\" folder ? - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE needSecurity = false; #endif */ @@ -866,7 +877,7 @@ #endif if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) { - RINOK(dirItems.AddError(fullPath)); + RINOK(dirItems.AddError(fullPath)) continue; } @@ -884,7 +895,7 @@ if (isDir ? !item.ForDir : !item.ForFile) { // RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR)); - RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)); + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) continue; } { @@ -898,10 +909,10 @@ if (dirItems.CanIncludeItem(fi.IsDir())) { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (needSecurity && dirItems.ReadSecure) { - RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)); + RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)) } #endif @@ -912,13 +923,13 @@ #if !defined(UNDER_CE) { CDirItem &dirItem = dirItems.Items.Back(); - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) if (dirItem.ReparseData.Size() != 0) continue; } #if defined(_WIN32) - if (needAltStreams && dirItems.ScanAltStreams) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) { UStringVector pathParts; pathParts.Add(fs2us(fi.Name)); @@ -926,7 +937,7 @@ fullPath, // including (name) pathParts, // including (fi.Name) true, /* addAllSubStreams */ - dirItems)); + dirItems)) } #endif // defined(_WIN32) @@ -975,9 +986,9 @@ } RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, - newParts, dirItems, true)); + newParts, dirItems, true)) } - + for (i = 0; i < curNode.SubNodes.Size(); i++) { if (i < needEnterVector.Size()) @@ -987,17 +998,20 @@ FString fullPath = phyPrefix + us2fs(nextNode.Name); NFind::CFileInfo fi; - if (phyPrefix.IsEmpty()) + if (nextNode.Name.IsEmpty()) { - { - if (nextNode.Name.IsEmpty()) - fullPath = CHAR_PATH_SEPARATOR; - #ifdef _WIN32 - else if (NWildcard::IsDriveColonName(nextNode.Name)) - fullPath.Add_PathSepar(); - #endif - } + if (phyPrefix.IsEmpty()) + fullPath = CHAR_PATH_SEPARATOR; } + #ifdef _WIN32 + else if(phyPrefix.IsEmpty() + || (phyPrefix.Len() == NName::kSuperPathPrefixSize + && IsSuperPath(phyPrefix))) + { + if (NWildcard::IsDriveColonName(nextNode.Name)) + fullPath.Add_PathSepar(); + } + #endif // we don't want to call fi.Find() for root folder or virtual folder if ((phyPrefix.IsEmpty() && nextNode.Name.IsEmpty()) @@ -1015,19 +1029,19 @@ { if (!nextNode.AreThereIncludeItems()) continue; - RINOK(dirItems.AddError(fullPath)); + RINOK(dirItems.AddError(fullPath)) continue; } if (!fi.IsDir()) { - RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)); + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) continue; } } RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, - UStringVector(), dirItems, false)); + UStringVector(), dirItems, false)) } return S_OK; @@ -1073,7 +1087,7 @@ fi.Name = driveName; RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addParts, dirItems, enterToSubFolders)); + addParts, dirItems, enterToSubFolders)) } return S_OK; } @@ -1088,7 +1102,7 @@ // for (int y = 0; y < 1; y++) { // files.Clear(); - RINOK(dirItems.EnumerateOneDir(phyPrefix, files)); + RINOK(dirItems.EnumerateOneDir(phyPrefix, files)) /* FOR_VECTOR (i, files) { @@ -1134,10 +1148,10 @@ #endif RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addParts, dirItems, enterToSubFolders)); + addParts, dirItems, enterToSubFolders)) if (dirItems.Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) { - RINOK(dirItems.ScanProgress(phyPrefix)); + RINOK(dirItems.ScanProgress(phyPrefix)) } } @@ -1170,16 +1184,16 @@ RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(), dirItems, false // enterToSubFolders - )); + )) } dirItems.ReserveDown(); #if defined(_WIN32) && !defined(UNDER_CE) - RINOK(dirItems.FillFixedReparse()); + RINOK(dirItems.FillFixedReparse()) #endif #ifndef _WIN32 - RINOK(dirItems.FillDeviceSizes()); + RINOK(dirItems.FillDeviceSizes()) #endif return S_OK; @@ -1199,11 +1213,13 @@ // continue; // for debug if (!item.Has_Attrib_ReparsePoint()) continue; - + /* + We want to get properties of target file instead of properies of symbolic link. + Probably this code is unused, because + CFileInfo::Find(with followLink = true) called Fill_From_ByHandleFileInfo() already. + */ // if (item.IsDir()) continue; - const FString phyPath = GetPhyPath(i); - NFind::CFileInfo fi; if (fi.Fill_From_ByHandleFileInfo(phyPath)) // item.IsDir() { @@ -1214,38 +1230,13 @@ item.Attrib = fi.Attrib; continue; } - - /* - // we request properties of target file instead of properies of symbolic link - // here we also can manually parse unsupported links (like WSL links) - NIO::CInFile inFile; - if (inFile.Open(phyPath)) - { - BY_HANDLE_FILE_INFORMATION info; - if (inFile.GetFileInformation(&info)) - { - // Stat.FilesSize doesn't contain item.Size already - // Stat.FilesSize -= item.Size; - item.Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; - Stat.FilesSize += item.Size; - item.CTime = info.ftCreationTime; - item.ATime = info.ftLastAccessTime; - item.MTime = info.ftLastWriteTime; - item.Attrib = info.dwFileAttributes; - continue; - } - } - */ - - RINOK(AddError(phyPath)); + RINOK(AddError(phyPath)) continue; } - // (SymLinks == true) here - + // (SymLinks == true) if (item.ReparseData.Size() == 0) continue; - // if (item.Size == 0) { // 20.03: we use Reparse Data instead of real data @@ -1263,7 +1254,7 @@ /* imagex/WIM reduces absolute paths in links (raparse data), if we archive non root folder. We do same thing here */ - bool isWSL = false; + // bool isWSL = false; if (attr.IsSymLink_WSL()) { // isWSL = true; @@ -1300,21 +1291,27 @@ continue; if (rootPrefixSize == prefix.Len()) continue; // simple case: paths are from root - if (link.Len() <= prefix.Len()) continue; - if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0) continue; UString newLink = prefix.Left(rootPrefixSize); newLink += link.Ptr(prefix.Len()); - CByteBuffer data; - bool isSymLink = !attr.IsMountPoint(); - if (!FillLinkData(data, newLink, isSymLink, isWSL)) + CByteBuffer &data = item.ReparseData2; +/* + if (isWSL) + { + Convert_WinPath_to_WslLinuxPath(newLink, true); // is absolute : change it + FillLinkData_WslLink(data, newLink); + } + else +*/ + FillLinkData_WinLink(data, newLink, !attr.IsMountPoint()); + if (data.Size() == 0) continue; - item.ReparseData2 = data; + // item.ReparseData2 = data; } return S_OK; } @@ -1485,7 +1482,7 @@ { HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); st = dirItems.Stat; - RINOK(res); + RINOK(res) } FOR_VECTOR (i, dirItems.Items) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.h 2020-09-16 17:17:51.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/EnumDirItems.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // EnumDirItems.h -#ifndef __ENUM_DIR_ITEMS_H -#define __ENUM_DIR_ITEMS_H +#ifndef ZIP7_INC_ENUM_DIR_ITEMS_H +#define ZIP7_INC_ENUM_DIR_ITEMS_H #include "../../../Common/Wildcard.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExitCode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExitCode.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExitCode.h 2008-08-06 07:50:21.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExitCode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExitCode.h -#ifndef __EXIT_CODE_H -#define __EXIT_CODE_H +#ifndef ZIP7_INC_EXIT_CODE_H +#define ZIP7_INC_EXIT_CODE_H namespace NExitCode { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Extract.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Extract.cpp 2022-06-09 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../../../../C/Sort.h" - #include "../../../Common/StringConvert.h" #include "../../../Windows/FileDir.h" @@ -43,6 +41,7 @@ const CExtractOptions &options, bool calcCrc, IExtractCallbackUI *callback, + IFolderArchiveExtractCallback *callbackFAE, CArchiveExtractCallback *ecs, UString &errorMessage, UInt64 &stdInProcessed) @@ -94,7 +93,7 @@ if (!options.StdInMode) { UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) CReadArcItem item; @@ -105,7 +104,7 @@ || options.ExcludeDirItems || options.ExcludeFileItems) { - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) if (item.IsDir ? options.ExcludeDirItems : options.ExcludeFileItems) continue; } @@ -115,7 +114,7 @@ item.IsAltStream = false; if (!options.NtOptions.AltStreams.Val && arc.Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)); + RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)) } #endif } @@ -194,12 +193,14 @@ options.NtOptions, options.StdInMode ? &wildcardCensor : NULL, &arc, - callback, + callbackFAE, options.StdOutMode, options.TestMode, outDir, removePathParts, false, packSize); + ecs->Is_elimPrefix_Mode = elimIsPossible; + #ifdef SUPPORT_LINKS @@ -207,14 +208,14 @@ !options.TestMode && options.NtOptions.HardLinks.Val) { - RINOK(ecs->PrepareHardLinks(&realIndices)); + RINOK(ecs->PrepareHardLinks(&realIndices)) } #endif HRESULT result; - Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; + const Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; CArchiveExtractCallback_Closer ecsCloser(ecs); @@ -226,9 +227,15 @@ ConvertPropVariantToUInt64(prop, stdInProcessed); } else - result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs); + { + // v23.02: we reset completed value that could be set by Open() operation + IArchiveExtractCallback *aec = ecs; + const UInt64 val = 0; + RINOK(aec->SetCompleted(&val)) + result = archive->Extract(realIndices.ConstData(), realIndices.Size(), testMode, aec); + } - HRESULT res2 = ecsCloser.Close(); + const HRESULT res2 = ecsCloser.Close(); if (result == S_OK) result = res2; @@ -270,7 +277,8 @@ const CExtractOptions &options, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback, - #ifndef _SFX + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX IHashCalc *hash, #endif UString &errorMessage, @@ -323,13 +331,13 @@ options.ZoneMode, false // keepEmptyDirParts ); - #ifndef _SFX + #ifndef Z7_SFX ecs->SetHashMethods(hash); #endif if (multi) { - RINOK(extractCallback->SetTotal(totalPackSize)); + RINOK(faeCallback->SetTotal(totalPackSize)) } UInt64 totalPackProcessed = 0; @@ -347,11 +355,10 @@ if (options.StdInMode) { // do we need ctime and mtime? - fi.ClearBase(); - fi.Size = 0; // (UInt64)(Int64)-1; - fi.SetAsFile(); - // NTime::GetCurUtc_FiTime(fi.MTime); - // fi.CTime = fi.ATime = fi.MTime; + // fi.ClearBase(); + // fi.Size = 0; // (UInt64)(Int64)-1; + if (!fi.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); } else { @@ -364,17 +371,17 @@ } /* - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback->Open_Clear_PasswordWasAsked_Flag(); #endif */ - RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)); + RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)) CArchiveLink arcLink; CObjectVector types2 = types; /* - #ifndef _SFX + #ifndef Z7_SFX if (types.IsEmpty()) { int pos = arcPath.ReverseFind(L'.'); @@ -382,7 +389,7 @@ { UString s = arcPath.Ptr(pos + 1); int index = codecs->FindFormatForExtension(s); - if (index >= 0 && s == L"001") + if (index >= 0 && s.IsEqualTo("001")) { s = arcPath.Left(pos); pos = s.ReverseFind(L'.'); @@ -402,7 +409,7 @@ */ COpenOptions op; - #ifndef _SFX + #ifndef Z7_SFX op.props = &options.Properties; #endif op.codecs = codecs; @@ -418,7 +425,7 @@ return result; // arcLink.Set_ErrorsText(); - RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)); + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)) if (result != S_OK) { @@ -428,7 +435,7 @@ continue; } - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) if (options.ZoneMode != NExtract::NZoneIdMode::kNone && !options.StdInMode) { @@ -446,7 +453,13 @@ /* real Extracting to files is possible. But user can think that hash archive contains real files. So we block extracting here. */ - return E_NOTIMPL; + // v23.00 : we don't break process. + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, E_NOTIMPL)) + thereAreNotOpenArcs = true; + if (!options.StdInMode) + totalPackProcessed += fi.Size; + continue; + // return E_NOTIMPL; // before v23 } FString dirPrefix = us2fs(options.HashDir); if (dirPrefix.IsEmpty()) @@ -490,7 +503,7 @@ if (newPackSize < 0) newPackSize = 0; totalPackSize = (UInt64)newPackSize; - RINOK(extractCallback->SetTotal(totalPackSize)); + RINOK(faeCallback->SetTotal(totalPackSize)) } } } @@ -498,13 +511,13 @@ /* // Now openCallback and extractCallback use same object. So we don't need to send password. - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool passwordIsDefined; UString password; - RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)); + RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)) if (passwordIsDefined) { - RINOK(extractCallback->SetPassword(password)); + RINOK(extractCallback->SetPassword(password)) } #endif */ @@ -520,7 +533,7 @@ UInt64 packProcessed; const bool calcCrc = - #ifndef _SFX + #ifndef Z7_SFX (hash != NULL); #else false; @@ -533,7 +546,8 @@ wildcardCensor, options, calcCrc, - extractCallback, ecs, errorMessage, packProcessed)); + extractCallback, faeCallback, ecs, + errorMessage, packProcessed)) if (!options.StdInMode) packProcessed = fi.Size + arcLink.VolumesSize; @@ -546,8 +560,8 @@ if (multi || thereAreNotOpenArcs) { - RINOK(extractCallback->SetTotal(totalPackSize)); - RINOK(extractCallback->SetCompleted(&totalPackProcessed)); + RINOK(faeCallback->SetTotal(totalPackSize)) + RINOK(faeCallback->SetCompleted(&totalPackProcessed)) } st.NumFolders = ecs->NumFolders; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Extract.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Extract.h 2022-06-03 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Extract.h 2024-03-07 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Extract.h -#ifndef __EXTRACT_H -#define __EXTRACT_H +#ifndef ZIP7_INC_EXTRACT_H +#define ZIP7_INC_EXTRACT_H #include "../../../Windows/FileFind.h" @@ -26,9 +26,10 @@ NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; NExtract::NZoneIdMode::EEnum ZoneMode; + + CExtractNtOptions NtOptions; FString OutputDir; - CExtractNtOptions NtOptions; UString HashDir; CExtractOptionsBase(): @@ -52,12 +53,12 @@ // bool ShowDialog; // bool PasswordEnabled; // UString Password; - #ifndef _SFX + #ifndef Z7_SFX CObjectVector Properties; #endif /* - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CCodecs *Codecs; #endif */ @@ -96,7 +97,8 @@ const CExtractOptions &options, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback, - #ifndef _SFX + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX IHashCalc *hash, #endif UString &errorMessage, diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractMode.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractMode.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractMode.h 2022-05-26 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractMode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractMode.h -#ifndef __EXTRACT_MODE_H -#define __EXTRACT_MODE_H +#ifndef ZIP7_INC_EXTRACT_MODE_H +#define ZIP7_INC_EXTRACT_MODE_H namespace NExtract { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.cpp 2022-01-09 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -124,7 +124,7 @@ static bool IsSupportedName(const UString &name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ReservedNames); i++) { const char *reservedName = g_ReservedNames[i]; unsigned len = MyStringLen(reservedName); @@ -208,7 +208,7 @@ if (parts.Size() > 1 && parts[1].IsEmpty()) { i = 2; - if (parts.Size() > 2 && parts[2] == L"?") + if (parts.Size() > 2 && parts[2].IsEqualTo("?")) { i = 3; if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.h 2019-03-01 17:24:26.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ExtractingFilePath.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractingFilePath.h -#ifndef __EXTRACTING_FILE_PATH_H -#define __EXTRACTING_FILE_PATH_H +#ifndef ZIP7_INC_EXTRACTING_FILE_PATH_H +#define ZIP7_INC_EXTRACTING_FILE_PATH_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/HashCalc.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/HashCalc.cpp 2022-04-04 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -22,7 +22,7 @@ using namespace NWindows; -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS extern const CExternalCodecs *g_ExternalCodecs_Ptr; #endif @@ -57,12 +57,12 @@ for (i = 0; i < names.Size(); i++) { COneMethodInfo m; - RINOK(m.ParseMethodFromString(names[i])); + RINOK(m.ParseMethodFromString(names[i])) if (m.MethodName.IsEmpty()) m.MethodName = k_DefaultHashMethod; - if (m.MethodName == "*") + if (m.MethodName.IsEqualTo("*")) { CRecordVector tempMethods; GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods); @@ -92,7 +92,7 @@ { CMyComPtr hasher; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)); + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)) if (!hasher) throw "Can't create hasher"; const COneMethodInfo &m = methods[i]; @@ -100,7 +100,7 @@ CMyComPtr scp; hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) - RINOK(m.SetCoderProps(scp, NULL)); + RINOK(m.SetCoderProps(scp, NULL)) } const UInt32 digestSize = hasher->GetDigestSize(); if (digestSize > k_HashCalc_DigestSize_Max) @@ -249,12 +249,12 @@ char c = src[i++]; if (c == '\n') { - dest += '\\'; + dest.Add_Char('\\'); c = 'n'; } else if (c == '\\') - dest += '\\'; - dest += c; + dest.Add_Char('\\'); + dest.Add_Char(c); } } @@ -287,7 +287,7 @@ isOK = false; } } - dest += c; + dest.Add_Char(c); } return isOK; } @@ -330,14 +330,14 @@ if (numSpaces > 0) SetSpacesAndNul(s + pos, (unsigned)numSpaces); if (i != 0) - _s += ' '; + _s.Add_Space(); _s += s; } /* if (showSize) { - _s += ' '; + _s.Add_Space(); static const unsigned kSizeField_Len = 13; // same as in HashCon.cpp char s[kSizeField_Len + 32]; char *p = s; @@ -403,7 +403,7 @@ } if (isDir && !esc.IsEmpty() && esc.Back() != '/') - esc += '/'; + esc.Add_Slash(); if (tagMode) { @@ -431,6 +431,19 @@ } +static void Convert_TagName_to_MethodName(AString &method) +{ + // we need to convert at least SHA512/256 to SHA512-256, and SHA512/224 to SHA512-224 + // but we convert any '/' to '-'. + method.Replace('/', '-'); +} + +static void Convert_MethodName_to_TagName(AString &method) +{ + if (method.IsPrefixedBy_Ascii_NoCase("SHA512-2")) + method.ReplaceOneCharAtPos(6, '/'); +} + static void WriteLine(CDynLimBuf &hashFileString, const CHashOptionsLocal &options, @@ -440,8 +453,10 @@ { AString methodName; if (!hb.Hashers.IsEmpty()) + { methodName = hb.Hashers[0].Name; - + Convert_MethodName_to_TagName(methodName); + } AString hashesString; AddHashResultLine(hashesString, hb.Hashers); WriteLine(hashFileString, options, path, isDir, methodName, hashesString); @@ -461,13 +476,13 @@ if (options.StdInMode) { CDirItem di; - di.Size = (UInt64)(Int64)-1; - di.SetAsFile(); + if (!di.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); dirItems.Items.Add(di); } else { - RINOK(callback->StartScanning()); + RINOK(callback->StartScanning()) dirItems.SymLinks = options.SymLinks.Val; dirItems.ScanAltStreams = options.AltStreamsMode; @@ -487,12 +502,12 @@ errorInfo = "Scanning error"; return res; } - RINOK(callback->FinishScanning(dirItems.Stat)); + RINOK(callback->FinishScanning(dirItems.Stat)) } unsigned i; CHashBundle hb; - RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)); + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)) // hb.Init(); hb.NumErrors = dirItems.Stat.NumErrors; @@ -500,12 +515,12 @@ UInt64 totalSize = 0; if (options.StdInMode) { - RINOK(callback->SetNumFiles(1)); + RINOK(callback->SetNumFiles(1)) } else { totalSize = dirItems.Stat.GetTotalBytes(); - RINOK(callback->SetTotal(totalSize)); + RINOK(callback->SetTotal(totalSize)) } const UInt32 kBufSize = 1 << 15; @@ -515,7 +530,7 @@ UInt64 completeValue = 0; - RINOK(callback->BeforeFirstFile(hb)); + RINOK(callback->BeforeFirstFile(hb)) /* CDynLimBuf hashFileString((size_t)1 << 31); @@ -531,7 +546,19 @@ if (options.StdInMode) { +#if 1 inStream = new CStdInFileStream; +#else + if (!CreateStdInStream(inStream)) + { + const DWORD lastError = ::GetLastError(); + const HRESULT res = callback->OpenFileError(FString("stdin"), lastError); + hb.NumErrors++; + if (res != S_FALSE && res != S_OK) + return res; + continue; + } +#endif } else { @@ -561,7 +588,7 @@ const FString phyPath = dirItems.GetPhyPath(i); if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite)) { - HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); + const HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); hb.NumErrors++; if (res != S_FALSE) return res; @@ -575,7 +602,7 @@ if (curSize > di.Size) { totalSize += curSize - di.Size; - RINOK(callback->SetTotal(totalSize)); + RINOK(callback->SetTotal(totalSize)) // printf("\ntotal = %d MiB\n", (unsigned)(totalSize >> 20)); } } @@ -585,7 +612,7 @@ } } - RINOK(callback->GetStream(path, isDir)); + RINOK(callback->GetStream(path, isDir)) UInt64 fileSize = 0; hb.InitForNewFile(); @@ -597,10 +624,10 @@ if ((step & 0xFF) == 0) { // printf("\ncompl = %d\n", (unsigned)(completeValue >> 20)); - RINOK(callback->SetCompleted(&completeValue)); + RINOK(callback->SetCompleted(&completeValue)) } UInt32 size; - RINOK(inStream->Read(buf, kBufSize, &size)); + RINOK(inStream->Read(buf, kBufSize, &size)) if (size == 0) break; hb.Update(buf, size); @@ -626,8 +653,8 @@ } */ - RINOK(callback->SetOperationResult(fileSize, hb, !isDir)); - RINOK(callback->SetCompleted(&completeValue)); + RINOK(callback->SetOperationResult(fileSize, hb, !isDir)) + RINOK(callback->SetCompleted(&completeValue)) } /* @@ -645,51 +672,40 @@ } -static inline char GetHex_Upper(unsigned v) -{ - return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); -} - -static inline char GetHex_Lower(unsigned v) +void HashHexToString(char *dest, const Byte *data, size_t size) { - return (char)((v < 10) ? ('0' + v) : ('a' + (v - 10))); -} - -void HashHexToString(char *dest, const Byte *data, UInt32 size) -{ - dest[size * 2] = 0; - if (!data) { - for (UInt32 i = 0; i < size; i++) + for (size_t i = 0; i < size; i++) { dest[0] = ' '; dest[1] = ' '; dest += 2; } + *dest = 0; return; } - if (size <= 8) + if (size > 8) + ConvertDataToHex_Lower(dest, data, size); + else if (size == 0) { - dest += size * 2; - for (UInt32 i = 0; i < size; i++) - { - const unsigned b = data[i]; - dest -= 2; - dest[0] = GetHex_Upper((b >> 4) & 0xF); - dest[1] = GetHex_Upper(b & 0xF); - } + *dest = 0; + return; } else { - for (UInt32 i = 0; i < size; i++) + const char *dest_start = dest; + dest += size * 2; + *dest = 0; + do { - const unsigned b = data[i]; - dest[0] = GetHex_Lower((b >> 4) & 0xF); - dest[1] = GetHex_Lower(b & 0xF); - dest += 2; + const size_t b = *data++; + dest -= 2; + dest[0] = GET_HEX_CHAR_UPPER(b >> 4); + dest[1] = GET_HEX_CHAR_UPPER(b & 15); } + while (dest != dest_start); } } @@ -720,31 +736,6 @@ namespace NHash { -static size_t ParseHexString(const char *s, Byte *dest) throw() -{ - size_t num; - for (num = 0;; num++, s += 2) - { - unsigned c = (Byte)s[0]; - unsigned v0; - if (c >= '0' && c <= '9') v0 = (c - '0'); - else if (c >= 'A' && c <= 'F') v0 = 10 + (c - 'A'); - else if (c >= 'a' && c <= 'f') v0 = 10 + (c - 'a'); - else - return num; - c = (Byte)s[1]; - unsigned v1; - if (c >= '0' && c <= '9') v1 = (c - '0'); - else if (c >= 'A' && c <= 'F') v1 = 10 + (c - 'A'); - else if (c >= 'a' && c <= 'f') v1 = 10 + (c - 'a'); - else - return num; - if (dest) - dest[num] = (Byte)(v1 | (v0 << 4)); - } -} - - #define IsWhite(c) ((c) == ' ' || (c) == '\t') bool CHashPair::IsDir() const @@ -753,7 +744,7 @@ return false; // here we expect that Dir items contain only zeros or no Hash for (size_t i = 0; i < Hash.Size(); i++) - if (Hash[i] != 0) + if (Hash.ConstData()[i] != 0) return false; return true; } @@ -776,7 +767,7 @@ Name = end; Hash.Alloc(4); - SetBe32(Hash, crc); + SetBe32a(Hash, crc) Size_from_Arc = size; Size_from_Arc_Defined = true; @@ -797,48 +788,87 @@ { "sha256" , "sha224" -// , "sha512/224" -// , "sha512/256" - , "sha512" + , "sha512-224" + , "sha512-256" , "sha384" + , "sha512" + , "sha3-224" + , "sha3-256" + , "sha3-384" + , "sha3-512" +// , "shake128" +// , "shake256" , "sha1" + , "sha2" + , "sha3" + , "sha" , "md5" + , "blake2s" , "blake2b" - , "crc64" + , "blake2sp" + , "xxh64" , "crc32" + , "crc64" , "cksum" }; -static UString GetMethod_from_FileName(const UString &name) + +// returns true, if (method) is known hash method or hash method group name. +static bool GetMethod_from_FileName(const UString &name, AString &method) { + method.Empty(); AString s; ConvertUnicodeToUTF8(name, s); const int dotPos = s.ReverseFind_Dot(); - const char *src = s.Ptr(); - bool isExtension = false; if (dotPos >= 0) { - isExtension = true; - src = s.Ptr(dotPos + 1); + method = s.Ptr(dotPos + 1); + if (method.IsEqualTo_Ascii_NoCase("txt") || + method.IsEqualTo_Ascii_NoCase("asc")) + { + method.Empty(); + const int dotPos2 = s.Find('.'); + if (dotPos2 >= 0) + s.DeleteFrom(dotPos2); + } + } + if (method.IsEmpty()) + { + // we support file names with "sum" and "sums" postfixes: "sha256sum", "sha256sums" + unsigned size; + if (s.Len() > 4 && StringsAreEqualNoCase_Ascii(s.RightPtr(4), "sums")) + size = 4; + else if (s.Len() > 3 && StringsAreEqualNoCase_Ascii(s.RightPtr(3), "sum")) + size = 3; + else + return false; + method = s; + method.DeleteFrom(s.Len() - size); } - const char *m = ""; + unsigned i; - for (i = 0; i < ARRAY_SIZE(k_CsumMethodNames); i++) + for (i = 0; i < Z7_ARRAY_SIZE(k_CsumMethodNames); i++) { - m = k_CsumMethodNames[i]; - if (isExtension) + const char *m = k_CsumMethodNames[i]; + if (method.IsEqualTo_Ascii_NoCase(m)) { - if (StringsAreEqual_Ascii(src, m)) - break; + // method = m; // we can get lowcase + return true; } - else if (IsString1PrefixedByString2_NoCase_Ascii(src, m)) - if (StringsAreEqual_Ascii(src + strlen(m), "sums")) - break; } - UString res; - if (i != ARRAY_SIZE(k_CsumMethodNames)) - res = m; - return res; + +/* + for (i = 0; i < Z7_ARRAY_SIZE(k_CsumMethodNames); i++) + { + const char *m = k_CsumMethodNames[i]; + if (method.IsPrefixedBy_Ascii_NoCase(m)) + { + method = m; // we get lowcase + return true; + } + } +*/ + return false; } @@ -854,10 +884,11 @@ s++; escape = true; } + Escape = escape; // const char *kMethod = GetMethod_from_FileName(s); // if (kMethod) - if (ParseHexString(s, NULL) < 4) + if ((size_t)(FindNonHexChar(s) - s) < 4) { // BSD-style checksum line { @@ -903,10 +934,10 @@ } { - const size_t num = ParseHexString(s, NULL); - Hash.Alloc(num); - ParseHexString(s, Hash); - const size_t numChars = num * 2; + const size_t numChars = (size_t)(FindNonHexChar(s) - s) & ~(size_t)1; + Hash.Alloc(numChars / 2); + if ((size_t)(ParseHexString(s, Hash) - Hash) != numChars / 2) + throw 101; HashString.SetFrom(s, (unsigned)numChars); s += numChars; } @@ -1033,27 +1064,27 @@ }; -STDMETHODIMP CHandler::GetParent(UInt32 /* index */ , UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */ , UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; return S_OK; } -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { - *numProps = ARRAY_SIZE(kRawProps); + *numProps = Z7_ARRAY_SIZE(kRawProps); return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) { *propID = kRawProps[index]; - *name = 0; + *name = NULL; return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -1062,7 +1093,7 @@ if (propID == kpidChecksum) { const CHashPair &hp = HashPairs[index]; - if (hp.Hash.Size() > 0) + if (hp.Hash.Size() != 0) { *data = hp.Hash; *dataSize = (UInt32)hp.Hash.Size(); @@ -1077,7 +1108,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = HashPairs.Size(); return S_OK; @@ -1089,9 +1120,9 @@ dest += src; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { - NWindows::NCOM::CPropVariant prop; + NCOM::CPropVariant prop; switch (propID) { case kpidPhySize: if (_phySize != 0) prop = _phySize; break; @@ -1115,17 +1146,12 @@ s.Add_UInt32(_hashSize * 8); s += "-bit"; } - if (!_nameExtenstion.IsEmpty()) - { - s.Add_Space_if_NotEmpty(); - s += _nameExtenstion; - } if (_is_PgpMethod) { Add_OptSpace_String(s, "PGP"); if (!_pgpMethod.IsEmpty()) { - s += ":"; + s.Add_Colon(); s += _pgpMethod; } } @@ -1135,6 +1161,18 @@ Add_OptSpace_String(s, "TAG"); if (_are_there_Dirs) Add_OptSpace_String(s, "DIRS"); + if (!_method_from_FileName.IsEmpty()) + { + Add_OptSpace_String(s, "filename_method:"); + s += _method_from_FileName; + if (!_is_KnownMethod_in_FileName) + s += ":UNKNOWN"; + } + if (!_methods.IsEmpty()) + { + Add_OptSpace_String(s, "cmd_method:"); + s += _methods[0]; + } prop = s; break; } @@ -1146,17 +1184,18 @@ prop = true; break; } + default: break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { // COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - CHashPair &hp = HashPairs[index]; + NCOM::CPropVariant prop; + const CHashPair &hp = HashPairs[index]; switch (propID) { case kpidIsDir: @@ -1169,9 +1208,17 @@ UString path; hp.Get_UString_Path(path); - NArchive::NItemName::ReplaceToOsSlashes_Remove_TailSlash(path, - true); // useBackslashReplacement - + bool useBackslashReplacement = true; + if (_supportWindowsBackslash && !hp.Escape && path.Find(L"\\\\") < 0) + { +#if WCHAR_PATH_SEPARATOR == L'/' + path.Replace(L'\\', L'/'); +#else + useBackslashReplacement = false; +#endif + } + NArchive::NItemName::ReplaceToOsSlashes_Remove_TailSlash( + path, useBackslashReplacement); prop = path; break; } @@ -1195,6 +1242,7 @@ prop = hp.Method; break; } + default: break; } prop.Detach(value); return S_OK; @@ -1206,10 +1254,9 @@ { buf.Free(); UInt64 len; - RINOK(stream->Seek(0, STREAM_SEEK_END, &len)); + RINOK(InStream_AtBegin_GetSize(stream, len)) if (len == 0 || len >= ((UInt64)1 << 31)) return S_FALSE; - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); buf.Alloc((size_t)len); UInt64 pos = 0; // return ReadStream_FALSE(stream, buf, (size_t)len); @@ -1218,7 +1265,7 @@ const UInt32 kBlockSize = ((UInt32)1 << 24); const UInt32 curSize = (len < kBlockSize) ? (UInt32)len : kBlockSize; UInt32 processedSizeLoc; - RINOK(stream->Read((Byte *)buf + pos, curSize, &processedSizeLoc)); + RINOK(stream->Read((Byte *)buf + pos, curSize, &processedSizeLoc)) if (processedSizeLoc == 0) return E_FAIL; len -= processedSizeLoc; @@ -1228,13 +1275,22 @@ if (openCallback) { const UInt64 files = 0; - RINOK(openCallback->SetCompleted(&files, &pos)); + RINOK(openCallback->SetCompleted(&files, &pos)) } } } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback) +static bool isThere_Zero_Byte(const Byte *data, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (data[i] == 0) + return true; + return false; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) { COM_TRY_BEGIN { @@ -1245,36 +1301,37 @@ CObjectVector &pairs = HashPairs; - bool zeroMode = false; - bool cr_lf_Mode = false; - { - for (size_t i = 0; i < buf.Size(); i++) - if (buf[i] == 0) - { - zeroMode = true; - break; - } - } + const bool zeroMode = isThere_Zero_Byte(buf, buf.Size()); _is_ZeroMode = zeroMode; + bool cr_lf_Mode = false; if (!zeroMode) cr_lf_Mode = Is_CR_LF_Data(buf, buf.Size()); if (openCallback) { - CMyComPtr openVolumeCallback; - openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - NCOM::CPropVariant prop; + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openCallback) if (openVolumeCallback) { - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) if (prop.vt == VT_BSTR) - _nameExtenstion = GetMethod_from_FileName(prop.bstrVal); + _is_KnownMethod_in_FileName = GetMethod_from_FileName(prop.bstrVal, _method_from_FileName); } } - bool cksumMode = false; - if (_nameExtenstion.IsEqualTo_Ascii_NoCase("cksum")) - cksumMode = true; + if (!_methods.IsEmpty()) + { + ConvertUnicodeToUTF8(_methods[0], _method_for_Extraction); + } + if (_method_for_Extraction.IsEmpty()) + { + // if (_is_KnownMethod_in_FileName) + _method_for_Extraction = _method_from_FileName; + } + + const bool cksumMode = _method_for_Extraction.IsEqualTo_Ascii_NoCase("cksum"); _is_CksumMode = cksumMode; size_t pos = 0; @@ -1371,15 +1428,17 @@ _is_ZeroMode = false; _are_there_Tags = false; _are_there_Dirs = false; + _is_KnownMethod_in_FileName = false; _hashSize_Defined = false; _hashSize = 0; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { ClearVars(); - _nameExtenstion.Empty(); + _method_from_FileName.Empty(); + _method_for_Extraction.Empty(); _pgpMethod.Empty(); HashPairs.Clear(); return S_OK; @@ -1406,19 +1465,73 @@ } -static void AddDefaultMethod(UStringVector &methods, unsigned size) +static void AddDefaultMethod(UStringVector &methods, + const char *name, unsigned size) { + int shaVersion = -1; + if (name) + { + if (StringsAreEqualNoCase_Ascii(name, "sha")) + { + shaVersion = 0; + if (size == 0) + size = 32; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha1")) + { + shaVersion = 1; + if (size == 0) + size = 20; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha2")) + { + shaVersion = 2; + if (size == 0) + size = 32; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha3")) + { + if (size == 0 || + size == 32) name = "sha3-256"; + else if (size == 28) name = "sha3-224"; + else if (size == 48) name = "sha3-384"; + else if (size == 64) name = "sha3-512"; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha512")) + { + // we allow any sha512 derived hash inside .sha512 file: + if (size == 48) name = "sha384"; + else if (size == 32) name = "sha512-256"; + else if (size == 28) name = "sha512-224"; + } + if (shaVersion >= 0) + name = NULL; + } + const char *m = NULL; - if (size == 32) m = "sha256"; - else if (size == 20) m = "sha1"; - else if (size == 16) m = "md5"; - else if (size == 8) m = "crc64"; - else if (size == 4) m = "crc32"; + if (name) + m = name; else + { + if (size == 64) m = "sha512"; + else if (size == 48) m = "sha384"; + else if (size == 32) m = "sha256"; + else if (size == 28) m = "sha224"; + else if (size == 20) m = "sha1"; + else if (shaVersion < 0) + { + if (size == 16) m = "md5"; + else if (size == 8) m = "crc64"; + else if (size == 4) m = "crc32"; + } + } + + if (!m) return; - #ifdef EXTERNAL_CODECS - const CExternalCodecs *__externalCodecs = g_ExternalCodecs_Ptr; - #endif + +#ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; +#endif CMethodId id; if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS AString(m), id)) @@ -1426,8 +1539,8 @@ } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN @@ -1442,22 +1555,22 @@ if (numItems == 0) return S_OK; - #ifdef EXTERNAL_CODECS - const CExternalCodecs *__externalCodecs = g_ExternalCodecs_Ptr; + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; #endif CHashBundle hb_Glob; // UStringVector methods = options.Methods; UStringVector methods; - - if (methods.IsEmpty() && !_nameExtenstion.IsEmpty()) + +/* + if (methods.IsEmpty() && !utf_nameExtenstion.IsEmpty() && !_hashSize_Defined) { - AString utf; - ConvertUnicodeToUTF8(_nameExtenstion, utf); CMethodId id; - if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS utf, id)) + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS utf_nameExtenstion, id)) methods.Add(_nameExtenstion); } +*/ if (methods.IsEmpty() && !_pgpMethod.IsEmpty()) { @@ -1466,20 +1579,31 @@ methods.Add(UString(_pgpMethod)); } +/* if (methods.IsEmpty() && _pgpMethod.IsEmpty() && _hashSize_Defined) - AddDefaultMethod(methods, _hashSize); + { + AddDefaultMethod(methods, + utf_nameExtenstion.IsEmpty() ? NULL : utf_nameExtenstion.Ptr(), + _hashSize); + } +*/ - RINOK(hb_Glob.SetMethods( + if (!methods.IsEmpty()) + { + RINOK(hb_Glob.SetMethods( EXTERNAL_CODECS_LOC_VARS - methods)); + methods)) + } - CMyComPtr updateCallbackFile; - extractCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&updateCallbackFile); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + updateCallbackFile, extractCallback) if (!updateCallbackFile) return E_NOTIMPL; { - CMyComPtr GetDiskProperty; - extractCallback->QueryInterface(IID_IArchiveGetDiskProperty, (void **)&GetDiskProperty); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetDiskProperty, + GetDiskProperty, extractCallback) if (GetDiskProperty) { UInt64 totalSize = 0; @@ -1492,13 +1616,13 @@ continue; { NCOM::CPropVariant prop; - RINOK(GetDiskProperty->GetDiskProperty(index, kpidSize, &prop)); + RINOK(GetDiskProperty->GetDiskProperty(index, kpidSize, &prop)) if (prop.vt != VT_UI8) continue; totalSize += prop.uhVal.QuadPart; } } - RINOK(extractCallback->SetTotal(totalSize)); + RINOK(extractCallback->SetTotal(totalSize)) // RINOK(Hash_SetTotalUnpacked->Hash_SetTotalUnpacked(indices, numItems)); } } @@ -1508,15 +1632,14 @@ if (!buf.Alloc(kBufSize)) return E_OUTOFMEMORY; - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(extractCallback, false); - lps->InSize = lps->OutSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) + for (UInt32 i = 0;; i++) { - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i >= numItems) + break; const UInt32 index = allFilesMode ? i : indices[i]; CHashPair &hp = HashPairs[index]; @@ -1528,7 +1651,7 @@ const bool isDir = hp.IsDir(); if (!isDir) { - RINOK(updateCallbackFile->GetStream2(index, &inStream, NUpdateNotifyOp::kHashRead)); + RINOK(updateCallbackFile->GetStream2(index, &inStream, NUpdateNotifyOp::kHashRead)) if (!inStream) { continue; // we have shown error in GetStream2() @@ -1541,13 +1664,13 @@ NArchive::NExtract::NAskMode::kExtract; CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) /* PrepareOperation() can expect kExtract to set Attrib and security of output file */ askMode = NArchive::NExtract::NAskMode::kReadExternal; - extractCallback->PrepareOperation(askMode); + RINOK(extractCallback->PrepareOperation(askMode)) const bool isAltStream = false; @@ -1565,25 +1688,30 @@ { hb_Use = &hb_Loc; CMethodId id; - if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS hp.Method, id)) + AString methodName = hp.Method; + Convert_TagName_to_MethodName(methodName); + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, id)) { - methods_loc.Add(UString(hp.Method)); + methods_loc.Add(UString(methodName)); RINOK(hb_Loc.SetMethods( EXTERNAL_CODECS_LOC_VARS - methods_loc)); + methods_loc)) } else res_SetMethods = E_NOTIMPL; } else if (methods.IsEmpty()) { - AddDefaultMethod(methods_loc, (unsigned)hp.Hash.Size()); + AddDefaultMethod(methods_loc, + _method_for_Extraction.IsEmpty() ? NULL : + _method_for_Extraction.Ptr(), + (unsigned)hp.Hash.Size()); if (!methods_loc.IsEmpty()) { hb_Use = &hb_Loc; RINOK(hb_Loc.SetMethods( EXTERNAL_CODECS_LOC_VARS - methods_loc)); + methods_loc)) } } @@ -1596,16 +1724,16 @@ { if ((step & 0xFF) == 0) { - RINOK(lps->SetRatioInfo(NULL, &fileSize)); + RINOK(lps.Interface()->SetRatioInfo(NULL, &fileSize)) } UInt32 size; - RINOK(inStream->Read(buf, kBufSize, &size)); + RINOK(inStream->Read(buf, kBufSize, &size)) if (size == 0) break; hb_Use->Update(buf, size); if (realOutStream) { - RINOK(WriteStream(realOutStream, buf, size)); + RINOK(WriteStream(realOutStream, buf, size)) } fileSize += size; } @@ -1625,7 +1753,7 @@ Int32 opRes = NArchive::NExtract::NOperationResult::kUnsupportedMethod; if (isSupportedMode && res_SetMethods != E_NOTIMPL - && hb_Use->Hashers.Size() > 0 + && !hb_Use->Hashers.IsEmpty() ) { const CHasherState &hs = hb_Use->Hashers[0]; @@ -1638,11 +1766,10 @@ } } - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } - return lps->SetCur(); - + return S_OK; COM_TRY_END } @@ -1668,7 +1795,7 @@ bool convertSlash) { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propId, &prop)); + RINOK(callback->GetProperty(index, propId, &prop)) if (prop.vt == VT_BSTR) { res = prop.bstrVal; @@ -1681,15 +1808,15 @@ } -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) { *type = NFileTimeType::kUnix; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) { COM_TRY_BEGIN @@ -1697,8 +1824,8 @@ return E_NOTIMPL; /* - CMyComPtr reportArcProp; - callback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); + Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, + reportArcProp, callback) */ CObjectVector updateItems; @@ -1716,7 +1843,7 @@ if (!callback) return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) ui.NewProps = IntToBool(newProps); ui.NewData = IntToBool(newData); @@ -1726,7 +1853,7 @@ { { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) if (prop.vt == VT_EMPTY) ui.IsDir = false; else if (prop.vt != VT_BOOL) @@ -1736,7 +1863,7 @@ } RINOK(GetPropString(callback, i, kpidPath, ui.Path, - true)); // convertSlash + true)) // convertSlash /* if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') ui.Name += '/'; @@ -1746,7 +1873,7 @@ if (IntToBool(newData)) { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)) if (prop.vt == VT_UI8) { ui.Size = prop.uhVal.QuadPart; @@ -1763,11 +1890,11 @@ if (complexity != 0) { - RINOK(callback->SetTotal(complexity)); + RINOK(callback->SetTotal(complexity)) } - #ifdef EXTERNAL_CODECS - const CExternalCodecs *__externalCodecs = g_ExternalCodecs_Ptr; + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; #endif CHashBundle hb; @@ -1779,32 +1906,38 @@ methods.Add(_methods[k]); } } - else if (_crcSize_WasSet) - { - AddDefaultMethod(methods, _crcSize); - } else { - CMyComPtr getRootProps; - callback->QueryInterface(IID_IArchiveGetRootProps, (void **)&getRootProps); - - NCOM::CPropVariant prop; + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRootProps, + getRootProps, callback) if (getRootProps) { - RINOK(getRootProps->GetRootProp(kpidArcFileName, &prop)); + NCOM::CPropVariant prop; + RINOK(getRootProps->GetRootProp(kpidArcFileName, &prop)) if (prop.vt == VT_BSTR) { - const UString method = GetMethod_from_FileName(prop.bstrVal); + AString method; + /* const bool isKnownMethod = */ GetMethod_from_FileName(prop.bstrVal, method); if (!method.IsEmpty()) - methods.Add(method); + { + AddDefaultMethod(methods, method, _crcSize_WasSet ? _crcSize : 0); + if (methods.IsEmpty()) + return E_NOTIMPL; + } } } } + if (methods.IsEmpty() && _crcSize_WasSet) + { + AddDefaultMethod(methods, + NULL, // name + _crcSize); + } - RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS methods)); + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS methods)) - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; + CMyComPtr2_Create lps; lps->Init(callback, true); const UInt32 kBufSize = 1 << 15; @@ -1828,13 +1961,12 @@ if (options.HashMode_OnlyHash.Val && updateItems.Size() != 1) options.HashMode_OnlyHash.Val = false; - lps->OutSize = 0; complexity = 0; for (i = 0; i < updateItems.Size(); i++) { lps->InSize = complexity; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) const CUpdateItem &ui = updateItems[i]; @@ -1858,12 +1990,13 @@ needWrite = false; else { - RINOK(res); + RINOK(res) if (fileInStream) { - CMyComPtr streamGetSize; - fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize); + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, fileInStream) if (streamGetSize) { UInt64 size; @@ -1871,8 +2004,9 @@ currentComplexity = size; } /* - CMyComPtr getProps; - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetProps, + getProps, fileInStream) if (getProps) { FILETIME mTime; @@ -1880,7 +2014,7 @@ if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK) { currentComplexity = size2; - // item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; + // item.MTime = NTime::FileTimeToUnixTime64(mTime);; } } */ @@ -1901,11 +2035,11 @@ { if ((step & 0xFF) == 0) { - RINOK(lps->SetRatioInfo(&fileSize, NULL)); + RINOK(lps.Interface()->SetRatioInfo(&fileSize, NULL)) // RINOK(callback->SetCompleted(&completeValue)); } UInt32 size; - RINOK(fileInStream->Read(buf, kBufSize, &size)); + RINOK(fileInStream->Read(buf, kBufSize, &size)) if (size == 0) break; hb.Update(buf, size); @@ -1962,7 +2096,7 @@ } } */ - RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) } else { @@ -1987,7 +2121,7 @@ return E_OUTOFMEMORY; } - RINOK(WriteStream(outStream, hashFileString, hashFileString.Len())); + RINOK(WriteStream(outStream, hashFileString, hashFileString.Len())) return S_OK; COM_TRY_END @@ -2023,6 +2157,9 @@ return S_OK; } + if (name.IsEqualTo("backslash")) + return PROPVARIANT_to_bool(value, _supportWindowsBackslash); + if (name.IsPrefixedBy_Ascii_NoCase("crc")) { name.Delete(0, 3); @@ -2040,7 +2177,16 @@ } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +void CHandler::InitProps() +{ + _supportWindowsBackslash = true; + _crcSize_WasSet = false; + _crcSize = 4; + _methods.Clear(); + _options.Init_HashOptionsLocal(); +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN @@ -2048,7 +2194,7 @@ for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetProperty(names[i], values[i])); + RINOK(SetProperty(names[i], values[i])) } return S_OK; COM_TRY_END @@ -2086,11 +2232,32 @@ // ubuntu uses "SHA256SUMS" file item.AddExts(UString ( - "sha256 sha512 sha224 sha384 sha1 sha md5" - // "b2sum" - " crc32 crc64" - " asc" + "sha256" + " sha512" + " sha384" + " sha224" + " sha512-224" + " sha512-256" + " sha3-224" + " sha3-256" + " sha3-384" + " sha3-512" + // " shake128" + // " shake256" + " sha1" + " sha2" + " sha3" + " sha" + " md5" + " blake2s" + " blake2b" + " blake2sp" + " xxh64" + " crc32" + " crc64" " cksum" + " asc" + // " b2sum" ), UString()); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/HashCalc.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/HashCalc.h 2022-02-08 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/HashCalc.h 2024-12-09 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // HashCalc.h -#ifndef __HASH_CALC_H -#define __HASH_CALC_H +#ifndef ZIP7_INC_HASH_CALC_H +#define ZIP7_INC_HASH_CALC_H #include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" @@ -20,7 +20,7 @@ if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number if (size > 8) : lower case : original byte order (as big-endian byte sequence) */ -void HashHexToString(char *dest, const Byte *data, UInt32 size); +void HashHexToString(char *dest, const Byte *data, size_t size); enum { @@ -65,8 +65,10 @@ }; +Z7_PURE_INTERFACES_BEGIN -struct IHashCalc + +DECLARE_INTERFACE(IHashCalc) { virtual void InitForNewFile() = 0; virtual void Update(const void *data, UInt32 size) = 0; @@ -74,7 +76,9 @@ virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; }; -struct CHashBundle: public IHashCalc +Z7_PURE_INTERFACES_END + +struct CHashBundle Z7_final: public IHashCalc { CObjectVector Hashers; @@ -98,32 +102,32 @@ NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; } - virtual ~CHashBundle() {}; - - void InitForNewFile(); - void Update(const void *data, UInt32 size); - void SetSize(UInt64 size); - void Final(bool isDir, bool isAltStream, const UString &path); + void InitForNewFile() Z7_override; + void Update(const void *data, UInt32 size) Z7_override; + void SetSize(UInt64 size) Z7_override; + void Final(bool isDir, bool isAltStream, const UString &path) Z7_override; }; -#define INTERFACE_IHashCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT SetNumFiles(UInt64 numFiles) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT CheckBreak() x; \ - virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \ - virtual HRESULT AfterLastFile(CHashBundle &hb) x; \ +Z7_PURE_INTERFACES_BEGIN -struct IHashCallbackUI: public IDirItemsCallback -{ - INTERFACE_IHashCallbackUI(=0) -}; +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IHashCallbackUI(x) \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT SetNumFiles(UInt64 numFiles) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT CheckBreak() x \ + virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \ + virtual HRESULT AfterLastFile(CHashBundle &hb) x \ + +Z7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback) + +Z7_PURE_INTERFACES_END struct CHashOptionsLocal @@ -200,7 +204,7 @@ OpenShareForWrite(false), StdInMode(false), AltStreamsMode(false), - PathMode(NWildcard::k_RelatPath) {}; + PathMode(NWildcard::k_RelatPath) {} }; @@ -213,7 +217,7 @@ -#ifndef _SFX +#ifndef Z7_SFX namespace NHash { @@ -222,6 +226,7 @@ CByteBuffer Hash; char Mode; bool IsBSD; + bool Escape; bool Size_from_Arc_Defined; bool Size_from_Disk_Defined; AString Method; @@ -255,6 +260,7 @@ CHashPair(): Mode(0) , IsBSD(false) + , Escape(false) , Size_from_Arc_Defined(false) , Size_from_Disk_Defined(false) // , HashLengthInBits(0) @@ -264,70 +270,46 @@ }; -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - // public IGetArchiveHashHandler, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveGetRawProps, + /* public IGetArchiveHashHandler, */ + IOutArchive, + ISetProperties +) bool _isArc; - UInt64 _phySize; - CObjectVector HashPairs; - UString _nameExtenstion; - // UString _method_fromName; - AString _pgpMethod; + bool _supportWindowsBackslash; + bool _crcSize_WasSet; bool _is_CksumMode; bool _is_PgpMethod; bool _is_ZeroMode; bool _are_there_Tags; bool _are_there_Dirs; + bool _is_KnownMethod_in_FileName; bool _hashSize_Defined; unsigned _hashSize; - - bool _crcSize_WasSet; UInt32 _crcSize; + UInt64 _phySize; + CObjectVector HashPairs; UStringVector _methods; + AString _method_from_FileName; + AString _pgpMethod; + AString _method_for_Extraction; + CHashOptionsLocal _options; void ClearVars(); - - void InitProps() - { - _crcSize_WasSet = false; - _crcSize = 4; - _methods.Clear(); - _options.Init_HashOptionsLocal(); - } - - CHashOptionsLocal _options; + void InitProps(); bool CanUpdate() const { if (!_isArc || _is_PgpMethod || _is_CksumMode) return false; return true; - } HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value); public: - CHandler(); - - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveGetRawProps, - IOutArchive, - ISetProperties - /*, IGetArchiveHashHandler */ - ) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - INTERFACE_IArchiveGetRawProps(;) - // STDMETHOD(GetArchiveHashHandler)(CHandler **handler); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); }; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/IFileExtractCallback.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/IFileExtractCallback.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/IFileExtractCallback.h 2021-09-21 16:07:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/IFileExtractCallback.h 2023-04-05 20:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // IFileExtractCallback.h -#ifndef __I_FILE_EXTRACT_CALLBACK_H -#define __I_FILE_EXTRACT_CALLBACK_H +#ifndef ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H +#define ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H #include "../../../Common/MyString.h" @@ -10,6 +10,15 @@ #include "LoadCodecs.h" #include "OpenArchive.h" +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_FOLDERARC_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 1, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_FOLDERARC(i, n) \ + Z7_IFACE_CONSTR_FOLDERARC_SUB(i, IUnknown, n) + namespace NOverwriteAnswer { enum EEnum @@ -42,27 +51,21 @@ IFolderArchiveExtractCallback is used by Common/ArchiveExtractCallback.cpp */ -#define INTERFACE_IFolderArchiveExtractCallback(x) \ - STDMETHOD(AskOverwrite)( \ +#define Z7_IFACEM_IFolderArchiveExtractCallback(x) \ + x(AskOverwrite( \ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, \ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, \ - Int32 *answer) x; \ - STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position) x; \ - STDMETHOD(MessageError)(const wchar_t *message) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes, Int32 encrypted) x; \ + Int32 *answer)) \ + x(PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) \ + x(MessageError(const wchar_t *message)) \ + x(SetOperationResult(Int32 opRes, Int32 encrypted)) \ -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07) -{ - INTERFACE_IFolderArchiveExtractCallback(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC_SUB(IFolderArchiveExtractCallback, IProgress, 0x07) -#define INTERFACE_IFolderArchiveExtractCallback2(x) \ - STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 encrypted, const wchar_t *name) x; \ +#define Z7_IFACEM_IFolderArchiveExtractCallback2(x) \ + x(ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) \ -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback2, IUnknown, 0x01, 0x08) -{ - INTERFACE_IFolderArchiveExtractCallback2(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveExtractCallback2, 0x08) /* ---------- IExtractCallbackUI ---------- is implemented by @@ -70,45 +73,40 @@ FileManager/ExtractCallback.h CExtractCallbackImp */ -#ifdef _NO_CRYPTO - #define INTERFACE_IExtractCallbackUI_Crypto(x) +#ifdef Z7_NO_CRYPTO + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) #else - #define INTERFACE_IExtractCallbackUI_Crypto(x) \ - virtual HRESULT SetPassword(const UString &password) x; + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) \ + virtual HRESULT SetPassword(const UString &password) px #endif -#define INTERFACE_IExtractCallbackUI(x) \ - virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) x; \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT ThereAreNoFiles() x; \ - virtual HRESULT ExtractResult(HRESULT result) x; \ - INTERFACE_IExtractCallbackUI_Crypto(x) +#define Z7_IFACEN_IExtractCallbackUI(px) \ + virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) px \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) px \ + virtual HRESULT ThereAreNoFiles() px \ + virtual HRESULT ExtractResult(HRESULT result) px \ + Z7_IFACEM_IExtractCallbackUI_Crypto(px) -struct IExtractCallbackUI: IFolderArchiveExtractCallback -{ - INTERFACE_IExtractCallbackUI(PURE) -}; +// IExtractCallbackUI - is non-COM interface +// IFolderArchiveExtractCallback - is COM interface +// Z7_IFACE_DECL_PURE_(IExtractCallbackUI, IFolderArchiveExtractCallback) +Z7_IFACE_DECL_PURE(IExtractCallbackUI) -#define INTERFACE_IGetProp(x) \ - STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \ +#define Z7_IFACEM_IGetProp(x) \ + x(GetProp(PROPID propID, PROPVARIANT *value)) \ -DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20) -{ - INTERFACE_IGetProp(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IGetProp, 0x20) -#define INTERFACE_IFolderExtractToStreamCallback(x) \ - STDMETHOD(UseExtractToStream)(Int32 *res) x; \ - STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \ - STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult8)(Int32 resultEOperationResult, Int32 encrypted, UInt64 size) x; \ +#define Z7_IFACEM_IFolderExtractToStreamCallback(x) \ + x(UseExtractToStream(Int32 *res)) \ + x(GetStream7(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp)) \ + x(PrepareOperation7(Int32 askExtractMode)) \ + x(SetOperationResult8(Int32 resultEOperationResult, Int32 encrypted, UInt64 size)) \ -DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x31) -{ - INTERFACE_IFolderExtractToStreamCallback(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderExtractToStreamCallback, 0x31) +Z7_PURE_INTERFACES_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.cpp 2022-05-11 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LoadCodecs.cpp /* -EXTERNAL_CODECS +Z7_EXTERNAL_CODECS --------------- CCodecs::Load() tries to detect the directory with plugins. It stops the checking, if it can find any of the following items: @@ -22,7 +22,7 @@ EXPORT_CODECS ------------- - if (EXTERNAL_CODECS) is defined, then the code exports internal + if (Z7_EXTERNAL_CODECS) is defined, then the code exports internal codecs of client from CCodecs object to external plugins. 7-Zip doesn't use that feature. 7-Zip uses the scheme: - client application without internal plugins. @@ -43,29 +43,15 @@ #include "LoadCodecs.h" -using namespace NWindows; - -#ifdef NEW_FOLDER_INTERFACE -#include "../../../Common/StringToInt.h" -#endif - #include "../../ICoder.h" #include "../../Common/RegisterArc.h" #include "../../Common/RegisterCodec.h" -#ifdef EXTERNAL_CODECS - +#ifdef Z7_EXTERNAL_CODECS // #define EXPORT_CODECS - -#endif - -#ifdef NEW_FOLDER_INTERFACE -extern HINSTANCE g_hInstance; -#include "../../../Windows/ResourceString.h" -static const UINT kIconTypesResId = 100; #endif -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../../../Windows/FileFind.h" #include "../../../Windows/DLL.h" @@ -75,6 +61,7 @@ #include "../../../Windows/Registry.h" #endif +using namespace NWindows; using namespace NFile; @@ -119,10 +106,10 @@ #endif // _WIN32 -#endif // EXTERNAL_CODECS +#endif // Z7_EXTERNAL_CODECS -static const unsigned kNumArcsMax = 64; +static const unsigned kNumArcsMax = 72; static unsigned g_NumArcs = 0; static const CArcInfo *g_Arcs[kNumArcsMax]; @@ -133,8 +120,10 @@ g_Arcs[g_NumArcs] = arcInfo; g_NumArcs++; } + // else throw 1; } +/* static void SplitString(const UString &srcString, UStringVector &destStrings) { destStrings.Clear(); @@ -159,6 +148,7 @@ if (!s.IsEmpty()) destStrings.Add(s); } +*/ int CArcInfoEx::FindExtension(const UString &ext) const { @@ -180,14 +170,14 @@ if (i < addExts.Size()) { extInfo.AddExt = addExts[i]; - if (extInfo.AddExt == L"*") + if (extInfo.AddExt.IsEqualTo("*")) extInfo.AddExt.Empty(); } Exts.Add(extInfo); } } -#ifndef _SFX +#ifndef Z7_SFX static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector &signatures) { @@ -205,11 +195,11 @@ return true; } -#endif // _SFX +#endif // Z7_SFX // #include -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS static FString GetBaseFolderPrefixFromRegistry() { @@ -238,7 +228,7 @@ { NCOM::CPropVariant prop; isAssigned = false; - RINOK(getMethodProperty(index, propId, &prop)); + RINOK(getMethodProperty(index, propId, &prop)) if (prop.vt == VT_BSTR) { if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) @@ -258,7 +248,7 @@ NCOM::CPropVariant prop; resVal = false; isAssigned = false; - RINOK(getMethodProperty(index, propId, &prop)); + RINOK(getMethodProperty(index, propId, &prop)) if (prop.vt == VT_BOOL) { isAssigned = true; @@ -269,45 +259,53 @@ return S_OK; } +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#ifdef _WIN32 +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif -#define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func); +#define MY_GET_FUNC(dest, type, lib, func) \ + dest = Z7_GET_PROC_ADDRESS(type, lib.Get_HMODULE(), func); // #define MY_GET_FUNC(dest, type, func) dest = (type)(func); -#define MY_GET_FUNC_LOC(dest, type, func) \ - type dest; MY_GET_FUNC(dest, type, func) +#define MY_GET_FUNC_LOC(dest, type, lib, func) \ + type dest; MY_GET_FUNC(dest, type, lib, func) HRESULT CCodecs::LoadCodecs() { CCodecLib &lib = Libs.Back(); - MY_GET_FUNC (lib.CreateDecoder, Func_CreateDecoder, lib.Lib.GetProc("CreateDecoder")); - MY_GET_FUNC (lib.CreateEncoder, Func_CreateEncoder, lib.Lib.GetProc("CreateEncoder")); - MY_GET_FUNC (lib.GetMethodProperty, Func_GetMethodProperty, lib.Lib.GetProc("GetMethodProperty")); + MY_GET_FUNC (lib.CreateDecoder, Func_CreateDecoder, lib.Lib, "CreateDecoder") + MY_GET_FUNC (lib.CreateEncoder, Func_CreateEncoder, lib.Lib, "CreateEncoder") + MY_GET_FUNC (lib.GetMethodProperty, Func_GetMethodProperty, lib.Lib, "GetMethodProperty") if (lib.GetMethodProperty) { UInt32 numMethods = 1; - MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods")); + MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib, "GetNumberOfMethods") if (getNumberOfMethods) { - RINOK(getNumberOfMethods(&numMethods)); + RINOK(getNumberOfMethods(&numMethods)) } for (UInt32 i = 0; i < numMethods; i++) { CDllCodecInfo info; info.LibIndex = Libs.Size() - 1; info.CodecIndex = i; - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)); - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)); - RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned)); + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)) + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)) + RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned)) Codecs.Add(info); } } - MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers")); + MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib, "GetHashers") if (getHashers) { - RINOK(getHashers(&lib.ComHashers)); + RINOK(getHashers(&lib.ComHashers)) if (lib.ComHashers) { UInt32 numMethods = lib.ComHashers->GetNumHashers(); @@ -330,7 +328,7 @@ UInt32 index, PROPID propID, NCOM::CPropVariant &prop) { if (getProp2) - return getProp2(index, propID, &prop);; + return getProp2(index, propID, &prop); return getProp(propID, &prop); } @@ -341,7 +339,7 @@ { res = false; NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BOOL) res = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -357,7 +355,7 @@ res = 0; defined = false; NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_UI4) { res = prop.ulVal; @@ -375,7 +373,7 @@ { res.Empty(); NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BSTR) res.SetFromBstr(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -390,7 +388,7 @@ { bb.Free(); NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BSTR) { UINT len = ::SysStringByteLen(prop.bstrVal); @@ -413,22 +411,22 @@ const NDLL::CLibrary &lib = Libs.Back().Lib; Func_GetHandlerProperty getProp = NULL; - MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2")); - MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc")); + MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib, "GetHandlerProperty2") + MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib, "GetIsArc") UInt32 numFormats = 1; if (getProp2) { - MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats")); + MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib, "GetNumberOfFormats") if (getNumberOfFormats) { - RINOK(getNumberOfFormats(&numFormats)); + RINOK(getNumberOfFormats(&numFormats)) } } else { - MY_GET_FUNC (getProp, Func_GetHandlerProperty, lib.GetProc("GetHandlerProperty")); + MY_GET_FUNC (getProp, Func_GetHandlerProperty, lib, "GetHandlerProperty") if (!getProp) return S_OK; } @@ -439,7 +437,7 @@ item.LibIndex = (int)(Libs.Size() - 1); item.FormatIndex = i; - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)); + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)) { NCOM::CPropVariant prop; @@ -454,18 +452,18 @@ } UString ext, addExt; - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)); - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)); + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)) + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)) item.AddExts(ext, addExt); GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled); bool flags_Defined = false; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)); + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)) item.NewInterface = flags_Defined; if (!flags_Defined) // && item.UpdateEnabled { // support for DLL version before 9.31: - for (unsigned j = 0; j < ARRAY_SIZE(kArcFlagsPars); j += 2) + for (unsigned j = 0; j < Z7_ARRAY_SIZE(kArcFlagsPars); j += 2) { bool val = false; GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val); @@ -476,21 +474,21 @@ { bool defined = false; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kTimeFlags, item.TimeFlags, defined)); + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kTimeFlags, item.TimeFlags, defined)) } CByteBuffer sig; - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)); + RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)) if (sig.Size() != 0) item.Signatures.Add(sig); else { - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)); + RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)) ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures); } bool signatureOffset_Defined; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)); + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)) // bool version_Defined; // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined)); @@ -503,7 +501,7 @@ return S_OK; } -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES extern "C" { extern SIZE_T g_LargePageSize; @@ -513,12 +511,57 @@ void CCodecs::AddLastError(const FString &path) { - HRESULT res = GetLastError_noZero_HRESULT(); + const HRESULT res = GetLastError_noZero_HRESULT(); CCodecError &error = Errors.AddNew(); error.Path = path; error.ErrorCode = res; } + +static bool IsSupportedDll(CCodecLib &lib) +{ + MY_GET_FUNC_LOC ( + f_GetModuleProp, + Func_GetModuleProp, lib.Lib, + "GetModuleProp") + /* p7zip and 7-Zip before v23 used virtual destructor in IUnknown, + if _WIN32 is not defined */ + UInt32 flags = + #ifdef _WIN32 + NModuleInterfaceType::k_IUnknown_VirtDestructor_No; + #else + NModuleInterfaceType::k_IUnknown_VirtDestructor_Yes; + #endif + if (f_GetModuleProp) + { + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kInterfaceType, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + flags = prop.ulVal; + else if (prop.vt != VT_EMPTY) + return false; + } + } + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kVersion, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + lib.Version = prop.ulVal; + } + } + } + if ( + flags + // (flags & NModuleFlags::kMask) + != NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule) + return false; + return true; +} + + HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK) { if (loadedOK) @@ -537,7 +580,7 @@ // #define ERROR_BAD_EXE_FORMAT 193L */ // return GetLastError_noZero_HRESULT(); - DWORD lastError = GetLastError(); + const DWORD lastError = GetLastError(); if (lastError != ERROR_BAD_EXE_FORMAT) { CCodecError &error = Errors.AddNew(); @@ -558,20 +601,30 @@ bool used = false; // HRESULT res = S_OK; - if (lib.Lib.Load(dllPath)) + if (lib.Lib.Load(dllPath)) + { + if (!IsSupportedDll(lib)) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "the module is not compatible with program"; + } + else { if (loadedOK) *loadedOK = true; + /* #ifdef NEW_FOLDER_INTERFACE lib.LoadIcons(); #endif + */ /* { - MY_GET_FUNC_LOC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup")); - if (_LibStartup) + MY_GET_FUNC_LOC (_libStartup, Func_libStartup, lib.Lib, "LibStartup") + if (_libStartup) { - HRESULT res = _LibStartup(); + HRESULT res = _libStartup(); if (res != 0) { CCodecError &error = Errors.AddNew(); @@ -582,10 +635,10 @@ } */ - #ifdef _7ZIP_LARGE_PAGES + #ifdef Z7_LARGE_PAGES if (g_LargePageSize != 0) { - MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode")); + MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib, "SetLargePageMode") if (setLargePageMode) setLargePageMode(); } @@ -593,14 +646,14 @@ if (CaseSensitive_Change) { - MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive")); + MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib, "SetCaseSensitive") if (setCaseSensitive) setCaseSensitive(CaseSensitive ? 1 : 0); } /* { - MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib.GetProc("SetClientVersion")); + MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib, "SetClientVersion") if (setClientVersion) { // const UInt32 kVersion = (MY_VER_MAJOR << 16) | MY_VER_MINOR; @@ -610,7 +663,7 @@ */ - MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib.GetProc("CreateObject")); + MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib, "CreateObject") { unsigned startSize = Codecs.Size() + Hashers.Size(); HRESULT res = LoadCodecs(); @@ -640,7 +693,8 @@ } */ } - else + } + else { AddLastError(dllPath); } @@ -686,7 +740,7 @@ continue; #endif - RINOK(LoadDll(folderPrefix + fi.Name, true)); + RINOK(LoadDll(folderPrefix + fi.Name, true)) } return S_OK; } @@ -714,18 +768,20 @@ // OutputDebugStringA("~CloseLibs end"); } -#endif // EXTERNAL_CODECS +#endif // Z7_EXTERNAL_CODECS HRESULT CCodecs::Load() { + /* #ifdef NEW_FOLDER_INTERFACE InternalIcons.LoadIcons(g_hInstance); #endif + */ Formats.Clear(); - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS Errors.Clear(); MainDll_ErrorPath.Empty(); Codecs.Clear(); @@ -751,7 +807,7 @@ item.AddExts(e, ae); } - #ifndef _SFX + #ifndef Z7_SFX item.CreateOutArchive = arc.CreateOutArchive; item.UpdateEnabled = (arc.CreateOutArchive != NULL); @@ -774,16 +830,16 @@ // printf("\nLoad codecs \n"); - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const FString baseFolder = GetBaseFolderPrefixFromRegistry(); { bool loadedOK; - RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)); + RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)) if (!loadedOK) MainDll_ErrorPath = kMainDll; } - RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName)); - RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName)); + RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName)) + RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName)) NeedSetLibCodecs = true; @@ -806,10 +862,10 @@ FOR_VECTOR(i, Libs) { CCodecLib &lib = Libs[i]; - MY_GET_FUNC (lib.SetCodecs, Func_SetCodecs, lib.Lib.GetProc("SetCodecs")); + MY_GET_FUNC (lib.SetCodecs, Func_SetCodecs, lib.Lib, "SetCodecs") if (lib.SetCodecs) { - RINOK(lib.SetCodecs(this)); + RINOK(lib.SetCodecs(this)) } } } @@ -821,7 +877,7 @@ return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX int CCodecs::FindFormatForArchiveName(const UString &arcPath) const { @@ -875,8 +931,8 @@ const UString name = arcType.Mid(pos, (unsigned)pos2 - pos); if (name.IsEmpty()) return false; - int index = FindFormatForArchiveType(name); - if (index < 0 && name != L"*") + const int index = FindFormatForArchiveType(name); + if (index < 0 && !name.IsEqualTo("*")) { formatIndices.Clear(); return false; @@ -887,60 +943,10 @@ return true; } -#endif // _SFX - - -#ifdef NEW_FOLDER_INTERFACE - -void CCodecIcons::LoadIcons(HMODULE m) -{ - UString iconTypes; - MyLoadString(m, kIconTypesResId, iconTypes); - UStringVector pairs; - SplitString(iconTypes, pairs); - FOR_VECTOR (i, pairs) - { - const UString &s = pairs[i]; - int pos = s.Find(L':'); - CIconPair iconPair; - iconPair.IconIndex = -1; - if (pos < 0) - pos = (int)s.Len(); - else - { - const UString num = s.Ptr((unsigned)pos + 1); - if (!num.IsEmpty()) - { - const wchar_t *end; - iconPair.IconIndex = (int)ConvertStringToUInt32(num, &end); - if (*end != 0) - continue; - } - } - iconPair.Ext = s.Left((unsigned)pos); - IconPairs.Add(iconPair); - } -} - -bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const -{ - iconIndex = -1; - FOR_VECTOR (i, IconPairs) - { - const CIconPair &pair = IconPairs[i]; - if (ext.IsEqualTo_NoCase(pair.Ext)) - { - iconIndex = pair.IconIndex; - return true; - } - } - return false; -} - -#endif // NEW_FOLDER_INTERFACE +#endif // Z7_SFX -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS // #define EXPORT_CODECS @@ -964,24 +970,24 @@ #endif // EXPORT_CODECS -STDMETHODIMP CCodecs::GetNumMethods(UInt32 *numMethods) +Z7_COM7F_IMF(CCodecs::GetNumMethods(UInt32 *numMethods)) { *numMethods = NUM_EXPORT_CODECS - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS + Codecs.Size() #endif ; return S_OK; } -STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return GetMethodProperty(index, propID, value); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (propID == NMethodPropID::kDecoderIsAssigned || @@ -1010,14 +1016,14 @@ #endif } -STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder) +Z7_COM7F_IMF(CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return CreateDecoder(index, iid, coder); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (ci.DecoderIsAssigned) { @@ -1033,14 +1039,14 @@ #endif } -STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder) +Z7_COM7F_IMF(CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return CreateEncoder(index, iid, coder); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (ci.EncoderIsAssigned) { @@ -1057,23 +1063,23 @@ } -STDMETHODIMP_(UInt32) CCodecs::GetNumHashers() +Z7_COM7F_IMF2(UInt32, CCodecs::GetNumHashers()) { return NUM_EXPORT_HASHERS - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS + Hashers.Size() #endif ; } -STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) { #ifdef EXPORT_CODECS if (index < g_NumHashers) return ::GetHasherProp(index, propID, value); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; return Libs[ci.LibIndex].ComHashers->GetHasherProp(ci.HasherIndex, propID, value); #else @@ -1081,13 +1087,13 @@ #endif } -STDMETHODIMP CCodecs::CreateHasher(UInt32 index, IHasher **hasher) +Z7_COM7F_IMF(CCodecs::CreateHasher(UInt32 index, IHasher **hasher)) { #ifdef EXPORT_CODECS if (index < g_NumHashers) return CreateHasher(index, hasher); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; return Libs[ci.LibIndex].ComHashers->CreateHasher(ci.HasherIndex, hasher); #else @@ -1102,7 +1108,7 @@ return -1; #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; return (int)ci.LibIndex; #else @@ -1117,7 +1123,7 @@ return -1; #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; return (int)ci.LibIndex; #else @@ -1140,7 +1146,7 @@ } #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return Codecs[index - NUM_EXPORT_CODECS].DecoderIsAssigned; #else return false; @@ -1163,7 +1169,7 @@ } #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return Codecs[index - NUM_EXPORT_CODECS].EncoderIsAssigned; #else return false; @@ -1190,7 +1196,7 @@ } #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { const CDllCodecInfo &c = Codecs[index - NUM_EXPORT_CODECS]; isAssigned = c.IsFilter_Assigned; @@ -1217,7 +1223,7 @@ HRESULT CCodecs::GetCodec_Id(UInt32 index, UInt64 &id) { NCOM::CPropVariant prop; - RINOK(GetProperty(index, NMethodPropID::kID, &prop)); + RINOK(GetProperty(index, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; id = prop.uhVal.QuadPart; @@ -1286,9 +1292,9 @@ } } -#endif // EXTERNAL_CODECS +#endif // Z7_EXTERNAL_CODECS -#ifndef _SFX +#ifndef Z7_SFX extern unsigned g_NumCodecs; extern const CCodecInfo *g_Codecs[]; @@ -1311,7 +1317,7 @@ } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { UInt32 numMethods; if (GetNumMethods(&numMethods) == S_OK) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.h 2022-05-11 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/LoadCodecs.h 2023-04-06 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // LoadCodecs.h -#ifndef __LOAD_CODECS_H -#define __LOAD_CODECS_H +#ifndef ZIP7_INC_LOAD_CODECS_H +#define ZIP7_INC_LOAD_CODECS_H /* Client application uses LoadCodecs.* to load plugins to @@ -10,26 +10,26 @@ 2) Codecs - external codecs 3) Hashers - external hashers -EXTERNAL_CODECS +Z7_EXTERNAL_CODECS --------------- - if EXTERNAL_CODECS is defined, then the code tries to load external + if Z7_EXTERNAL_CODECS is defined, then the code tries to load external plugins from DLL files (shared libraries). There are two types of executables in 7-Zip: 1) Executable that uses external plugins must be compiled - with EXTERNAL_CODECS defined: + with Z7_EXTERNAL_CODECS defined: - 7z.exe, 7zG.exe, 7zFM.exe - Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h + Note: Z7_EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h that code is used in plugin module (7z.dll). - 2) Standalone modules are compiled without EXTERNAL_CODECS: + 2) Standalone modules are compiled without Z7_EXTERNAL_CODECS: - SFX modules: 7z.sfx, 7zCon.sfx - standalone versions of console 7-Zip: 7za.exe, 7zr.exe - if EXTERNAL_CODECS is defined, CCodecs class implements interfaces: + if Z7_EXTERNAL_CODECS is defined, CCodecs class implements interfaces: - ICompressCodecsInfo : for Codecs - IHashers : for Hashers @@ -51,7 +51,7 @@ #include "../../../Common/MyString.h" #include "../../../Common/ComTry.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../../../Windows/DLL.h" #endif @@ -60,7 +60,7 @@ #include "../../Archive/IArchive.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CDllCodecInfo { @@ -104,19 +104,21 @@ UString Name; CObjectVector Exts; - #ifndef _SFX + #ifndef Z7_SFX Func_CreateOutArchive CreateOutArchive; bool UpdateEnabled; bool NewInterface; // UInt32 Version; UInt32 SignatureOffset; CObjectVector Signatures; + /* #ifdef NEW_FOLDER_INTERFACE UStringVector AssociateExts; #endif + */ #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS int LibIndex; UInt32 FormatIndex; CLSID ClassID; @@ -124,10 +126,10 @@ int Compare(const CArcInfoEx &a) const { - int res = Name.Compare(a.Name); + const int res = Name.Compare(a.Name); if (res != 0) return res; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return MyCompare(LibIndex, a.LibIndex); #else return 0; @@ -192,6 +194,7 @@ bool Is_Tar() const { return Name.IsEqualTo_Ascii_NoCase("tar"); } bool Is_Zip() const { return Name.IsEqualTo_Ascii_NoCase("zip"); } bool Is_Rar() const { return Name.IsEqualTo_Ascii_NoCase("rar"); } + bool Is_Zstd() const { return Name.IsEqualTo_Ascii_NoCase("zstd"); } /* UString GetAllExtensions() const @@ -200,7 +203,7 @@ for (int i = 0; i < Exts.Size(); i++) { if (i > 0) - s += ' '; + s.Add_Space(); s += Exts[i].Ext; } return s; @@ -215,42 +218,23 @@ TimeFlags(0), CreateInArchive(NULL), IsArcFunc(NULL) - #ifndef _SFX + #ifndef Z7_SFX , CreateOutArchive(NULL) , UpdateEnabled(false) , NewInterface(false) // , Version(0) , SignatureOffset(0) #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS , LibIndex(-1) #endif {} }; -#ifdef NEW_FOLDER_INTERFACE - -struct CCodecIcons -{ - struct CIconPair - { - UString Ext; - int IconIndex; - }; - CObjectVector IconPairs; - - void LoadIcons(HMODULE m); - bool FindIconIndex(const UString &ext, int &iconIndex) const; -}; - -#endif -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CCodecLib - #ifdef NEW_FOLDER_INTERFACE - : public CCodecIcons - #endif { NWindows::NDLL::CLibrary Lib; FString Path; @@ -262,17 +246,23 @@ Func_SetCodecs SetCodecs; CMyComPtr ComHashers; + + UInt32 Version; + /* #ifdef NEW_FOLDER_INTERFACE - void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); } + CCodecIcons CodecIcons; + void LoadIcons() { CodecIcons.LoadIcons((HMODULE)Lib); } #endif + */ CCodecLib(): CreateObject(NULL), GetMethodProperty(NULL), CreateDecoder(NULL), CreateEncoder(NULL), - SetCodecs(NULL) + SetCodecs(NULL), + Version(0) {} }; @@ -301,8 +291,8 @@ }; -class CCodecs: - #ifdef EXTERNAL_CODECS +class CCodecs Z7_final: + #ifdef Z7_EXTERNAL_CODECS public ICompressCodecsInfo, public IHashers, #else @@ -310,9 +300,15 @@ #endif public CMyUnknownImp { - CLASS_NO_COPY(CCodecs); +#ifdef Z7_EXTERNAL_CODECS + Z7_IFACES_IMP_UNK_2(ICompressCodecsInfo, IHashers) +#else + Z7_COM_UNKNOWN_IMP_0 +#endif // Z7_EXTERNAL_CODECS + + Z7_CLASS_NO_COPY(CCodecs) public: - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CObjectVector Libs; FString MainDll_ErrorPath; @@ -323,7 +319,7 @@ class CReleaser { - CLASS_NO_COPY(CReleaser); + Z7_CLASS_NO_COPY(CReleaser) /* CCodecsReleaser object releases CCodecs links. 1) CCodecs is COM object that is deleted when all links to that object will be released/ @@ -352,13 +348,15 @@ #endif + /* #ifdef NEW_FOLDER_INTERFACE CCodecIcons InternalIcons; #endif + */ CObjectVector Formats; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CRecordVector Codecs; CRecordVector Hashers; #endif @@ -367,7 +365,7 @@ bool CaseSensitive; CCodecs(): - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS NeedSetLibCodecs(true), #endif CaseSensitive_Change(false), @@ -386,34 +384,14 @@ HRESULT Load(); - #ifndef _SFX + #ifndef Z7_SFX int FindFormatForArchiveName(const UString &arcPath) const; int FindFormatForExtension(const UString &ext) const; int FindFormatForArchiveType(const UString &arcType) const; bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const; #endif - #ifdef EXTERNAL_CODECS - - MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers) - - STDMETHOD(GetNumMethods)(UInt32 *numMethods); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder); - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder); - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); - - #else - - MY_UNKNOWN_IMP - - #endif // EXTERNAL_CODECS - - - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS int GetCodec_LibIndex(UInt32 index) const; bool GetCodec_DecoderIsAssigned(UInt32 index) const; @@ -435,7 +413,7 @@ HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr &archive) const { const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (ai.LibIndex < 0) #endif { @@ -444,17 +422,17 @@ return S_OK; COM_TRY_END } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return CreateArchiveHandler(ai, false, (void **)&archive); #endif } - #ifndef _SFX + #ifndef Z7_SFX HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr &archive) const { const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (ai.LibIndex < 0) #endif { @@ -464,7 +442,7 @@ COM_TRY_END } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return CreateArchiveHandler(ai, true, (void **)&archive); #endif } @@ -484,21 +462,21 @@ void Get_CodecsInfoUser_Vector(CObjectVector &v); - #endif // _SFX + #endif // Z7_SFX }; -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #define CREATE_CODECS_OBJECT \ CCodecs *codecs = new CCodecs; \ - CExternalCodecs __externalCodecs; \ - __externalCodecs.GetCodecs = codecs; \ - __externalCodecs.GetHashers = codecs; \ + CExternalCodecs _externalCodecs; \ + _externalCodecs.GetCodecs = codecs; \ + _externalCodecs.GetHashers = codecs; \ CCodecs::CReleaser codecsReleaser; \ codecsReleaser.Set(codecs); #else #define CREATE_CODECS_OBJECT \ CCodecs *codecs = new CCodecs; \ - CMyComPtr __codecsRef = codecs; + CMyComPtr _codecsRef = codecs; #endif #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/OpenArchive.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/OpenArchive.cpp 2022-04-30 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -29,11 +29,11 @@ #include "DefaultName.h" #include "OpenArchive.h" -#ifndef _SFX +#ifndef Z7_SFX #include "SetProperties.h" #endif -#ifndef _SFX +#ifndef Z7_SFX #ifdef SHOW_DEBUG_INFO #define PRF(x) x #else @@ -95,7 +95,7 @@ using namespace NWindows; /* -#ifdef _SFX +#ifdef Z7_SFX #define OPEN_PROPS_PARAM #else #define OPEN_PROPS_PARAM , props @@ -111,7 +111,7 @@ } */ -#ifndef _SFX +#ifndef Z7_SFX namespace NArchive { namespace NParser { @@ -172,23 +172,14 @@ } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) public: CObjectVector _items; UInt64 _maxEndOffset; CMyComPtr _stream; - MY_UNKNOWN_IMP2( - IInArchive, - IInArchiveGetStream) - - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - UInt64 GetLastEnd() const { if (_items.IsEmpty()) @@ -300,7 +291,7 @@ IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN { @@ -311,20 +302,20 @@ COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _items.Clear(); _stream.Release(); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -340,12 +331,12 @@ UString s(sz); if (!item.Name.IsEmpty()) { - s += '.'; + s.Add_Dot(); s += item.Name; } if (!item.Extension.IsEmpty()) { - s += '.'; + s.Add_Dot(); s += item.Extension; } prop = s; break; @@ -359,18 +350,19 @@ case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break; case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break; case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break; + default: break; } prop.Detach(value); return S_OK; COM_TRY_END } -HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (_stream && numItems == 0) @@ -401,35 +393,35 @@ { lps->InSize = totalSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CParseItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) UInt64 unpackSize = item.Size; totalSize += unpackSize; bool skipMode = false; if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) outStreamSpec->SetStream(realOutStream); realOutStream.Release(); outStreamSpec->Init(skipMode ? 0 : unpackSize, true); Int32 opRes = NExtract::NOperationResult::kOK; - RINOK(_stream->Seek((Int64)item.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, item.Offset)) streamSpec->Init(unpackSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) if (outStreamSpec->GetRem() != 0) opRes = NExtract::NOperationResult::kDataError; outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -438,7 +430,7 @@ } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN const CParseItem &item = _items[index]; @@ -454,7 +446,7 @@ { NCOM::CPropVariant prop; result = false; - RINOK(arc->GetProperty(index, propID, &prop)); + RINOK(arc->GetProperty(index, propID, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -486,7 +478,7 @@ { NCOM::CPropVariant prop; result = false; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -498,7 +490,7 @@ { defined = false; NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) switch (prop.vt) { case VT_UI4: result = prop.ulVal; break; @@ -516,7 +508,7 @@ { defined = false; NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) switch (prop.vt) { case VT_UI4: result = prop.ulVal; break; @@ -530,7 +522,7 @@ return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const { @@ -550,14 +542,14 @@ const void *p; UInt32 size; UInt32 propType; - RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)); + RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)) if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) s = (const wchar_t *)p; else #endif { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(curIndex, kpidName, &prop)); + RINOK(Archive->GetProperty(curIndex, kpidName, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) s.SetFromBstr(prop.bstrVal); else if (prop.vt == VT_EMPTY) @@ -568,7 +560,7 @@ UInt32 curParent = (UInt32)(Int32)-1; UInt32 parentType = 0; - RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)); + RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)) // 18.06: fixed : we don't want to split name to parts /* @@ -593,7 +585,7 @@ { { UString &s2 = parts[parts.Size() - 2]; - s2 += ':'; + s2.Add_Colon(); s2 += parts.Back(); } parts.DeleteBack(); @@ -742,7 +734,7 @@ { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidPath, &prop)); + RINOK(Archive->GetProperty(index, kpidPath, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) result.SetFromBstr(prop.bstrVal); else if (prop.vt == VT_EMPTY) @@ -762,15 +754,15 @@ { result.Empty(); bool isDir; - RINOK(Archive_IsItem_Dir(Archive, index, isDir)); + RINOK(Archive_IsItem_Dir(Archive, index, isDir)) if (!isDir) { result = DefaultName; NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidExtension, &prop)); + RINOK(Archive->GetProperty(index, kpidExtension, &prop)) if (prop.vt == VT_BSTR) { - result += '.'; + result.Add_Dot(); result += prop.bstrVal; } else if (prop.vt != VT_EMPTY) @@ -781,11 +773,11 @@ HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const { - RINOK(GetItem_Path(index, result)); + RINOK(GetItem_Path(index, result)) if (Ask_Deleted) { bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)); + RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)) if (isDeleted) result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR); } @@ -830,12 +822,12 @@ item.PathParts.Clear(); - RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); + RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)) item.MainIsDir = item.IsDir; - RINOK(GetItem_Path2(index, item.Path)); + RINOK(GetItem_Path2(index, item.Path)) - #ifndef _SFX + #ifndef Z7_SFX UInt32 mainIndex = index; #endif @@ -844,7 +836,7 @@ item.MainPath = item.Path; if (Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)); + RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)) } bool needFindAltStream = false; @@ -856,11 +848,11 @@ { UInt32 parentType = 0; UInt32 parentIndex; - RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)); + RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)) if (parentType == NParentType::kAltStream) { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidName, &prop)); + RINOK(Archive->GetProperty(index, kpidName, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) item.AltStreamName.SetFromBstr(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -885,8 +877,8 @@ } else { - RINOK(GetItem_Path2(parentIndex, item.MainPath)); - RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); + RINOK(GetItem_Path2(parentIndex, item.MainPath)) + RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)) } } } @@ -908,10 +900,10 @@ #endif - #ifndef _SFX + #ifndef Z7_SFX if (item._use_baseParentFolder_mode) { - RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)); + RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)) #ifdef SUPPORT_ALT_STREAMS if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) @@ -947,14 +939,14 @@ return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined) { NCOM::CPropVariant prop; defined = false; size = 0; - RINOK(archive->GetProperty(index, kpidSize, &prop)); + RINOK(archive->GetProperty(index, kpidSize, &prop)) switch (prop.vt) { case VT_UI1: size = prop.bVal; break; @@ -975,7 +967,7 @@ NCOM::CPropVariant prop; defined = false; size = 0; - RINOK(Archive->GetProperty(index, kpidSize, &prop)); + RINOK(Archive->GetProperty(index, kpidSize, &prop)) switch (prop.vt) { case VT_UI1: size = prop.bVal; break; @@ -993,7 +985,7 @@ { at.Clear(); NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidMTime, &prop)); + RINOK(Archive->GetProperty(index, kpidMTime, &prop)) if (prop.vt == VT_FILETIME) { @@ -1011,7 +1003,7 @@ // (at.Prec == 0) before version 22. // so kpidTimeType is required for that code prop.Clear(); - RINOK(Archive->GetProperty(index, kpidTimeType, &prop)); + RINOK(Archive->GetProperty(index, kpidTimeType, &prop)) if (prop.vt == VT_UI4) { UInt32 val = prop.ulVal; @@ -1038,7 +1030,7 @@ return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) { @@ -1121,7 +1113,7 @@ { if (ai.Flags_PreArc()) return true; - return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats)); + return IsNameFromList(ai.Name, k_PreArcFormats, Z7_ARRAY_SIZE(k_PreArcFormats)); } static const char * const k_Formats_with_simple_signuature[] = @@ -1143,44 +1135,46 @@ // if (ai.Version >= 0x91F) if (ai.NewInterface) return true; - return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature)); + return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, Z7_ARRAY_SIZE(k_Formats_with_simple_signuature)); } -class CArchiveOpenCallback_Offset: + + +class CArchiveOpenCallback_Offset Z7_final: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + public: CMyComPtr Callback; CMyComPtr OpenVolumeCallback; UInt64 Files; UInt64 Offset; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr GetTextPassword; #endif - - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif }; -#ifndef _NO_CRYPTO -STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password) +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (GetTextPassword) @@ -1190,12 +1184,12 @@ } #endif -STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)) { if (!Callback) return S_OK; @@ -1205,7 +1199,7 @@ return Callback->SetCompleted(&Files, &value); } -STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)) { if (OpenVolumeCallback) return OpenVolumeCallback->GetProperty(propID, value); @@ -1214,7 +1208,7 @@ // return E_NOTIMPL; } -STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)) { if (OpenVolumeCallback) return OpenVolumeCallback->GetStream(name, inStream); @@ -1266,32 +1260,32 @@ ErrorInfo.ClearErrors(); { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)); + RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)) ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)); + RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)) ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidError, &prop)); + RINOK(archive->GetArchiveProperty(kpidError, &prop)) if (prop.vt != VT_EMPTY) ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error"); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarning, &prop)); + RINOK(archive->GetArchiveProperty(kpidWarning, &prop)) if (prop.vt != VT_EMPTY) ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning"); } if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) { - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)); + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)) /* RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); if (!OkPhySize_Defined) @@ -1302,7 +1296,7 @@ */ bool offsetDefined; - RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)); + RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)) Int64 globalOffset = (Int64)startPos + Offset; AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); @@ -1338,12 +1332,12 @@ // OutputDebugStringA("a1"); // PrintNumber("formatIndex", formatIndex); - RINOK(op.codecs->CreateInArchive(formatIndex, archive)); + RINOK(op.codecs->CreateInArchive(formatIndex, archive)) // OutputDebugStringA("a2"); if (!archive) return S_OK; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (op.codecs->NeedSetLibCodecs) { const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; @@ -1355,14 +1349,14 @@ archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)) } } } #endif - #ifndef _SFX + #ifndef Z7_SFX const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; @@ -1392,14 +1386,14 @@ } } */ - RINOK(SetProperties(archive, *op.props)); + RINOK(SetProperties(archive, *op.props)) } #endif return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi) { @@ -1407,14 +1401,14 @@ pi.FileTime_Defined = false; pi.ArcType = ai.Name; - RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)); + RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)) // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); pi.IsSelfExe = ai.Flags_PreArc(); { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidMTime, &prop)); + RINOK(archive->GetArchiveProperty(kpidMTime, &prop)) if (prop.vt == VT_FILETIME) { pi.FileTime_Defined = true; @@ -1425,7 +1419,7 @@ if (!pi.FileTime_Defined) { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidCTime, &prop)); + RINOK(archive->GetArchiveProperty(kpidCTime, &prop)) if (prop.vt == VT_FILETIME) { pi.FileTime_Defined = true; @@ -1435,7 +1429,7 @@ { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidName, &prop)); + RINOK(archive->GetArchiveProperty(kpidName, &prop)) if (prop.vt == VT_BSTR) { pi.Name.SetFromBstr(prop.bstrVal); @@ -1443,7 +1437,7 @@ } else { - RINOK(archive->GetArchiveProperty(kpidExtension, &prop)); + RINOK(archive->GetArchiveProperty(kpidExtension, &prop)) if (prop.vt == VT_BSTR) pi.Extension.SetFromBstr(prop.bstrVal); } @@ -1451,14 +1445,14 @@ { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)); + RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)) if (prop.vt == VT_BSTR) pi.Comment.SetFromBstr(prop.bstrVal); } UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) // pi.NumSubFiles = numItems; // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined)); @@ -1499,14 +1493,14 @@ { if (!op.stream) return S_OK; - RINOK(op.stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(op.stream, offset)) const UInt32 kBufSize = 1 << 11; Byte buf[kBufSize]; for (;;) { UInt32 processed = 0; - RINOK(op.stream->Read(buf, kBufSize, &processed)); + RINOK(op.stream->Read(buf, kBufSize, &processed)) if (processed == 0) { // ErrorInfo.NonZerosTail = false; @@ -1527,21 +1521,19 @@ -#ifndef _SFX +#ifndef Z7_SFX -class CExtractCallback_To_OpenCallback: - public IArchiveExtractCallback, - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + CExtractCallback_To_OpenCallback + , IArchiveExtractCallback + , ICompressProgressInfo +) + Z7_IFACE_COM7_IMP(IProgress) public: CMyComPtr Callback; UInt64 Files; UInt64 Offset; - MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo) - INTERFACE_IArchiveExtractCallback(;) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); void Init(IArchiveOpenCallback *callback) { Callback = callback; @@ -1550,17 +1542,17 @@ } }; -STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { @@ -1572,18 +1564,18 @@ return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)) { *outStream = NULL; return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)) { return S_OK; } @@ -1597,30 +1589,31 @@ /* if (needPhySize) { - CMyComPtr open2; - archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpen2, + open2, archive) if (open2) return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback); } */ - RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)); + RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)) if (needPhySize) { bool phySize_Defined = false; UInt64 phySize = 0; - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)); + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)) if (phySize_Defined) return S_OK; bool phySizeCantBeDetected = false; - RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); + RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)) if (!phySizeCantBeDetected) { PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()")); // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize. // But the Handler will know phySize after full archive testing. - RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)); + RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)) PRF(printf("\n-- OK")); } } @@ -1663,7 +1656,7 @@ const UString fileName = ExtractFileNameFromPath(Path); UString extension; { - int dotPos = fileName.ReverseFind_Dot(); + const int dotPos = fileName.ReverseFind_Dot(); if (dotPos >= 0) extension = fileName.Ptr((unsigned)(dotPos + 1)); } @@ -1671,7 +1664,7 @@ CIntVector orderIndices; bool searchMarkerInHandler = false; - #ifdef _SFX + #ifdef Z7_SFX searchMarkerInHandler = true; #endif @@ -1681,25 +1674,25 @@ isMainFormatArr[i] = false; } - UInt64 maxStartOffset = + const UInt64 maxStartOffset = op.openType.MaxStartOffset_Defined ? op.openType.MaxStartOffset : kMaxCheckStartPosition; - #ifndef _SFX + #ifndef Z7_SFX bool isUnknownExt = false; #endif - #ifndef _SFX + #ifndef Z7_SFX bool isForced = false; #endif unsigned numMainTypes = 0; - int formatIndex = op.openType.FormatIndex; + const int formatIndex = op.openType.FormatIndex; if (formatIndex >= 0) { - #ifndef _SFX + #ifndef Z7_SFX isForced = true; #endif orderIndices.Add(formatIndex); @@ -1711,12 +1704,12 @@ else { unsigned numFinded = 0; - #ifndef _SFX + #ifndef Z7_SFX bool isPrearcExt = false; #endif { - #ifndef _SFX + #ifndef Z7_SFX bool isZip = false; bool isRar = false; @@ -1758,13 +1751,13 @@ if (op.excludedFormats->FindInSorted((int)i) >= 0) continue; - #ifndef _SFX + #ifndef Z7_SFX if (IsPreArcFormat(ai)) isPrearcExt = true; #endif if (ai.FindExtension(extension) >= 0 - #ifndef _SFX + #ifndef Z7_SFX || (isZip && ai.Is_Zip()) || (isRar && ai.Is_Rar()) #endif @@ -1795,11 +1788,11 @@ } */ - #ifndef _SFX + #ifndef Z7_SFX if (op.stream && orderIndices.Size() >= 2) { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CByteBuffer byteBuffer; CIntVector orderIndices2; if (numFinded == 0 || IsExeExt(extension)) @@ -1808,13 +1801,13 @@ } else if (extension.IsEqualTo("000") || extension.IsEqualTo("001")) { - int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); + const int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); if (i >= 0) { const size_t kBufSize = (1 << 10); byteBuffer.Alloc(kBufSize); size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize >= 16) { const Byte *buf = byteBuffer; @@ -1834,7 +1827,7 @@ const size_t kBufSize = (1 << 10); byteBuffer.Alloc(kBufSize); size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize == 0) return S_FALSE; @@ -1870,7 +1863,7 @@ FOR_VECTOR (i, orderIndices) { - int val = orderIndices[i]; + const int val = orderIndices[i]; if (val != -1) orderIndices2.Add(val); } @@ -1879,12 +1872,12 @@ if (orderIndices.Size() >= 2) { - int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); - int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); + const int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); + const int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); if (iUdf > iIso && iIso >= 0) { - int isoIndex = orderIndices[(unsigned)iIso]; - int udfIndex = orderIndices[(unsigned)iUdf]; + const int isoIndex = orderIndices[(unsigned)iIso]; + const int udfIndex = orderIndices[(unsigned)iUdf]; orderIndices[(unsigned)iUdf] = isoIndex; orderIndices[(unsigned)iIso] = udfIndex; } @@ -1893,7 +1886,7 @@ numMainTypes = numFinded; isUnknownExt = (numMainTypes == 0) || isPrearcExt; - #else // _SFX + #else // Z7_SFX numMainTypes = orderIndices.Size(); @@ -1907,13 +1900,12 @@ UInt64 fileSize = 0; if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) } FileSize = fileSize; - #ifndef _SFX + #ifndef Z7_SFX CBoolArr skipFrontalFormat(op.codecs->Formats.Size()); { @@ -1945,7 +1937,7 @@ bool exactOnly = false; - #ifndef _SFX + #ifndef Z7_SFX const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; // OutputDebugStringW(ai.Name); @@ -1963,16 +1955,16 @@ // Some handlers do not set total bytes. So we set it here if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) } CMyComPtr archive; - RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) if (!archive) continue; @@ -1991,13 +1983,13 @@ result = openSeq->OpenSeq(op.seqStream); } - RINOK(ReadBasicProps(archive, 0, result)); + RINOK(ReadBasicProps(archive, 0, result)) if (result == S_FALSE) { bool isArc = ErrorInfo.IsArc_After_NonOpen(); - #ifndef _SFX + #ifndef Z7_SFX // if it's archive, we allow another open attempt for parser if (!mode.CanReturnParser || !isArc) skipFrontalFormat[(unsigned)FormatIndex] = true; @@ -2017,7 +2009,7 @@ // if (formatIndex < 0 && !searchMarkerInHandler) { // if bad archive was detected, we don't need additional open attempts - #ifndef _SFX + #ifndef Z7_SFX if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */) #endif return S_FALSE; @@ -2026,7 +2018,7 @@ } /* - #ifndef _SFX + #ifndef Z7_SFX if (IsExeExt(extension) || ai.Flags_PreArc()) { // openOnlyFullArc = false; @@ -2039,9 +2031,9 @@ continue; } - RINOK(result); + RINOK(result) - #ifndef _SFX + #ifndef Z7_SFX bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); @@ -2049,7 +2041,7 @@ bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -2103,7 +2095,7 @@ - #ifndef _SFX + #ifndef Z7_SFX if (!op.stream) return S_FALSE; @@ -2148,9 +2140,9 @@ endOfFile = true; } byteBuffer.Alloc(bufSize); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) processedSize = bufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize == 0) return S_FALSE; if (processedSize < bufSize) @@ -2232,12 +2224,12 @@ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CMyComPtr archive; - RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) if (!archive) continue; @@ -2263,9 +2255,9 @@ // printf(" OpenForSize Error"); continue; } - RINOK(result); + RINOK(result) - RINOK(ReadBasicProps(archive, 0, result)); + RINOK(ReadBasicProps(archive, 0, result)) if (Offset > 0) { @@ -2302,7 +2294,7 @@ if (mode.CanReturnArc) { - bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; + const bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); bool openCur = false; @@ -2312,7 +2304,7 @@ { if (mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) openCur = true; } @@ -2352,7 +2344,7 @@ continue; // printf("\nAdd offset = %d", (int)pi.Offset); - RINOK(ReadParseItemProps(archive, ai, pi)); + RINOK(ReadParseItemProps(archive, ai, pi)) handlerSpec->AddItem(pi); } } @@ -2451,7 +2443,7 @@ // canReturnTailArc = true; } - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream; CMyComPtr limitedStream = limitedStreamSpec; @@ -2465,13 +2457,13 @@ openCallback_Offset = openCallback_Offset_Spec; openCallback_Offset_Spec->Callback = op.callback; openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); #endif } if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) CByteBuffer &byteBuffer = limitedStreamSpec->Buffer; byteBuffer.Alloc(kBufSize); @@ -2509,8 +2501,8 @@ size_t processedSize = kBufSize - bytesInBuf; // printf("\nRead ask = %d", (unsigned)processedSize); UInt64 seekPos = bufPhyPos + bytesInBuf; - RINOK(op.stream->Seek((Int64)(bufPhyPos + bytesInBuf), STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)); + RINOK(InStream_SeekSet(op.stream, bufPhyPos + bytesInBuf)) + RINOK(ReadStream(op.stream, byteBuffer.NonConstData() + bytesInBuf, &processedSize)) // printf(" processed = %d", (unsigned)processedSize); if (processedSize == 0) { @@ -2532,7 +2524,7 @@ { size_t keepSize = (size_t)(kBeforeSize - skipSize); // printf("\nmemmove skip = %d", (int)keepSize); - memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize); + memmove(byteBuffer, byteBuffer.ConstData() + bytesInBuf - keepSize, keepSize); bytesInBuf = keepSize; bufPhyPos = pos - keepSize; continue; @@ -2548,7 +2540,7 @@ { size_t beg = (size_t)posInBuf - kBeforeSize; // printf("\nmemmove for after beg = %d", (int)beg); - memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg); + memmove(byteBuffer, byteBuffer.ConstData() + beg, bytesInBuf - beg); bufPhyPos += beg; bytesInBuf -= beg; continue; @@ -2568,7 +2560,7 @@ if (pos >= callbackPrev + (1 << 23)) { - RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL)); + RINOK(openCallback_Offset->SetCompleted(NULL, NULL)) callbackPrev = pos; } } @@ -2606,14 +2598,14 @@ scanSize++; - const Byte *buf = byteBuffer + (size_t)posInBuf; + const Byte *buf = byteBuffer.ConstData() + (size_t)posInBuf; const Byte *bufLimit = buf + scanSize; size_t ppp = 0; if (!needCheckStartOpen) { for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++); - ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf)); + ppp = (size_t)(buf - (byteBuffer.ConstData() + (size_t)posInBuf)); pos += ppp; if (buf == bufLimit) continue; @@ -2691,10 +2683,10 @@ if (ai.IsArcFunc && startArcPos >= bufPhyPos) { - size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); + const size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); if (offsetInBuf < bytesInBuf) { - UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf); + const UInt32 isArcRes = ai.IsArcFunc(byteBuffer.ConstData() + offsetInBuf, bytesInBuf - offsetInBuf); if (isArcRes == k_IsArc_Res_NO) continue; if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) @@ -2716,7 +2708,7 @@ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); CMyComPtr archive; - RINOK(PrepareToOpen(op, index, archive)); + RINOK(PrepareToOpen(op, index, archive)) if (!archive) return E_FAIL; @@ -2728,12 +2720,12 @@ if (ai.Flags_UseGlobalOffset()) { - limitedStreamSpec->InitAndSeek(0, fileSize); - limitedStream->Seek((Int64)startArcPos, STREAM_SEEK_SET, NULL); + RINOK(limitedStreamSpec->InitAndSeek(0, fileSize)) + RINOK(InStream_SeekSet(limitedStream, startArcPos)) } else { - limitedStreamSpec->InitAndSeek(startArcPos, rem); + RINOK(limitedStreamSpec->InitAndSeek(startArcPos, rem)) arcStreamOffset = startArcPos; } @@ -2755,7 +2747,7 @@ useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, extractCallback_To_OpenCallback); - RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)); + RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)) bool isOpen = false; @@ -2784,7 +2776,7 @@ continue; } isOpen = true; - RINOK(result); + RINOK(result) PRF(printf(" OK ")); } @@ -2874,7 +2866,7 @@ pos = pi.Offset + pi.Size; - RINOK(ReadParseItemProps(archive, ai, pi)); + RINOK(ReadParseItemProps(archive, ai, pi)) if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */) { @@ -2903,7 +2895,7 @@ bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))); + RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -3029,7 +3021,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op) { - RINOK(OpenStream2(op)); + RINOK(OpenStream2(op)) // PrintNumber("op.formatIndex 3", op.formatIndex); if (Archive) @@ -3039,12 +3031,12 @@ Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); - RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)); - RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)); - RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)); - RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)); - RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)); - RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)) const UString fileName = ExtractFileNameFromPath(Path); UString extension; @@ -3074,7 +3066,7 @@ return S_OK; } -#ifdef _SFX +#ifdef Z7_SFX #ifdef _WIN32 #define k_ExeExt ".exe" @@ -3094,7 +3086,12 @@ if (op.stdInMode) { +#if 1 seqStream = new CStdInFileStream; +#else + if (!CreateStdInStream(seqStream)) + return GetLastError_noZero_HRESULT(); +#endif op.seqStream = seqStream; } else if (!op.stream) @@ -3105,7 +3102,7 @@ if (!fileStreamSpec->Open(us2fs(Path))) return GetLastError_noZero_HRESULT(); op.stream = fileStream; - #ifdef _SFX + #ifdef Z7_SFX IgnoreSplit = true; #endif } @@ -3114,7 +3111,7 @@ if (callback) { UInt64 fileSize; - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(op.stream, fileSize)); RINOK(op.callback->SetTotal(NULL, &fileSize)) } */ @@ -3122,7 +3119,7 @@ HRESULT res = OpenStream(op); IgnoreSplit = false; - #ifdef _SFX + #ifdef Z7_SFX if (res != S_FALSE || !fileStreamSpec @@ -3141,7 +3138,7 @@ if (ai.Is_Split()) continue; UString path3 = path2; - path3 += '.'; + path3.Add_Dot(); path3 += ai.GetMainExt(); // "7z" for SFX. Path = path3; Path += ".001"; @@ -3187,7 +3184,7 @@ for (unsigned i = Arcs.Size(); i != 0;) { i--; - RINOK(Arcs[i].Close()); + RINOK(Arcs[i].Close()) } IsOpen = false; // ErrorsText.Empty(); @@ -3320,13 +3317,13 @@ UInt32 mainSubfile; { NCOM::CPropVariant prop; - RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)); + RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)) if (prop.vt == VT_UI4) mainSubfile = prop.ulVal; else break; UInt32 numItems; - RINOK(arc.Archive->GetNumberOfItems(&numItems)); + RINOK(arc.Archive->GetNumberOfItems(&numItems)) if (mainSubfile >= numItems) break; } @@ -3345,16 +3342,17 @@ break; CArc arc2; - RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)); + RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)) bool zerosTailIsAllowed; - RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); + RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)) if (op.callback) { - CMyComPtr setSubArchiveName; - op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenSetSubArchiveName, + setSubArchiveName, op.callback) if (setSubArchiveName) setSubArchiveName->SetSubArchiveName(arc2.Path); } @@ -3365,7 +3363,7 @@ CIntVector excl; COpenOptions op2; - #ifndef _SFX + #ifndef Z7_SFX op2.props = op.props; #endif op2.codecs = op.codecs; @@ -3388,8 +3386,8 @@ NonOpen_ArcPath = arc2.Path; break; } - RINOK(result); - RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)); + RINOK(result) + RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)) Arcs.Add(arc2); } IsOpen = !Arcs.IsEmpty(); @@ -3408,7 +3406,7 @@ if (!op.stream && !op.stdInMode) { NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); - RINOK(openCallbackSpec->Init2(prefix, name)); + RINOK(openCallbackSpec->Init2(prefix, name)) } else { @@ -3423,7 +3421,7 @@ PasswordWasAsked = openCallbackSpec->PasswordWasAsked; // Password = openCallbackSpec->Password; - RINOK(res); + RINOK(res) // VolumePaths.Add(fs2us(prefix + name)); FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed) @@ -3446,8 +3444,9 @@ UInt64 fileSize = 0; if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) + RINOK(InStream_AtBegin_GetSize(op.stream, fileSize)) + // RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) } FileSize = fileSize; @@ -3462,7 +3461,7 @@ tailStreamSpec->Stream = op.stream; tailStreamSpec->Offset = (UInt64)globalOffset; tailStreamSpec->Init(); - RINOK(tailStreamSpec->SeekToStart()); + RINOK(tailStreamSpec->SeekToStart()) } // There are archives with embedded STUBs (like ZIP), so we must support signature scanning @@ -3475,7 +3474,7 @@ if (res == S_OK) { - RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)); + RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)) ArcStreamOffset = (UInt64)globalOffset; if (ArcStreamOffset != 0) InStream = op.stream; @@ -3488,7 +3487,7 @@ HRESULT res = Open2(op, callbackUI); if (callbackUI) { - RINOK(callbackUI->Open_Finished()); + RINOK(callbackUI->Open_Finished()) } return res; } @@ -3508,6 +3507,8 @@ if (Arcs.Size() == 0) // ??? return Open2(op, NULL); + /* if archive is multivolume (unsupported here still) + COpenCallbackImp object will exist after Open stage. */ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; CMyComPtr openCallbackNew = openCallbackSpec; @@ -3516,7 +3517,7 @@ { FString dirPrefix, fileName; NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); - RINOK(openCallbackSpec->Init2(dirPrefix, fileName)); + RINOK(openCallbackSpec->Init2(dirPrefix, fileName)) } @@ -3527,7 +3528,9 @@ op.stream = stream; CArc &arc = Arcs[0]; - HRESULT res = arc.ReOpen(op, openCallbackNew); + const HRESULT res = arc.ReOpen(op, openCallbackNew); + + openCallbackSpec->ReOpenCallback = NULL; PasswordWasAsked = openCallbackSpec->PasswordWasAsked; // Password = openCallbackSpec->Password; @@ -3536,7 +3539,7 @@ return res; } -#ifndef _SFX +#ifndef Z7_SFX bool ParseComplexSize(const wchar_t *s, UInt64 &result); bool ParseComplexSize(const wchar_t *s, UInt64 &result) @@ -3580,6 +3583,7 @@ case 'e': type.EachPos = true; return true; case 'a': type.CanReturnArc = true; return true; case 'r': type.Recursive = true; return true; + default: break; } return false; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/OpenArchive.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/OpenArchive.h 2022-04-07 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/OpenArchive.h 2023-04-06 04:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // OpenArchive.h -#ifndef __OPEN_ARCHIVE_H -#define __OPEN_ARCHIVE_H +#ifndef ZIP7_INC_OPEN_ARCHIVE_H +#define ZIP7_INC_OPEN_ARCHIVE_H #include "../../../Windows/PropVariant.h" @@ -10,7 +10,7 @@ #include "Property.h" #include "DirItem.h" -#ifndef _SFX +#ifndef Z7_SFX #define SUPPORT_ALT_STREAMS @@ -34,7 +34,7 @@ }; */ -#ifdef _SFX +#ifdef Z7_SFX #define OPEN_PROPS_DECL #else #define OPEN_PROPS_DECL const CObjectVector *props; @@ -243,7 +243,7 @@ bool MainIsDir; UInt32 ParentIndex; // use it, if IsAltStream - #ifndef _SFX + #ifndef Z7_SFX bool _use_baseParentFolder_mode; int _baseParentFolder; #endif @@ -254,7 +254,7 @@ WriteToAltStreamIfColon = false; #endif - #ifndef _SFX + #ifndef Z7_SFX _use_baseParentFolder_mode = false; _baseParentFolder = -1; #endif @@ -270,7 +270,7 @@ HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset); HRESULT OpenStream2(const COpenOptions &options); - #ifndef _SFX + #ifndef Z7_SFX // parts.Back() can contain alt stream name "nams:AltName" HRESULT GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; #endif @@ -285,8 +285,17 @@ CMyComPtr GetRawProps; CMyComPtr GetRootProps; - CArcErrorInfo ErrorInfo; // for OK archives - CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) + bool IsParseArc; + + bool IsTree; + bool IsReadOnly; + + bool Ask_Deleted; + bool Ask_AltStream; + bool Ask_Aux; + bool Ask_INode; + + bool IgnoreSplit; // don't try split handler UString Path; UString filePath; @@ -305,7 +314,9 @@ // bool OkPhySize_Defined; UInt64 FileSize; UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file - // bool offsetDefined; + + CArcErrorInfo ErrorInfo; // for OK archives + CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; } @@ -314,18 +325,6 @@ // AString ErrorFlagsText; - bool IsParseArc; - - bool IsTree; - bool IsReadOnly; - - bool Ask_Deleted; - bool Ask_AltStream; - bool Ask_Aux; - bool Ask_INode; - - bool IgnoreSplit; // don't try split handler - // void Set_ErrorFlagsText(); CArc(): @@ -341,8 +340,6 @@ HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes); - // ~CArc(); - HRESULT Close() { InStream.Release(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.cpp 2022-05-13 13:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.cpp 2024-08-08 08:00:00.000000000 +0000 @@ -14,15 +14,15 @@ #include "PropIDUtils.h" -#ifndef _SFX +#ifndef Z7_SFX #define Get16(x) GetUi16(x) #define Get32(x) GetUi32(x) #endif using namespace NWindows; -static const unsigned kNumWinAtrribFlags = 21; -static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEV.X.PU"; +static const unsigned kNumWinAtrribFlags = 30; +static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEVvX.PU.M......B"; /* FILE_ATTRIBUTE_ @@ -48,13 +48,14 @@ 18 RECALL_ON_OPEN or EA 19 PINNED 20 UNPINNED -21 STRICTLY_SEQUENTIAL +21 STRICTLY_SEQUENTIAL (10.0.16267) 22 RECALL_ON_DATA_ACCESS +29 STRICTLY_SEQUENTIAL (10.0.17134+) (SMR Blob) */ static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' }; -#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-'; +#define MY_ATTR_CHAR(a, n, c) (((a) & (1 << (n))) ? c : '-') static void ConvertPosixAttribToString(char *s, UInt32 a) throw() { @@ -83,26 +84,34 @@ { /* some programs store posix attributes in high 16 bits. - p7zip - stores additional 0x8000 flag marker. - macos - stores additional 0x4000 flag marker. - info-zip - no additional marker. + p7zip - stores additional 0x8000 flag marker. + macos - stores additional 0x4000 flag marker. + info-zip - no additional marker. + But this code works with Attrib from internal 7zip code. + So we expect that 0x8000 marker is set, if there are posix attributes. + (DT_UNKNOWN == 0) type in high bits is possible in some case for linux files. + 0x8000 flag is possible also in ReFS (Windows)? */ - - bool isPosix = ((wa & 0xF0000000) != 0); - + + const bool isPosix = ( + (wa & 0x8000) != 0 // FILE_ATTRIBUTE_UNIX_EXTENSION; + // && (wa & 0xFFFF0000u) != 0 + ); + UInt32 posix = 0; if (isPosix) { posix = wa >> 16; - wa &= (UInt32)0x3FFF; + if ((wa & 0xF0000000u) != 0) + wa &= (UInt32)0x3FFF; } for (unsigned i = 0; i < kNumWinAtrribFlags; i++) { - UInt32 flag = (1 << i); - if ((wa & flag) != 0) + const UInt32 flag = (UInt32)1 << i; + if (wa & flag) { - char c = g_WinAttribChars[i]; + const char c = g_WinAttribChars[i]; if (c != '.') { wa &= ~flag; @@ -183,7 +192,7 @@ { if (prop.vt != VT_UI4) break; - UInt32 a = prop.ulVal; + const UInt32 a = prop.ulVal; /* if ((a & 0x8000) && (a & 0x7FFF) == 0) @@ -207,7 +216,7 @@ ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest); dest += strlen(dest); *dest++ = '-'; - UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); + const UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); ConvertUInt64ToString(low, dest); return; } @@ -243,6 +252,7 @@ return; } */ + default: break; } ConvertPropVariantToShortString(prop, dest); @@ -260,17 +270,12 @@ dest = temp; } -#ifndef _SFX - -static inline unsigned GetHex(unsigned v) -{ - return (v < 10) ? ('0' + v) : ('A' + (v - 10)); -} +#ifndef Z7_SFX static inline void AddHexToString(AString &res, unsigned v) { - res += (char)GetHex(v >> 4); - res += (char)GetHex(v & 0xF); + res.Add_Char((char)GET_HEX_CHAR_UPPER(v >> 4)); + res.Add_Char((char)GET_HEX_CHAR_UPPER(v & 15)); } /* @@ -379,41 +384,41 @@ { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" } }; -static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) +static void ParseSid(AString &s, const Byte *p, size_t lim /* , unsigned &sidSize */) { - sidSize = 0; + // sidSize = 0; if (lim < 8) { s += "ERROR"; return; } - UInt32 rev = p[0]; - if (rev != 1) + if (p[0] != 1) // rev { s += "UNSUPPORTED"; return; } - UInt32 num = p[1]; - if (8 + num * 4 > lim) + const unsigned num = p[1]; + const unsigned sidSize_Loc = 8 + num * 4; + if (sidSize_Loc > lim) { s += "ERROR"; return; } - sidSize = 8 + num * 4; - UInt32 authority = GetBe32(p + 4); + // sidSize = sidSize_Loc; + const UInt32 authority = GetBe32(p + 4); if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1) { - UInt32 v0 = Get32(p + 8); - if (v0 < ARRAY_SIZE(sidNames)) + const UInt32 v0 = Get32(p + 8); + if (v0 < Z7_ARRAY_SIZE(sidNames)) { s += sidNames[v0]; return; } if (v0 == 32 && num == 2) { - UInt32 v1 = Get32(p + 12); - int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1); + const UInt32 v1 = Get32(p + 12); + const int index = FindPairIndex(sid_32_Names, Z7_ARRAY_SIZE(sid_32_Names), v1); if (index >= 0) { s += sid_32_Names[(unsigned)index].sz; @@ -423,7 +428,7 @@ if (v0 == 21 && num == 5) { UInt32 v4 = Get32(p + 8 + 4 * 4); - int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4); + const int index = FindPairIndex(sid_21_Names, Z7_ARRAY_SIZE(sid_21_Names), v4); if (index >= 0) { s += sid_21_Names[(unsigned)index].sz; @@ -432,7 +437,7 @@ } if (v0 == 80 && num == 6) { - for (unsigned i = 0; i < ARRAY_SIZE(services_to_name); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(services_to_name); i++) { const CServicesToName &sn = services_to_name[i]; int j; @@ -457,39 +462,39 @@ } for (UInt32 i = 0; i < num; i++) { - s += '-'; + s.Add_Minus(); s.Add_UInt32(Get32(p + 8 + i * 4)); } } -static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos) +static void ParseOwner(AString &s, const Byte *p, size_t size, UInt32 pos) { if (pos > size) { s += "ERROR"; return; } - UInt32 sidSize = 0; - ParseSid(s, p + pos, size - pos, sidSize); + // unsigned sidSize = 0; + ParseSid(s, p + pos, size - pos /* , sidSize */); } -static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset) +static void ParseAcl(AString &s, const Byte *p, size_t size, const char *strName, UInt32 flags, UInt32 offset) { - UInt32 control = Get16(p + 2); + const unsigned control = Get16(p + 2); if ((flags & control) == 0) return; - UInt32 pos = Get32(p + offset); + const UInt32 pos = Get32(p + offset); s.Add_Space(); s += strName; if (pos >= size) return; p += pos; - size -= pos; + size -= (size_t)pos; if (size < 8) return; if (Get16(p) != 2) // revision return; - UInt32 num = Get32(p + 4); + const UInt32 num = Get32(p + 4); s.Add_UInt32(num); /* @@ -547,7 +552,7 @@ #define MY_SE_SELF_RELATIVE (0x8000) */ -void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) +void ConvertNtSecureToString(const Byte *data, size_t size, AString &s) { s.Empty(); if (size < 20 || size > (1 << 18)) @@ -566,44 +571,43 @@ ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12); ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16); s.Add_Space(); - s.Add_UInt32(size); - // s += '\n'; + s.Add_UInt32((UInt32)size); + // s.Add_LF(); // s += Data_To_Hex(data, size); } #ifdef _WIN32 -static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos) throw() +static bool CheckSid(const Byte *data, size_t size, UInt32 pos) throw() { if (pos >= size) return false; size -= pos; if (size < 8) return false; - UInt32 rev = data[pos]; - if (rev != 1) + if (data[pos] != 1) // rev return false; - UInt32 num = data[pos + 1]; + const unsigned num = data[pos + 1]; return (8 + num * 4 <= size); } -static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset) throw() +static bool CheckAcl(const Byte *p, size_t size, UInt32 flags, size_t offset) throw() { - UInt32 control = Get16(p + 2); + const unsigned control = Get16(p + 2); if ((flags & control) == 0) return true; - UInt32 pos = Get32(p + offset); + const UInt32 pos = Get32(p + offset); if (pos >= size) return false; p += pos; size -= pos; if (size < 8) return false; - UInt32 aclSize = Get16(p + 2); + const unsigned aclSize = Get16(p + 2); return (aclSize <= size); } -bool CheckNtSecure(const Byte *data, UInt32 size) throw() +bool CheckNtSecure(const Byte *data, size_t size) throw() { if (size < 20) return false; @@ -653,7 +657,7 @@ { 0x80000026, "LX_BLK" } }; -bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s) +bool ConvertNtReparseToString(const Byte *data, size_t size, UString &s) { s.Empty(); NFile::CReparseAttr attr; @@ -681,27 +685,27 @@ if (attr.MinorError) s += " : MINOR_ERROR"; return true; - // s += " "; // for debug + // s.Add_Space(); // for debug } if (size < 8) return false; - UInt32 tag = Get32(data); - UInt32 len = Get16(data + 4); + const UInt32 tag = Get32(data); + const UInt32 len = Get16(data + 4); if (len + 8 > size) return false; if (Get16(data + 6) != 0) // padding return false; /* - #define _my_IO_REPARSE_TAG_DEDUP (0x80000013L) - if (tag == _my_IO_REPARSE_TAG_DEDUP) + #define my_IO_REPARSE_TAG_DEDUP (0x80000013L) + if (tag == my_IO_REPARSE_TAG_DEDUP) { } */ { - int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag); + const int index = FindPairIndex(k_ReparseTags, Z7_ARRAY_SIZE(k_ReparseTags), tag); if (index >= 0) s += k_ReparseTags[(unsigned)index].sz; else @@ -713,7 +717,7 @@ } } - s += ":"; + s.Add_Colon(); s.Add_UInt32(len); if (len != 0) @@ -729,9 +733,9 @@ s += "..."; break; } - unsigned b = data[i]; - s += (char)GetHex((b >> 4) & 0xF); - s += (char)GetHex(b & 0xF); + const unsigned b = data[i]; + s.Add_Char((char)GET_HEX_CHAR_UPPER(b >> 4)); + s.Add_Char((char)GET_HEX_CHAR_UPPER(b & 15)); } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.h 2017-02-25 11:49:34.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/PropIDUtils.h 2023-09-05 08:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // PropIDUtils.h -#ifndef __PROPID_UTILS_H -#define __PROPID_UTILS_H +#ifndef ZIP7_INC_PROPID_UTILS_H +#define ZIP7_INC_PROPID_UTILS_H #include "../../../Common/MyString.h" @@ -9,9 +9,9 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0) throw(); void ConvertPropertyToString2(UString &dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0); -bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s); -void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s); -bool CheckNtSecure(const Byte *data, UInt32 size) throw();; +bool ConvertNtReparseToString(const Byte *data, size_t size, UString &s); +void ConvertNtSecureToString(const Byte *data, size_t size, AString &s); +bool CheckNtSecure(const Byte *data, size_t size) throw(); void ConvertWinAttribToString(char *s, UInt32 wa) throw(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Property.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Property.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Property.h 2011-01-31 21:05:24.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Property.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Property.h -#ifndef __7Z_PROPERTY_H -#define __7Z_PROPERTY_H +#ifndef ZIP7_INC_7Z_PROPERTY_H +#define ZIP7_INC_7Z_PROPERTY_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/SetProperties.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/SetProperties.cpp 2019-08-24 11:23:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.cpp 2023-09-26 16:00:00.000000000 +0000 @@ -18,7 +18,7 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) { const wchar_t *end; - UInt64 result = ConvertStringToUInt64(s, &end); + const UInt64 result = ConvertStringToUInt64(s, &end); if (*end != 0 || s.IsEmpty()) prop = s; else if (result <= (UInt32)0xFFFFFFFF) @@ -46,8 +46,9 @@ { if (properties.IsEmpty()) return S_OK; - CMyComPtr setProperties; - unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties); + Z7_DECL_CMyComPtr_QI_FROM( + ISetProperties, + setProperties, unknown) if (!setProperties) return S_OK; @@ -64,7 +65,7 @@ { if (!name.IsEmpty()) { - wchar_t c = name.Back(); + const wchar_t c = name.Back(); if (c == L'-') propVariant = false; else if (c == L'+') @@ -82,6 +83,6 @@ for (i = 0; i < realNames.Size(); i++) names.Add((const wchar_t *)realNames[i]); - return setProperties->SetProperties(&names.Front(), values.values, names.Size()); + return setProperties->SetProperties(names.ConstData(), values.values, names.Size()); } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/SetProperties.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/SetProperties.h 2006-02-19 12:09:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SetProperties.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // SetProperties.h -#ifndef __SETPROPERTIES_H -#define __SETPROPERTIES_H +#ifndef ZIP7_INC_SETPROPERTIES_H +#define ZIP7_INC_SETPROPERTIES_H #include "Property.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/SortUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SortUtils.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/SortUtils.h 2014-01-17 07:05:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/SortUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // SortUtils.h -#ifndef __SORT_UTLS_H -#define __SORT_UTLS_H +#ifndef ZIP7_INC_SORT_UTLS_H +#define ZIP7_INC_SORT_UTLS_H #include "../../../Common/MyString.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/StdAfx.h 2013-01-25 07:40:27.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/TempFiles.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/TempFiles.cpp 2015-11-13 16:39:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.cpp 2024-10-15 15:00:00.000000000 +0000 @@ -13,7 +13,8 @@ { while (!Paths.IsEmpty()) { - NDir::DeleteFileAlways(Paths.Back()); + if (NeedDeleteFiles) + NDir::DeleteFileAlways(Paths.Back()); Paths.DeleteBack(); } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/TempFiles.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/TempFiles.h 2013-01-17 09:54:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/TempFiles.h 2024-10-15 15:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // TempFiles.h -#ifndef __TEMP_FILES_H -#define __TEMP_FILES_H +#ifndef ZIP7_INC_TEMP_FILES_H +#define ZIP7_INC_TEMP_FILES_H #include "../../../Common/MyString.h" @@ -10,6 +10,9 @@ void Clear(); public: FStringVector Paths; + bool NeedDeleteFiles; + + CTempFiles(): NeedDeleteFiles(true) {} ~CTempFiles() { Clear(); } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Update.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Update.cpp 2022-04-09 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.cpp 2024-12-30 13:00:00.000000000 +0000 @@ -18,6 +18,8 @@ #include "../../Common/FileStreams.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/MultiOutStream.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" @@ -71,203 +73,44 @@ using namespace NUpdateArchive; -class COutMultiVolStream: - public IOutStream, - public CMyUnknownImp -{ - unsigned _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CAltStreamInfo - { - COutFileStream *StreamSpec; - CMyComPtr Stream; - FString Name; - UInt64 Pos; - UInt64 RealSize; - }; - CObjectVector Streams; -public: - // CMyComPtr VolumeCallback; - CRecordVector Sizes; - FString Prefix; - CTempFiles *TempFiles; - - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - bool SetMTime(const CFiTime *mTime); - HRESULT Close(); - - UInt64 GetSize() const { return _length; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); +struct CMultiOutStream_Rec +{ + CMultiOutStream *Spec; + CMyComPtr Ref; }; -// static NSynchronization::CCriticalSection g_TempPathsCS; - -HRESULT COutMultiVolStream::Close() +struct CMultiOutStream_Bunch { - HRESULT res = S_OK; - FOR_VECTOR (i, Streams) + CObjectVector Items; + + HRESULT Destruct() { - COutFileStream *s = Streams[i].StreamSpec; - if (s) + HRESULT hres = S_OK; + FOR_VECTOR (i, Items) { - HRESULT res2 = s->Close(); - if (res2 != S_OK) - res = res2; + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + { + const HRESULT hres2 = rec.Spec->Destruct(); + if (hres == S_OK) + hres = hres2; + } } + Items.Clear(); + return hres; } - return res; -} -bool COutMultiVolStream::SetMTime(const CFiTime *mTime) -{ - bool res = true; - FOR_VECTOR (i, Streams) + void DisableDeletion() { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - if (!s->SetMTime(mTime)) - res = false; - } - return res; -} - -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - while (size > 0) - { - if (_streamIndex >= Streams.Size()) - { - CAltStreamInfo altStream; - - FString name; - name.Add_UInt32(_streamIndex + 1); - while (name.Len() < 3) - name.InsertAtFront(FTEXT('0')); - name.Insert(0, Prefix); - altStream.StreamSpec = new COutFileStream; - altStream.Stream = altStream.StreamSpec; - if (!altStream.StreamSpec->Create(name, false)) - return GetLastError_noZero_HRESULT(); - { - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); - TempFiles->Paths.Add(name); - } - - altStream.Pos = 0; - altStream.RealSize = 0; - altStream.Name = name; - Streams.Add(altStream); - continue; - } - CAltStreamInfo &altStream = Streams[_streamIndex]; - - unsigned index = _streamIndex; - if (index >= Sizes.Size()) - index = Sizes.Size() - 1; - UInt64 volSize = Sizes[index]; - - if (_offsetPos >= volSize) + FOR_VECTOR (i, Items) { - _offsetPos -= volSize; - _streamIndex++; - continue; + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + rec.Spec->NeedDelete = false; } - if (_offsetPos != altStream.Pos) - { - // CMyComPtr outStream; - // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(altStream.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)); - altStream.Pos = _offsetPos; - } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos); - UInt32 realProcessed; - RINOK(altStream.Stream->Write(data, curSize, &realProcessed)); - data = (const void *)((const Byte *)data + realProcessed); - size -= realProcessed; - altStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (_offsetPos > altStream.RealSize) - altStream.RealSize = _offsetPos; - if (processedSize) - *processedSize += realProcessed; - if (altStream.Pos == volSize) - { - _streamIndex++; - _offsetPos = 0; - } - if (realProcessed == 0 && curSize != 0) - return E_FAIL; - break; } - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - switch (seekOrigin) - { - case STREAM_SEEK_SET: _absPos = (UInt64)offset; break; - case STREAM_SEEK_CUR: _absPos = (UInt64)((Int64)_absPos + offset); break; - case STREAM_SEEK_END: _absPos = (UInt64)((Int64)_length + offset); break; - } - _offsetPos = _absPos; - if (newPosition) - *newPosition = _absPos; - _streamIndex = 0; - return S_OK; -} +}; -STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize) -{ - unsigned i = 0; - while (i < Streams.Size()) - { - CAltStreamInfo &altStream = Streams[i++]; - if ((UInt64)newSize < altStream.RealSize) - { - RINOK(altStream.Stream->SetSize(newSize)); - altStream.RealSize = newSize; - break; - } - newSize -= altStream.RealSize; - } - while (i < Streams.Size()) - { - { - CAltStreamInfo &altStream = Streams.Back(); - altStream.Stream.Release(); - DeleteFileAlways(altStream.Name); - } - Streams.DeleteBack(); - } - _offsetPos = _absPos; - _streamIndex = 0; - _length = newSize; - return S_OK; -} void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) { @@ -305,7 +148,7 @@ UString path = GetPathWithoutExt(); if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += BaseExtension; } return path; @@ -317,7 +160,7 @@ // if BaseExtension is empty, we must ignore VolExtension also. if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += VolExtension; } return path; @@ -329,7 +172,7 @@ path += us2fs(Name); if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += us2fs(BaseExtension); } path += ".tmp"; @@ -403,7 +246,7 @@ } -struct CUpdateProduceCallbackImp: public IUpdateProduceCallback +struct CUpdateProduceCallbackImp Z7_final: public IUpdateProduceCallback { const CObjectVector *_arcItems; CDirItemsStat *_stat; @@ -417,7 +260,7 @@ _stat(stat), _callback(callback) {} - virtual HRESULT ShowDeleteFile(unsigned arcIndex); + virtual HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; }; @@ -499,6 +342,8 @@ int FindAltStreamColon_in_Path(const wchar_t *path); #endif + + static HRESULT Compress( const CUpdateOptions &options, bool isUpdatingItself, @@ -511,6 +356,7 @@ const CDirItems &dirItems, const CDirItem *parentDirItem, CTempFiles &tempFiles, + CMultiOutStream_Bunch &multiStreams, CUpdateErrorInfo &errorInfo, IUpdateCallbackUI *callback, CFinishArchiveStat &st) @@ -530,15 +376,15 @@ } else { - RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)); + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { CMyComPtr setCompressCodecsInfo; outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) } } #endif @@ -548,7 +394,7 @@ throw kUpdateIsNotSupoorted; // we need to set properties to get fileTimeType. - RINOK(SetProperties(outArchive, options.MethodMode.Properties)); + RINOK(SetProperties(outArchive, options.MethodMode.Properties)) NFileTimeType::EEnum fileTimeType; { @@ -580,7 +426,7 @@ */ UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); + RINOK(outArchive->GetFileTimeType(&value)) // we support any future fileType here. fileTimeType = (NFileTimeType::EEnum)value; @@ -628,7 +474,7 @@ CArcToDoStat stat2; - if (options.RenamePairs.Size() != 0) + if (options.RenameMode || options.RenamePairs.Size() != 0) { FOR_VECTOR (i, arcItems) { @@ -661,7 +507,7 @@ if (rp.GetNewPath(false, mainName, dest)) { needRename = true; - dest += ':'; + dest.Add_Colon(); dest += ai.Name.Ptr((unsigned)(colonPos + 1)); break; } @@ -676,7 +522,7 @@ if (needRename) { up2.NewProps = true; - RINOK(arc->IsItem_Anti(i, up2.IsAnti)); + RINOK(arc->IsItem_Anti(i, up2.IsAnti)) up2.NewNameIndex = (int)newNames.Add(dest); } updatePairs2.Add(up2); @@ -768,7 +614,7 @@ } } } - RINOK(callback->SetNumItems(stat2)); + RINOK(callback->SetNumItems(stat2)) } CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; @@ -828,7 +674,7 @@ COutFileStream *outStreamSpec = NULL; CStdOutFileStream *stdOutFileStreamSpec = NULL; - COutMultiVolStream *volStreamSpec = NULL; + CMultiOutStream *volStreamSpec = NULL; if (options.VolumesSizes.Size() == 0) { @@ -858,7 +704,7 @@ } else realPath = us2fs(archivePath.GetFinalPath()); - if (outStreamSpec->Create(realPath, false)) + if (outStreamSpec->Create_NEW(realPath)) { tempFiles.Paths.Add(realPath); isOK = true; @@ -881,14 +727,17 @@ if (arc && arc->GetGlobalOffset() > 0) return E_NOTIMPL; - volStreamSpec = new COutMultiVolStream; + volStreamSpec = new CMultiOutStream(); outSeekStream = volStreamSpec; outStream = outSeekStream; - volStreamSpec->Sizes = options.VolumesSizes; volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); - volStreamSpec->Prefix += '.'; - volStreamSpec->TempFiles = &tempFiles; - volStreamSpec->Init(); + volStreamSpec->Prefix.Add_Dot(); + volStreamSpec->Init(options.VolumesSizes); + { + CMultiOutStream_Rec &rec = multiStreams.Items.AddNew(); + rec.Spec = volStreamSpec; + rec.Ref = rec.Spec; + } /* updateCallbackSpec->VolumesSizes = volumesSizes; @@ -913,22 +762,22 @@ { outStreamSpec2 = new COutFileStream; sfxOutStream = outStreamSpec2; - FString realPath = us2fs(archivePath.GetFinalPath()); - if (!outStreamSpec2->Create(realPath, false)) + const FString realPath = us2fs(archivePath.GetFinalPath()); + if (!outStreamSpec2->Create_NEW(realPath)) return errorInfo.SetFromLastError("cannot open file", realPath); } { UInt64 sfxSize; - RINOK(sfxStreamSpec->GetSize(&sfxSize)); - RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)); + RINOK(sfxStreamSpec->GetSize(&sfxSize)) + RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)) } - RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)); + RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)) if (outStreamSpec2) { - RINOK(outStreamSpec2->Close()); + RINOK(outStreamSpec2->Close()) } } @@ -939,8 +788,8 @@ else { // Int64 globalOffset = arc->GetGlobalOffset(); - RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)); + RINOK(InStream_SeekToBegin(arc->InStream)) + RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)) if (options.StdOutMode) tailStream = outStream; else @@ -953,24 +802,67 @@ } } + CFiTime ft; + FiTime_Clear(ft); + bool ft_Defined = false; + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &pair2 = updatePairs2[i]; + CFiTime ft2; + FiTime_Clear(ft2); + bool ft2_Defined = false; + /* we use full precision of dirItem, if dirItem is defined + and (dirItem will be used or dirItem is sameTime in dir and arc */ + if (pair2.DirIndex >= 0 && + (pair2.NewProps || pair2.IsSameTime)) + { + ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; + ft2_Defined = true; + } + else if (pair2.UseArcProps && pair2.ArcIndex >= 0) + { + const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; + if (arcItem.MTime.Def) + { + arcItem.MTime.Write_To_FiTime(ft2); + ft2_Defined = true; + } + } + if (ft2_Defined) + { + if (!ft_Defined || Compare_FiTime(&ft, &ft2) < 0) + { + ft = ft2; + ft_Defined = true; + } + } + } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ + } + + if (volStreamSpec && options.SetArcMTime && ft_Defined) + { + volStreamSpec->MTime = ft; + volStreamSpec->MTime_Defined = true; + } HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); // callback->Finalize(); - RINOK(result); + RINOK(result) if (!updateCallbackSpec->AreAllFilesClosed()) { - errorInfo.Message = "There are unclosed input file:"; + errorInfo.Message = "There are unclosed input files:"; errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths; return E_FAIL; } if (options.SetArcMTime) { - CFiTime ft; - FiTime_Clear(ft); - bool isDefined = false; - // bool needNormalizeAfterStream; // needParse; /* @@ -990,40 +882,9 @@ // CArcTime at = StreamCallback_ArcMTime; // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); // we must normalize with precision from archive; - ft = updateCallbackSpec->LatestMTime; - isDefined = true; - } - - FOR_VECTOR (i, updatePairs2) - { - const CUpdatePair2 &pair2 = updatePairs2[i]; - CFiTime ft2; - bool ft2_Defined = false; - /* we use full precision of dirItem, if dirItem is defined - and (dirItem will be used or dirItem is sameTime in dir and arc */ - if (pair2.DirIndex >= 0 && - (pair2.NewProps || pair2.IsSameTime)) - { - ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; - ft2_Defined = true; - } - else if (pair2.UseArcProps && pair2.ArcIndex >= 0) - { - const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; - if (arcItem.MTime.Def) - { - arcItem.MTime.Write_To_FiTime(ft2); - ft2_Defined = true; - } - } - if (ft2_Defined) - { - if (Compare_FiTime(&ft, &ft2) < 0) - { - ft = ft2; - isDefined = true; - } - } + if (!ft_Defined || Compare_FiTime(&ft, &updateCallbackSpec->LatestMTime) < 0) + ft = updateCallbackSpec->LatestMTime; + ft_Defined = true; } /* if (fileTimeType != NFileTimeType::kNotDefined) @@ -1031,12 +892,14 @@ */ } // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) - if (isDefined) + if (ft_Defined) { + // we ignore set time errors here. + // note that user could move some finished volumes to another folder. if (outStreamSpec) outStreamSpec->SetMTime(&ft); else if (volStreamSpec) - volStreamSpec->SetMTime(&ft); + volStreamSpec->SetMTime_Final(ft); } } @@ -1056,7 +919,10 @@ if (outStreamSpec) result = outStreamSpec->Close(); else if (volStreamSpec) - result = volStreamSpec->Close(); + { + result = volStreamSpec->FinalFlush_and_CloseFiles(st.NumVolumes); + st.IsMultiVolMode = true; + } RINOK(result) @@ -1121,7 +987,7 @@ arcItems.Clear(); UInt32 numItems; IInArchive *archive = arc.Archive; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) arcItems.ClearAndReserve(numItems); CReadArcItem item; @@ -1132,7 +998,7 @@ { CArcItem ai; - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) ai.Name = item.Path; ai.IsDir = item.IsDir; ai.IsAltStream = @@ -1152,8 +1018,8 @@ ai.Censored = Censor_CheckPath(censor, item); // ai.MTime will be set to archive MTime, if not present in archive item - RINOK(arc.GetItem_MTime(i, ai.MTime)); - RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)); + RINOK(arc.GetItem_MTime(i, ai.MTime)) + RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)) ai.IndexInServer = i; arcItems.AddInReserved(ai); @@ -1163,10 +1029,97 @@ #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else #include - #endif +extern "C" { + +#ifdef MAPI_FORCE_UNICODE + +#define Z7_WIN_LPMAPISENDMAILW LPMAPISENDMAILW +#define Z7_WIN_MapiFileDescW MapiFileDescW +#define Z7_WIN_MapiMessageW MapiMessageW +#define Z7_WIN_MapiRecipDescW MapiRecipDescW + +#else + +typedef struct +{ + ULONG ulReserved; + ULONG ulRecipClass; + PWSTR lpszName; + PWSTR lpszAddress; + ULONG ulEIDSize; + PVOID lpEntryID; +} Z7_WIN_MapiRecipDescW, *Z7_WIN_lpMapiRecipDescW; + +typedef struct +{ + ULONG ulReserved; + ULONG flFlags; + ULONG nPosition; + PWSTR lpszPathName; + PWSTR lpszFileName; + PVOID lpFileType; +} Z7_WIN_MapiFileDescW, *Z7_WIN_lpMapiFileDescW; + +typedef struct +{ + ULONG ulReserved; + PWSTR lpszSubject; + PWSTR lpszNoteText; + PWSTR lpszMessageType; + PWSTR lpszDateReceived; + PWSTR lpszConversationID; + FLAGS flFlags; + Z7_WIN_lpMapiRecipDescW lpOriginator; + ULONG nRecipCount; + Z7_WIN_lpMapiRecipDescW lpRecips; + ULONG nFileCount; + Z7_WIN_lpMapiFileDescW lpFiles; +} Z7_WIN_MapiMessageW, *Z7_WIN_lpMapiMessageW; + +typedef ULONG (FAR PASCAL Z7_WIN_MAPISENDMAILW)( + LHANDLE lhSession, + ULONG_PTR ulUIParam, + Z7_WIN_lpMapiMessageW lpMessage, + FLAGS flFlags, + ULONG ulReserved +); +typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; + +#endif // MAPI_FORCE_UNICODE +} +#endif // _WIN32 + + +struct C_CopyFileProgress_to_IUpdateCallbackUI2 Z7_final: + public ICopyFileProgress +{ + IUpdateCallbackUI2 *Callback; + HRESULT CallbackResult; + // bool Disable_Break; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + const HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // if (Disable_Break && res == E_ABORT) res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_IUpdateCallbackUI2( + IUpdateCallbackUI2 *callback) : + Callback(callback), + CallbackResult(S_OK) + // , Disable_Break(false) + {} +}; + + HRESULT UpdateArchive( CCodecs *codecs, const CObjectVector &types, @@ -1253,8 +1206,7 @@ if (!options.VolumesSizes.IsEmpty()) { arcPath = options.ArchivePath.GetFinalVolPath(); - arcPath += '.'; - arcPath += "001"; + arcPath += ".001"; } if (cmdArcPath2.IsEmpty()) @@ -1268,7 +1220,7 @@ if (!fi.Find_FollowLink(us2fs(arcPath))) { if (renameMode) - throw "can't find archive";; + throw "can't find archive"; if (options.MethodMode.Type.FormatIndex < 0) { if (!options.SetArcPath(codecs, cmdArcPath2)) @@ -1319,7 +1271,7 @@ CIntVector excl; COpenOptions op; - #ifndef _SFX + #ifndef Z7_SFX op.props = &options.MethodMode.Properties; #endif op.codecs = codecs; @@ -1329,7 +1281,7 @@ op.stream = NULL; op.filePath = arcPath; - RINOK(callback->StartOpenArchive(arcPath)); + RINOK(callback->StartOpenArchive(arcPath)) HRESULT result = arcLink.Open_Strict(op, openCallback); @@ -1341,8 +1293,8 @@ if (result == S_FALSE) return E_FAIL; */ - RINOK(res2); - RINOK(result); + RINOK(res2) + RINOK(result) if (arcLink.VolumePaths.Size() > 1) { @@ -1383,7 +1335,7 @@ return E_NOTIMPL; } - bool thereIsInArchive = arcLink.IsOpen; + const bool thereIsInArchive = arcLink.IsOpen; if (!thereIsInArchive && renameMode) return E_FAIL; @@ -1403,12 +1355,14 @@ if (options.StdInMode) { CDirItem di; - di.ClearBase(); + // di.ClearBase(); + // di.Size = (UInt64)(Int64)-1; + if (!di.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); di.Name = options.StdInFileName; - di.Size = (UInt64)(Int64)-1; - di.SetAsFile(); - NTime::GetCurUtc_FiTime(di.MTime); - di.CTime = di.ATime = di.MTime; + // di.Attrib_IsDefined = false; + // NTime::GetCurUtc_FiTime(di.MTime); + // di.CTime = di.ATime = di.MTime; dirItems.Items.Add(di); } else @@ -1422,7 +1376,7 @@ if (needScanning) { - RINOK(callback->StartScanning()); + RINOK(callback->StartScanning()) dirItems.SymLinks = options.SymLinks.Val; @@ -1452,7 +1406,7 @@ return res; } - RINOK(callback->FinishScanning(dirItems.Stat)); + RINOK(callback->FinishScanning(dirItems.Stat)) // 22.00: we don't need parent folder, if absolute path mode if (options.PathMode != NWildcard::k_AbsPath) @@ -1460,7 +1414,7 @@ { NFind::CFileInfo fi; FString prefix = us2fs(censor.Pairs[0].Prefix); - prefix += '.'; + prefix.Add_Dot(); // UString prefix = censor.Pairs[0].Prefix; /* if (prefix.Back() == WCHAR_PATH_SEPARATOR) @@ -1576,7 +1530,7 @@ { RINOK(EnumerateInArchiveItems( // options.StoreAltStreams, - censor, arcLink.Arcs.Back(), arcItems)); + censor, arcLink.Arcs.Back(), arcItems)) } /* @@ -1595,8 +1549,10 @@ processedItems[i] = 0; } + CMultiOutStream_Bunch multiStreams; + /* - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (arcLink.PasswordWasAsked) { // We set password, if open have requested password @@ -1640,19 +1596,30 @@ parentDirItem_Ptr, tempFiles, - errorInfo, callback, st)); + multiStreams, + errorInfo, callback, st)) - RINOK(callback->FinishArchive(st)); + RINOK(callback->FinishArchive(st)) } if (thereIsInArchive) { - RINOK(arcLink.Close()); + RINOK(arcLink.Close()) arcLink.Release(); } - tempFiles.Paths.Clear(); + multiStreams.DisableDeletion(); + RINOK(multiStreams.Destruct()) + + // here we disable deleting of temp archives. + // note: archive moving can fail, or it can be interrupted, + // if we move new temp update from another volume. + // And we still want to keep temp archive in that case, + // because we will have deleted original archive. + tempFiles.NeedDeleteFiles = false; + // tempFiles.Paths.Clear(); + if (createTempFile) { try @@ -1667,13 +1634,52 @@ if (!DeleteFileAlways(us2fs(arcPath))) return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); } - - if (!MyMoveFile(tempPath, us2fs(arcPath))) + + UInt64 totalArcSize = 0; { - errorInfo.SetFromLastError("cannot move the file", tempPath); + NFind::CFileInfo fi; + if (fi.Find(tempPath)) + totalArcSize = fi.Size; + } + RINOK(callback->MoveArc_Start(fs2us(tempPath), arcPath, + totalArcSize, BoolToInt(thereIsInArchive))) + + C_CopyFileProgress_to_IUpdateCallbackUI2 prox(callback); + // if we update archive, we have removed original archive. + // So if we break archive moving, we will have only temporary archive. + // We can disable breaking here: + // prox.Disable_Break = thereIsInArchive; + + if (!MyMoveFile_with_Progress(tempPath, us2fs(arcPath), &prox)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = "cannot move the file"; + if (errorInfo.SystemError == ERROR_INVALID_PARAMETER) + { + if (totalArcSize > (UInt32)(Int32)-1) + { + // bool isFsDetected = false; + // if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected) + { + errorInfo.Message.Add_LF(); + errorInfo.Message += "Archive file size exceeds 4 GB"; + } + } + } + // if there was no input archive, and we have operation breaking. + // then we can remove temporary archive, because we still have original uncompressed files. + if (!thereIsInArchive + && prox.CallbackResult == E_ABORT) + tempFiles.NeedDeleteFiles = true; + errorInfo.FileNames.Add(tempPath); errorInfo.FileNames.Add(us2fs(arcPath)); + RINOK(prox.CallbackResult) return errorInfo.Get_HRESULT_Error(); } + + // MoveArc_Finish() can return delayed user break (E_ABORT) status, + // if callback callee ignored interruption to finish archive creation operation. + RINOK(callback->MoveArc_Finish()) /* if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) @@ -1692,6 +1698,8 @@ #if defined(_WIN32) && !defined(UNDER_CE) + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION if (options.EMailMode) { @@ -1702,6 +1710,19 @@ return errorInfo.Get_HRESULT_Error(); } + FStringVector fullPaths; + unsigned i; + + for (i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + const FString finalPath = us2fs(ap.GetFinalPath()); + FString arcPath2; + if (!MyGetFullPathName(finalPath, arcPath2)) + return errorInfo.SetFromLastError("GetFullPathName error", finalPath); + fullPaths.Add(arcPath2); + } + /* LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); if (fnSend == 0) @@ -1710,25 +1731,70 @@ return errorInfo.Get_HRESULT_Error(); } */ + const + Z7_WIN_LPMAPISENDMAILW sendMailW = Z7_GET_PROC_ADDRESS( + Z7_WIN_LPMAPISENDMAILW, mapiLib.Get_HMODULE(), + "MAPISendMailW"); + if (sendMailW) + { + + CCurrentDirRestorer curDirRestorer; + + UStringVector paths; + UStringVector names; - LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)(void *)mapiLib.GetProc("MAPISendMail"); - if (sendMail == 0) + for (i = 0; i < fullPaths.Size(); i++) { - errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); - return errorInfo.Get_HRESULT_Error();; + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(arcPath2); + names.Add(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); } - FStringVector fullPaths; - unsigned i; + CRecordVector files; + files.ClearAndSetSize(paths.Size()); - for (i = 0; i < options.Commands.Size(); i++) + for (i = 0; i < paths.Size(); i++) { - CArchivePath &ap = options.Commands[i].ArchivePath; - FString finalPath = us2fs(ap.GetFinalPath()); - FString arcPath2; - if (!MyGetFullPathName(finalPath, arcPath2)) - return errorInfo.SetFromLastError("GetFullPathName error", finalPath); - fullPaths.Add(arcPath2); + Z7_WIN_MapiFileDescW &f = files[i]; + memset(&f, 0, sizeof(f)); + f.nPosition = 0xFFFFFFFF; + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { + Z7_WIN_MapiMessageW m; + memset(&m, 0, sizeof(m)); + m.nFileCount = files.Size(); + m.lpFiles = files.NonConstData(); + + const UString addr (options.EMailAddress); + Z7_WIN_MapiRecipDescW rec; + if (!addr.IsEmpty()) + { + memset(&rec, 0, sizeof(rec)); + rec.ulRecipClass = MAPI_TO; + rec.lpszAddress = addr.Ptr_non_const(); + m.nRecipCount = 1; + m.lpRecips = &rec; + } + + sendMailW((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); + } + } + else + { + const + LPMAPISENDMAIL sendMail = Z7_GET_PROC_ADDRESS( + LPMAPISENDMAIL, mapiLib.Get_HMODULE(), + "MAPISendMail"); + if (!sendMail) + { + errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); + return errorInfo.Get_HRESULT_Error(); } CCurrentDirRestorer curDirRestorer; @@ -1764,7 +1830,7 @@ MapiMessage m; memset(&m, 0, sizeof(m)); m.nFileCount = files.Size(); - m.lpFiles = &files.Front(); + m.lpFiles = files.NonConstData(); const AString addr (GetAnsiString(options.EMailAddress)); MapiRecipDesc rec; @@ -1779,6 +1845,7 @@ sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); } + } } #endif @@ -1827,7 +1894,7 @@ && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) { - RINOK(callback->DeletingAfterArchiving(phyPath, false)); + RINOK(callback->DeletingAfterArchiving(phyPath, false)) DeleteFileAlways(phyPath); } } @@ -1852,12 +1919,12 @@ const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); if (NFind::DoesDirExist(phyPath)) { - RINOK(callback->DeletingAfterArchiving(phyPath, true)); - RemoveDir(phyPath); + RINOK(callback->DeletingAfterArchiving(phyPath, true)) + RemoveDirAlways_if_Empty(phyPath); } } - RINOK(callback->FinishDeletingAfterArchiving()); + RINOK(callback->FinishDeletingAfterArchiving()) } return S_OK; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/Update.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/Update.h 2022-02-24 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/Update.h 2024-12-30 13:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // Update.h -#ifndef __COMMON_UPDATE_H -#define __COMMON_UPDATE_H +#ifndef ZIP7_INC_COMMON_UPDATE_H +#define ZIP7_INC_COMMON_UPDATE_H #include "../../../Common/Wildcard.h" @@ -12,8 +12,6 @@ #include "UpdateAction.h" #include "UpdateCallback.h" -#include "DirItem.h" - enum EArcNameMode { k_ArcNameMode_Smart, @@ -34,7 +32,7 @@ FString TempPrefix; // path(folder) for temp location FString TempPostfix; - CArchivePath(): Temp(false) {}; + CArchivePath(): Temp(false) {} void ParseFromPath(const UString &path, EArcNameMode mode); UString GetPathWithoutExt() const { return Prefix + Name; } @@ -81,31 +79,22 @@ struct CUpdateOptions { - CCompressionMethodMode MethodMode; - - CObjectVector Commands; bool UpdateArchiveItself; - CArchivePath ArchivePath; - EArcNameMode ArcNameMode; - bool SfxMode; - FString SfxModule; - + bool PreserveATime; bool OpenShareForWrite; bool StopAfterOpenError; bool StdInMode; - UString StdInFileName; bool StdOutMode; - + bool EMailMode; bool EMailRemoveAfter; - UString EMailAddress; - FString WorkingDir; - NWildcard::ECensorPathMode PathMode; - // UString AddPathPrefix; + bool DeleteAfterCompressing; + bool SetArcMTime; + bool RenameMode; CBoolPair NtSecurity; CBoolPair AltStreams; @@ -115,19 +104,28 @@ CBoolPair StoreOwnerId; CBoolPair StoreOwnerName; - bool DeleteAfterCompressing; + EArcNameMode ArcNameMode; + NWildcard::ECensorPathMode PathMode; - bool SetArcMTime; + CCompressionMethodMode MethodMode; + + CObjectVector Commands; + CArchivePath ArchivePath; + + FString SfxModule; + UString StdInFileName; + UString EMailAddress; + FString WorkingDir; + // UString AddPathPrefix; CObjectVector RenamePairs; + CRecordVector VolumesSizes; bool InitFormatIndex(const CCodecs *codecs, const CObjectVector &types, const UString &arcPath); bool SetArcPath(const CCodecs *codecs, const UString &arcPath); CUpdateOptions(): UpdateArchiveItself(true), - ArcNameMode(k_ArcNameMode_Smart), - SfxMode(false), PreserveATime(false), @@ -140,12 +138,14 @@ EMailMode(false), EMailRemoveAfter(false), - PathMode(NWildcard::k_RelatPath), - DeleteAfterCompressing(false), - SetArcMTime(false) + SetArcMTime(false), + RenameMode(false), - {}; + ArcNameMode(k_ArcNameMode_Smart), + PathMode(NWildcard::k_RelatPath) + + {} void SetActionCommand_Add() { @@ -154,10 +154,9 @@ c.ActionSet = NUpdateArchive::k_ActionSet_Add; Commands.Add(c); } - - CRecordVector VolumesSizes; }; + struct CUpdateErrorInfo { DWORD SystemError; // it's DWORD (WRes) only; @@ -170,32 +169,43 @@ HRESULT SetFromLastError(const char *message, const FString &fileName); HRESULT SetFromError_DWORD(const char *message, const FString &fileName, DWORD error); - CUpdateErrorInfo(): SystemError(0) {}; + CUpdateErrorInfo(): SystemError(0) {} }; struct CFinishArchiveStat { UInt64 OutArcFileSize; + unsigned NumVolumes; + bool IsMultiVolMode; - CFinishArchiveStat(): OutArcFileSize(0) {} + CFinishArchiveStat(): OutArcFileSize(0), NumVolumes(0), IsMultiVolMode(false) {} }; -#define INTERFACE_IUpdateCallbackUI2(x) \ - INTERFACE_IUpdateCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT StartOpenArchive(const wchar_t *name) x; \ - virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \ - virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x; \ - virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x; \ - virtual HRESULT FinishDeletingAfterArchiving() x; \ +Z7_PURE_INTERFACES_BEGIN + +// INTERFACE_IUpdateCallbackUI(x) +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IUpdateCallbackUI2(x) \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT StartOpenArchive(const wchar_t *name) x \ + virtual HRESULT StartArchive(const wchar_t *name, bool updating) x \ + virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \ + virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \ + virtual HRESULT FinishDeletingAfterArchiving() x \ + virtual HRESULT MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode) x \ + virtual HRESULT MoveArc_Progress(UInt64 total, UInt64 current) x \ + virtual HRESULT MoveArc_Finish() x \ -struct IUpdateCallbackUI2: public IUpdateCallbackUI, public IDirItemsCallback +DECLARE_INTERFACE(IUpdateCallbackUI2): + public IUpdateCallbackUI, + public IDirItemsCallback { - INTERFACE_IUpdateCallbackUI2(=0) + Z7_IFACE_PURE(IUpdateCallbackUI2) }; +Z7_PURE_INTERFACES_END HRESULT UpdateArchive( CCodecs *codecs, diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateAction.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateAction.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateAction.h 2015-08-01 08:55:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateAction.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdateAction.h -#ifndef __UPDATE_ACTION_H -#define __UPDATE_ACTION_H +#ifndef ZIP7_INC_UPDATE_ACTION_H +#define ZIP7_INC_UPDATE_ACTION_H namespace NUpdateArchive { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.cpp 2022-07-12 14:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.cpp 2025-06-18 12:00:00.000000000 +0000 @@ -7,17 +7,17 @@ #ifndef _WIN32 // #include // #include - // for major()/minor(): -#if defined(__FreeBSD__) || defined(BSD) +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else #include #endif -#endif +#endif // _WIN32 -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -32,18 +32,19 @@ #include "../../../Windows/PropVariant.h" #include "../../Common/StreamObjects.h" +#include "../../Archive/Common/ItemNameUtils.h" #include "UpdateCallback.h" #if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif using namespace NWindows; using namespace NFile; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -51,25 +52,11 @@ #endif -#ifdef _USE_SECURITY_CODE +#ifdef Z7_USE_SECURITY_CODE bool InitLocalPrivileges(); #endif CArchiveUpdateCallback::CArchiveUpdateCallback(): - _hardIndex_From((UInt32)(Int32)-1), - - Callback(NULL), - - DirItems(NULL), - ParentDirItem(NULL), - - Arc(NULL), - ArcItems(NULL), - UpdatePairs(NULL), - NewNames(NULL), - CommentIndex(-1), - Comment(NULL), - PreserveATime(false), ShareForWrite(false), StopAfterOpenError(false), @@ -92,29 +79,42 @@ Need_LatestMTime(false), LatestMTime_Defined(false), - ProcessedItemsStatuses(NULL) + Callback(NULL), + + DirItems(NULL), + ParentDirItem(NULL), + + Arc(NULL), + ArcItems(NULL), + UpdatePairs(NULL), + NewNames(NULL), + Comment(NULL), + CommentIndex(-1), + + ProcessedItemsStatuses(NULL), + _hardIndex_From((UInt32)(Int32)-1) { - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 size)) { COM_TRY_BEGIN return Callback->SetTotal(size); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)) { COM_TRY_BEGIN return Callback->SetCompleted(completeValue); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { COM_TRY_BEGIN return Callback->SetRatioInfo(inSize, outSize); @@ -135,17 +135,17 @@ { NULL, kpidIsAnti, VT_BOOL} }; -STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) +Z7_COM7F_IMF(CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) { - return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator); + return CStatPropEnumerator::CreateEnumerator(kProps, Z7_ARRAY_SIZE(kProps), enumerator); } */ -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, - Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) { COM_TRY_BEGIN - RINOK(Callback->CheckBreak()); + RINOK(Callback->CheckBreak()) const CUpdatePair2 &up = (*UpdatePairs)[index]; if (newData) *newData = BoolToInt(up.NewData); if (newProps) *newProps = BoolToInt(up.NewProps); @@ -160,7 +160,7 @@ } -STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -171,19 +171,20 @@ case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break; case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break; case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break; + default: break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; if (StoreNtSecurity) @@ -191,25 +192,27 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = kpidNtSecure; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID - #ifdef _USE_SECURITY_CODE +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootRawProp(PROPID propID - #endif - , const void **data, UInt32 *dataSize, UInt32 *propType) + , const void **data, UInt32 *dataSize, UInt32 *propType)) { - *data = 0; + #ifndef Z7_USE_SECURITY_CODE + UNUSED_VAR(propID) + #endif + + *data = NULL; *dataSize = 0; *propType = 0; if (!StoreNtSecurity) return S_OK; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (propID == kpidNtSecure) { if (StdInMode) @@ -233,12 +236,10 @@ return S_OK; } -// #ifdef _USE_SECURITY_CODE -// #endif -STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { - *data = 0; + *data = NULL; *dataSize = 0; *propType = 0; @@ -265,7 +266,7 @@ const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; #endif - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (propID == kpidNtSecure) { if (!StoreNtSecurity) @@ -306,7 +307,7 @@ #if defined(_WIN32) && !defined(UNDER_CE) -static UString GetRelativePath(const UString &to, const UString &from) +static UString GetRelativePath(const UString &to, const UString &from, bool isWSL) { UStringVector partsTo, partsFrom; SplitPathToParts(to, partsTo); @@ -324,11 +325,12 @@ if (i == 0) { - #ifdef _WIN32 - if (NName::IsDrivePath(to) || - NName::IsDrivePath(from)) +#ifdef _WIN32 + if (isWSL || + (NName::IsDrivePath(to) || + NName::IsDrivePath(from))) return to; - #endif +#endif } UString s; @@ -349,7 +351,7 @@ #endif -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN const CUpdatePair2 &up = (*UpdatePairs)[index]; @@ -373,54 +375,87 @@ return S_OK; } - #if !defined(UNDER_CE) - +#if !defined(UNDER_CE) if (up.DirIndex >= 0) { const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; - - #ifdef _WIN32 - // if (di.IsDir()) + if (di.ReparseData.Size()) { +#ifdef _WIN32 CReparseAttr attr; if (attr.Parse(di.ReparseData, di.ReparseData.Size())) { - UString simpleName = attr.GetPath(); - if (!attr.IsSymLink_WSL() && attr.IsRelative_Win()) - prop = simpleName; - else + UString path = attr.GetPath(); + if (!path.IsEmpty()) { - const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex); - FString fullPath; - if (NDir::MyGetFullPathName(phyPath, fullPath)) + bool isWSL = attr.IsSymLink_WSL(); + if (isWSL) + NArchive::NItemName::ReplaceToWinSlashes(path, true); // useBackslashReplacement + // it's expected that (path) now uses windows slashes. + // CReparseAttr::IsRelative_Win() returns true if FLAG_RELATIVE is set + // CReparseAttr::IsRelative_Win() returns true for "\dir1\path" + // but we want to store real relative paths without "\" root prefix. + // so we parse path instead of IsRelative_Win() calling. + if (// attr.IsRelative_Win() || + (isWSL ? + IS_PATH_SEPAR(path[0]) : + NName::IsAbsolutePath(path))) { - prop = GetRelativePath(simpleName, fs2us(fullPath)); + // (path) is abolute path or relative to root: "\path" + // we try to convert (path) to relative path for writing to archive. + const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex); + FString fullPath; + if (NDir::MyGetFullPathName(phyPath, fullPath)) + { + if (IS_PATH_SEPAR(path[0]) && + !IS_PATH_SEPAR(path[1])) + { + // path is relative to root of (fullPath): "\path" + const unsigned prefixSize = NName::GetRootPrefixSize(fullPath); + if (prefixSize) + { + path.DeleteFrontal(1); + path.Insert(0, fs2us(fullPath.Left(prefixSize))); + // we have changed "\" prefix to drive prefix "c:\" in (path). + // (path) is Windows path now. + isWSL = false; + } + } + } + path = GetRelativePath(path, fs2us(fullPath), isWSL); } +#if WCHAR_PATH_SEPARATOR != L'/' + // 7-Zip's TAR handler in Windows replaces windows slashes to linux slashes. + // so we can return any slashes to TAR handler. + // or we can convert to linux slashes here, + // because input IInArchive handler uses linux slashes for kpidSymLink. + // path.Replace(WCHAR_PATH_SEPARATOR, L'/'); +#endif + if (!path.IsEmpty()) + prop = path; } - prop.Detach(value); - return S_OK; } - } - - #else // _WIN32 - - if (di.ReparseData.Size() != 0) - { +#else // ! _WIN32 AString utf; utf.SetFrom_CalcLen((const char *)(const Byte *)di.ReparseData, (unsigned)di.ReparseData.Size()); - + #if 0 // 0 - for debug + // it's expected that link data uses system codepage. + // fs2us() ignores conversion errors. But we want correct path + UString us (fs2us(utf)); + #else UString us; if (ConvertUTF8ToUnicode(utf, us)) + #endif { - prop = us; - prop.Detach(value); - return S_OK; + if (!us.IsEmpty()) + prop = us; } +#endif // ! _WIN32 } - - #endif // _WIN32 + prop.Detach(value); + return S_OK; } - #endif // !defined(UNDER_CE) +#endif // !defined(UNDER_CE) } else if (propID == kpidHardLink) { @@ -428,7 +463,12 @@ { const CKeyKeyValPair &pair = _map[_hardIndex_To]; const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value]; - prop = DirItems->GetLogPath((unsigned)up2.DirIndex); + const UString path = DirItems->GetLogPath((unsigned)up2.DirIndex); +#if WCHAR_PATH_SEPARATOR != L'/' + // 7-Zip's TAR handler in Windows replaces windows slashes to linux slashes. + // path.Replace(WCHAR_PATH_SEPARATOR, L'/'); +#endif + prop = path; prop.Detach(value); return S_OK; } @@ -438,7 +478,7 @@ return S_OK; } } - } + } // if (up.NewData) if (up.IsAnti && propID != kpidIsDir @@ -449,6 +489,7 @@ { case kpidSize: prop = (UInt64)0; break; case kpidIsAnti: prop = true; break; + default: break; } } else if (propID == kpidPath && up.NewNameIndex >= 0) @@ -476,14 +517,19 @@ case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break; case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break; case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break; - case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break; - case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break; + case kpidAttrib: /* if (di.Attrib_IsDefined) */ prop = (UInt32)di.GetWinAttrib(); break; + case kpidPosixAttrib: /* if (di.Attrib_IsDefined) */ prop = (UInt32)di.GetPosixAttrib(); break; #if defined(_WIN32) case kpidIsAltStream: prop = di.IsAltStream; break; // case kpidShortName: prop = di.ShortName; break; #else + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + case kpidDeviceMajor: /* printf("\ndi.mode = %o\n", di.mode); @@ -499,6 +545,10 @@ prop = (UInt32)minor(di.rdev); break; + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + // case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break; case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break; @@ -512,6 +562,7 @@ prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; break; #endif + default: break; } } prop.Detach(value); @@ -519,22 +570,22 @@ COM_TRY_END } -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection CS; +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CS; #endif void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex) { if (ProcessedItemsStatuses) { - #ifndef _7ZIP_ST - NSynchronization::CCriticalSectionLock lock(CS); + #ifndef Z7_ST + NSynchronization::CCriticalSectionLock lock(g_CS); #endif ProcessedItemsStatuses[dirIndex] = 1; } } -STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) { COM_TRY_BEGIN *inStream = NULL; @@ -542,7 +593,7 @@ if (!up.NewData) return E_FAIL; - RINOK(Callback->CheckBreak()); + RINOK(Callback->CheckBreak()) // RINOK(Callback->Finalize()); bool isDir = IsDir(up); @@ -554,7 +605,7 @@ name = (*ArcItems)[(unsigned)up.ArcIndex].Name; else if (up.DirIndex >= 0) name = DirItems->GetLogPath((unsigned)up.DirIndex); - RINOK(Callback->GetStream(name, isDir, true, mode)); + RINOK(Callback->GetStream(name, isDir, true, mode)) /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file. so we return empty stream */ @@ -569,7 +620,7 @@ return S_OK; } - RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode)); + RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode)) if (isDir) return S_OK; @@ -580,8 +631,14 @@ mode != NUpdateNotifyOp::kUpdate) return S_OK; +#if 1 CStdInFileStream *inStreamSpec = new CStdInFileStream; CMyComPtr inStreamLoc(inStreamSpec); +#else + CMyComPtr inStreamLoc; + if (!CreateStdInStream(inStreamLoc)) + return GetLastError_noZero_HRESULT(); +#endif *inStream = inStreamLoc.Detach(); } else @@ -640,8 +697,9 @@ #endif inStreamSpec->SupportHardLinks = StoreHardLinks; - inStreamSpec->Set_PreserveATime(PreserveATime - || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass. + const bool preserveATime = (PreserveATime + || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass. + inStreamSpec->Set_PreserveATime(preserveATime); const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex); _openFiles_Indexes.Add(index); @@ -655,12 +713,32 @@ if (!inStreamSpec->OpenShared(path, ShareForWrite)) { - const DWORD error = ::GetLastError(); - const HRESULT hres = Callback->OpenFileError(path, error); - if (StopAfterOpenError) + bool isOpen = false; + if (preserveATime) + { + inStreamSpec->Set_PreserveATime(false); + isOpen = inStreamSpec->OpenShared(path, ShareForWrite); + } + if (!isOpen) + { + const DWORD error = ::GetLastError(); + const HRESULT hres = Callback->OpenFileError(path, error); if (hres == S_OK || hres == S_FALSE) + if (StopAfterOpenError || + // v23: we check also for some critical errors: + #ifdef _WIN32 + error == ERROR_NO_SYSTEM_RESOURCES + #else + error == EMFILE + #endif + ) + { + if (error == 0) + return E_FAIL; return HRESULT_FROM_WIN32(error); - return hres; + } + return hres; + } } /* @@ -679,7 +757,7 @@ inStreamSpec->ReloadProps(); } - // #if defined(USE_WIN_FILE) || !defined(_WIN32) + // #if defined(Z7_FILE_STREAMS_USE_WIN_FILE) || !defined(_WIN32) if (StoreHardLinks) { CStreamFileProps props; @@ -691,8 +769,8 @@ pair.Key1 = props.VolID; pair.Key2 = props.FileID_Low; pair.Value = index; - unsigned numItems = _map.Size(); - unsigned pairIndex = _map.AddToUniqueSorted2(pair); + const unsigned numItems = _map.Size(); + const unsigned pairIndex = _map.AddToUniqueSorted2(pair); if (numItems == _map.Size()) { // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex]; @@ -714,14 +792,14 @@ COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 opRes) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 opRes)) { COM_TRY_BEGIN return Callback->SetOperationResult(opRes); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) { COM_TRY_BEGIN return GetStream2(index, inStream, @@ -731,7 +809,7 @@ COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op)) { COM_TRY_BEGIN @@ -770,9 +848,9 @@ } else if (Arc) { - RINOK(Arc->GetItem_Path(index, s2)); + RINOK(Arc->GetItem_Path(index, s2)) s = s2; - RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)); + RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)) } } } @@ -791,7 +869,7 @@ COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) { COM_TRY_BEGIN @@ -825,12 +903,12 @@ s = (*ArcItems)[index].Name; else if (Arc) { - RINOK(Arc->GetItem_Path(index, s2)); + RINOK(Arc->GetItem_Path(index, s2)) s = s2; } if (Archive) { - RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)); + RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)) } } } @@ -848,7 +926,7 @@ /* -STDMETHODIMP CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer) +Z7_COM7F_IMF(CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer)) { *answer = 0; if (Need_ArcMTime_Report && propID == kpidComboMTime) @@ -856,7 +934,7 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) { if (indexType == NArchive::NEventIndexType::kArcProp) { @@ -879,19 +957,19 @@ return Callback->ReportProp(indexType, index, propID, value); } -STDMETHODIMP CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index, - PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index, + PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) { return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType); } -STDMETHODIMP CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) { return Callback->ReportFinished(indexType, index, opRes); } */ -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) { if (VolumesSizes.Size() == 0) return S_FALSE; @@ -901,7 +979,7 @@ return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) { COM_TRY_BEGIN char temp[16]; @@ -910,26 +988,26 @@ while (res.Len() < 2) res.InsertAtFront(FTEXT('0')); FString fileName = VolName; - fileName += '.'; + fileName.Add_Dot(); fileName += res; fileName += VolExt; COutFileStream *streamSpec = new COutFileStream; CMyComPtr streamLoc(streamSpec); - if (!streamSpec->Create(fileName, false)) + if (!streamSpec->Create_NEW(fileName)) return GetLastError_noZero_HRESULT(); *volumeStream = streamLoc.Detach(); return S_OK; COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) { COM_TRY_BEGIN return Callback->CryptoGetTextPassword2(passwordIsDefined, password); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN return Callback->CryptoGetTextPassword(password); @@ -949,7 +1027,7 @@ { if (_openFiles_Indexes[i] == index) { - RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)); + RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)) break; } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.h 2022-04-09 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateCallback.h 2023-04-06 05:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdateCallback.h -#ifndef __UPDATE_CALLBACK_H -#define __UPDATE_CALLBACK_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_H +#define ZIP7_INC_UPDATE_CALLBACK_H #include "../../../Common/MyCom.h" @@ -27,37 +27,38 @@ } }; -#define INTERFACE_IUpdateCallbackUI(x) \ - virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \ - virtual HRESULT CheckBreak() x; \ - /* virtual HRESULT Finalize() x; */ \ - virtual HRESULT SetNumItems(const CArcToDoStat &stat) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(Int32 opRes) x; \ - virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \ - virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x; \ - /* virtual HRESULT SetPassword(const UString &password) x; */ \ - virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \ - virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \ - virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \ + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEN_IUpdateCallbackUI(x) \ + virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x \ + virtual HRESULT CheckBreak() x \ + /* virtual HRESULT Finalize() x */ \ + virtual HRESULT SetNumItems(const CArcToDoStat &stat) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(Int32 opRes) x \ + virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x \ + virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x \ + /* virtual HRESULT SetPassword(const UString &password) x */ \ + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x \ + virtual HRESULT CryptoGetTextPassword(BSTR *password) x \ + virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x \ /* - virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x; \ - virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x; \ - virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x; \ + virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x \ + virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x \ + virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x \ */ /* virtual HRESULT CloseProgress() { return S_OK; } */ -struct IUpdateCallbackUI -{ - INTERFACE_IUpdateCallbackUI(=0) -}; +Z7_IFACE_DECL_PURE(IUpdateCallbackUI) +Z7_PURE_INTERFACES_END struct CKeyKeyValPair { @@ -74,11 +75,11 @@ }; -class CArchiveUpdateCallback: +class CArchiveUpdateCallback Z7_final: public IArchiveUpdateCallback2, public IArchiveUpdateCallbackFile, // public IArchiveUpdateCallbackArcProp, - public IArchiveExtractCallbackMessage, + public IArchiveExtractCallbackMessage2, public IArchiveGetRawProps, public IArchiveGetRootProps, public ICryptoGetTextPassword2, @@ -87,54 +88,63 @@ public IInFileStream_Callback, public CMyUnknownImp { - #if defined(_WIN32) && !defined(UNDER_CE) - bool _saclEnabled; - #endif - CRecordVector _map; + Z7_COM_QI_BEGIN2(IArchiveUpdateCallback2) + Z7_COM_QI_ENTRY(IArchiveUpdateCallbackFile) + // Z7_COM_QI_ENTRY(IArchiveUpdateCallbackArcProp) + Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage2) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IArchiveGetRootProps) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword2) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + Z7_COM_QI_ENTRY(ICompressProgressInfo) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback2) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + // Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackArcProp) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IArchiveGetRootProps) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) - UInt32 _hardIndex_From; - UInt32 _hardIndex_To; void UpdateProcessedItemStatus(unsigned dirIndex); public: - MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2) - MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile) - // MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackArcProp) - MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword2) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - INTERFACE_IArchiveUpdateCallback2(;) - INTERFACE_IArchiveUpdateCallbackFile(;) - // INTERFACE_IArchiveUpdateCallbackArcProp(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IArchiveGetRootProps(;) + bool PreserveATime; + bool ShareForWrite; + bool StopAfterOpenError; + bool StdInMode; + + bool KeepOriginalItemNames; + bool StoreNtSecurity; + bool StoreHardLinks; + bool StoreSymLinks; - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); - STDMETHOD(CryptoGetTextPassword)(BSTR *password); + bool StoreOwnerId; + bool StoreOwnerName; + + bool Need_LatestMTime; + bool LatestMTime_Defined; + + /* + bool Need_ArcMTime_Report; + bool ArcMTime_WasReported; + */ CRecordVector _openFiles_Indexes; FStringVector _openFiles_Paths; // CRecordVector< CInFileStream* > _openFiles_Streams; bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); } - virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error); - virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val); - - CRecordVector VolumesSizes; - FString VolName; - FString VolExt; - UString ArcFileName; // without path prefix + virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) Z7_override; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) Z7_override; IUpdateCallbackUI *Callback; @@ -145,36 +155,24 @@ CMyComPtr Archive; const CObjectVector *ArcItems; const CRecordVector *UpdatePairs; - const UStringVector *NewNames; - int CommentIndex; - const UString *Comment; - bool PreserveATime; - bool ShareForWrite; - bool StopAfterOpenError; - bool StdInMode; - - bool KeepOriginalItemNames; - bool StoreNtSecurity; - bool StoreHardLinks; - bool StoreSymLinks; + CRecordVector VolumesSizes; + FString VolName; + FString VolExt; + UString ArcFileName; // without path prefix - bool StoreOwnerId; - bool StoreOwnerName; + const UStringVector *NewNames; + const UString *Comment; + int CommentIndex; /* - bool Need_ArcMTime_Report; - bool ArcMTime_WasReported; CArcTime Reported_ArcMTime; */ - bool Need_LatestMTime; - bool LatestMTime_Defined; CFiTime LatestMTime; Byte *ProcessedItemsStatuses; - CArchiveUpdateCallback(); bool IsDir(const CUpdatePair2 &up) const @@ -185,6 +183,15 @@ return (*ArcItems)[(unsigned)up.ArcIndex].IsDir; return false; } + +private: + #if defined(_WIN32) && !defined(UNDER_CE) + bool _saclEnabled; + #endif + CRecordVector _map; + + UInt32 _hardIndex_From; + UInt32 _hardIndex_To; }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdatePair.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdatePair.cpp 2022-04-06 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.cpp 2023-04-06 05:00:00.000000000 +0000 @@ -103,7 +103,7 @@ static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:"; static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void ThrowError(const char *message, const UString &s1, const UString &s2) { @@ -115,7 +115,7 @@ static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) { - int res = CompareFileNames(ai1.Name, ai2.Name); + const int res = CompareFileNames(ai1.Name, ai2.Name); if (res != 0) return res; if (ai1.IsDir != ai2.IsDir) @@ -128,7 +128,7 @@ const unsigned i1 = *p1; const unsigned i2 = *p2; const CObjectVector &arcItems = *(const CObjectVector *)param; - int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); + const int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); if (res != 0) return res; return MyCompare(i1, i2); @@ -259,7 +259,7 @@ int compResult = 0; if (ai->MTime.Def) { - compResult = MyCompareTime(fileTimeType, di->MTime, ai->MTime); + compResult = MyCompareTime((unsigned)fileTimeType, di->MTime, ai->MTime); } switch (compResult) { @@ -283,7 +283,7 @@ { if (prevHostName) { - unsigned hostLen = prevHostName->Len(); + const unsigned hostLen = prevHostName->Len(); if (name->Len() > hostLen) if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0) pair.HostIndex = prevHostFile; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdatePair.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdatePair.h 2014-05-03 11:49:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdatePair.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdatePair.h -#ifndef __UPDATE_PAIR_H -#define __UPDATE_PAIR_H +#ifndef ZIP7_INC_UPDATE_PAIR_H +#define ZIP7_INC_UPDATE_PAIR_H #include "DirItem.h" #include "UpdateAction.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.cpp 2022-02-08 16:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.cpp 2024-03-03 16:00:00.000000000 +0000 @@ -24,7 +24,7 @@ up2.NewData = up2.NewProps = true; up2.UseArcProps = false; - switch (actionSet.StateActions[(unsigned)pair.State]) + switch ((int)actionSet.StateActions[(unsigned)pair.State]) { case NPairAction::kIgnore: if (pair.ArcIndex >= 0 && callback) @@ -61,6 +61,8 @@ up2.IsAnti = true; up2.UseArcProps = (pair.ArcIndex >= 0); break; + + default: throw 123; // break; // is unexpected case } up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.h 2022-02-08 16:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/UpdateProduce.h 2023-02-01 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdateProduce.h -#ifndef __UPDATE_PRODUCE_H -#define __UPDATE_PRODUCE_H +#ifndef ZIP7_INC_UPDATE_PRODUCE_H +#define ZIP7_INC_UPDATE_PRODUCE_H #include "UpdatePair.h" @@ -43,10 +43,13 @@ {} }; -struct IUpdateProduceCallback +Z7_PURE_INTERFACES_BEGIN + +DECLARE_INTERFACE(IUpdateProduceCallback) { virtual HRESULT ShowDeleteFile(unsigned arcIndex) = 0; }; +Z7_PURE_INTERFACES_END void UpdateProduce( const CRecordVector &updatePairs, diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/WorkDir.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/WorkDir.cpp 2021-01-25 19:32:34.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.cpp 2024-10-17 10:00:00.000000000 +0000 @@ -2,11 +2,8 @@ #include "StdAfx.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileFind.h" #include "../../../Windows/FileName.h" +#include "../../../Windows/FileSystem.h" #include "WorkDir.h" @@ -22,10 +19,10 @@ if (workDirInfo.ForRemovableOnly) { mode = NWorkDir::NMode::kCurrent; - FString prefix = path.Left(3); - if (prefix[1] == FTEXT(':') && prefix[2] == FTEXT('\\')) + const FString prefix = path.Left(3); + if (NName::IsDrivePath(prefix)) { - UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP)); + const UINT driveType = NSystem::MyGetDriveType(prefix); if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) mode = workDirInfo.Mode; } @@ -39,29 +36,26 @@ } #endif - int pos = path.ReverseFind_PathSepar() + 1; + const int pos = path.ReverseFind_PathSepar() + 1; fileName = path.Ptr((unsigned)pos); - switch (mode) + FString tempDir; + switch ((int)mode) { case NWorkDir::NMode::kCurrent: - { - return path.Left((unsigned)pos); - } + tempDir = path.Left((unsigned)pos); + break; case NWorkDir::NMode::kSpecified: - { - FString tempDir = workDirInfo.Path; - NName::NormalizeDirPathPrefix(tempDir); - return tempDir; - } + tempDir = workDirInfo.Path; + break; + // case NWorkDir::NMode::kSystem: default: - { - FString tempDir; if (!MyGetTempPath(tempDir)) throw 141717; - return tempDir; - } + break; } + NName::NormalizeDirPathPrefix(tempDir); + return tempDir; } HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) @@ -69,25 +63,22 @@ NWorkDir::CInfo workDirInfo; workDirInfo.Load(); FString namePart; - FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); - CreateComplexDir(workDir); - CTempFile tempFile; + FString path = GetWorkDir(workDirInfo, originalPath, namePart); + CreateComplexDir(path); + path += namePart; _outStreamSpec = new COutFileStream; OutStream = _outStreamSpec; - if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) - { + if (!_tempFile.Create(path, &_outStreamSpec->File)) return GetLastError_noZero_HRESULT(); - } _originalPath = originalPath; return S_OK; } -HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal) +HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress) { OutStream.Release(); - if (!_tempFile.MoveTo(_originalPath, deleteOriginal)) - { + if (!_tempFile.MoveTo(_originalPath, deleteOriginal, progress)) return GetLastError_noZero_HRESULT(); - } return S_OK; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/WorkDir.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/WorkDir.h 2013-02-18 08:11:20.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/WorkDir.h 2024-10-17 10:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // WorkDir.h -#ifndef __WORK_DIR_H -#define __WORK_DIR_H +#ifndef ZIP7_INC_WORK_DIR_H +#define ZIP7_INC_WORK_DIR_H #include "../../../Windows/FileDir.h" @@ -11,7 +11,7 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName); -class CWorkDirTempFile +class CWorkDirTempFile MY_UNCOPYABLE { FString _originalPath; NWindows::NFile::NDir::CTempFile _tempFile; @@ -19,8 +19,12 @@ public: CMyComPtr OutStream; + const FString &Get_OriginalFilePath() const { return _originalPath; } + const FString &Get_TempFilePath() const { return _tempFile.GetPath(); } + HRESULT CreateTempFile(const FString &originalPath); - HRESULT MoveToOriginal(bool deleteOriginal); + HRESULT MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress = NULL); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.cpp 2022-06-03 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -11,6 +11,7 @@ #include "../../../Windows/Registry.h" #include "../../../Windows/Synchronization.h" +// #include "../Explorer/ContextMenuFlags.h" #include "ZipRegistry.h" using namespace NWindows; @@ -44,8 +45,8 @@ static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value) { - if (key.QueryValue(name, value) != ERROR_SUCCESS) - value = (UInt32)(Int32)-1; + value = (UInt32)(Int32)-1; + key.GetValue_UInt32_IfOk(name, value); } @@ -58,7 +59,7 @@ static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val) { bool oldVal = false; - if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS) + if (key.GetValue_bool_IfOk(name, oldVal) == ERROR_SUCCESS) if (val == oldVal) return; key.SetValue(name, val); @@ -75,13 +76,13 @@ static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) { b.Val = false; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); } static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b) { b.Val = true; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); } namespace NExtract @@ -97,6 +98,7 @@ static LPCTSTR const kElimDup = TEXT("ElimDup"); // static LPCTSTR const kAltStreams = TEXT("AltStreams"); static LPCTSTR const kNtSecur = TEXT("Security"); +static LPCTSTR const kMemLimit = TEXT("MemLimit"); void CInfo::Save() const { @@ -127,6 +129,14 @@ key.SetValue(kShowPassword, showPassword); } +void Save_LimitGB(UInt32 limit_GB) +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + Key_Set_UInt32(key, kMemLimit, limit_GB); +} + void CInfo::Load() { PathMode = NPathMode::kCurPaths; @@ -145,12 +155,12 @@ key.GetValue_Strings(kPathHistory, Paths); UInt32 v; - if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) + if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) { PathMode = (NPathMode::EEnum)v; PathMode_Force = true; } - if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) + if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) { OverwriteMode = (NOverwriteMode::EEnum)v; OverwriteMode_Force = true; @@ -171,10 +181,20 @@ bool showPassword = false; if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) return showPassword; - key.GetValue_IfOk(kShowPassword, showPassword); + key.GetValue_bool_IfOk(kShowPassword, showPassword); return showPassword; } +UInt32 Read_LimitGB() +{ + CS_LOCK + CKey key; + UInt32 v = (UInt32)(Int32)-1; + if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS) + key.GetValue_UInt32_IfOk(kMemLimit, v); + return v; +} + } namespace NCompression @@ -191,6 +211,7 @@ static LPCTSTR const kLevel = TEXT("Level"); static LPCTSTR const kDictionary = TEXT("Dictionary"); +// static LPCTSTR const kDictionaryChain = TEXT("DictionaryChain"); static LPCTSTR const kOrder = TEXT("Order"); static LPCTSTR const kBlockSize = TEXT("BlockSize"); static LPCTSTR const kNumThreads = TEXT("NumThreads"); @@ -269,6 +290,7 @@ Key_Set_UInt32(fk, kLevel, fo.Level); Key_Set_UInt32(fk, kDictionary, fo.Dictionary); + // Key_Set_UInt32(fk, kDictionaryChain, fo.DictionaryChain); Key_Set_UInt32(fk, kOrder, fo.Order); Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize); Key_Set_UInt32(fk, kNumThreads, fo.NumThreads); @@ -326,6 +348,7 @@ Key_Get_UInt32(fk, kLevel, fo.Level); Key_Get_UInt32(fk, kDictionary, fo.Dictionary); + // Key_Get_UInt32(fk, kDictionaryChain, fo.DictionaryChain); Key_Get_UInt32(fk, kOrder, fo.Order); Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize); Key_Get_UInt32(fk, kNumThreads, fo.NumThreads); @@ -345,9 +368,9 @@ UString a; if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) ArcType = a; - key.GetValue_IfOk(kLevel, Level); - key.GetValue_IfOk(kShowPassword, ShowPassword); - key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders); + key.GetValue_UInt32_IfOk(kLevel, Level); + key.GetValue_bool_IfOk(kShowPassword, ShowPassword); + key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders); } @@ -491,7 +514,7 @@ return; UInt32 dirType; - if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS) + if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS) return; switch (dirType) { @@ -509,7 +532,7 @@ if (Mode == NMode::kSpecified) Mode = NMode::kSystem; } - key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly); + key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly); } } @@ -549,7 +572,15 @@ WriteZone = (UInt32)(Int32)-1; - Flags = (UInt32)(Int32)-1; + /* we can disable email items by default, + because email code doesn't work in some systems */ + Flags = (UInt32)(Int32)-1 + /* + & ~NContextMenuFlags::kCompressEmail + & ~NContextMenuFlags::kCompressTo7zEmail + & ~NContextMenuFlags::kCompressToZipEmail + */ + ; Flags_Def = false; CS_LOCK @@ -564,5 +595,5 @@ Key_Get_UInt32(key, kWriteZoneId, WriteZone); - Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); + Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.h 2022-06-03 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Common/ZipRegistry.h 2024-03-16 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ZipRegistry.h -#ifndef __ZIP_REGISTRY_H -#define __ZIP_REGISTRY_H +#ifndef ZIP7_INC_ZIP_REGISTRY_H +#define ZIP7_INC_ZIP_REGISTRY_H #include "../../../Common/MyTypes.h" #include "../../../Common/MyString.h" @@ -43,6 +43,9 @@ void Save_ShowPassword(bool showPassword); bool Read_ShowPassword(); + + void Save_LimitGB(UInt32 limit_GB); + UInt32 Read_LimitGB(); } namespace NCompression @@ -81,6 +84,7 @@ { UInt32 Level; UInt32 Dictionary; + // UInt32 DictionaryChain; UInt32 Order; UInt32 BlockLogSize; UInt32 NumThreads; @@ -116,6 +120,7 @@ void ResetForLevelChange() { BlockLogSize = NumThreads = Level = Dictionary = Order = (UInt32)(Int32)-1; + // DictionaryChain = (UInt32)(Int32)-1; Method.Empty(); // Options.Empty(); // EncryptionMethod.Empty(); @@ -133,10 +138,6 @@ UInt32 Level; bool ShowPassword; bool EncryptHeaders; - UString ArcType; - UStringVector ArcPaths; - - CObjectVector Formats; CBoolPair NtSecurity; CBoolPair AltStreams; @@ -145,6 +146,11 @@ CBoolPair PreserveATime; + UString ArcType; + UStringVector ArcPaths; + + CObjectVector Formats; + void Save() const; void Load(); }; @@ -164,8 +170,8 @@ struct CInfo { NMode::EEnum Mode; - FString Path; bool ForRemovableOnly; + FString Path; void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } void SetDefault() diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/BenchCon.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/BenchCon.cpp 2015-03-10 16:19:21.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.cpp 2023-04-01 19:00:00.000000000 +0000 @@ -7,13 +7,13 @@ #include "BenchCon.h" #include "ConsoleClose.h" -struct CPrintBenchCallback: public IBenchPrintCallback +struct CPrintBenchCallback Z7_final: public IBenchPrintCallback { FILE *_file; - void Print(const char *s); - void NewLine(); - HRESULT CheckBreak(); + void Print(const char *s) Z7_override; + void NewLine() Z7_override; + HRESULT CheckBreak() Z7_override; }; void CPrintBenchCallback::Print(const char *s) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/BenchCon.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/BenchCon.h 2012-12-06 08:03:03.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/BenchCon.h 2023-04-01 19:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // BenchCon.h -#ifndef __BENCH_CON_H -#define __BENCH_CON_H +#ifndef ZIP7_INC_BENCH_CON_H +#define ZIP7_INC_BENCH_CON_H #include diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.dsp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.dsp 2022-07-14 06:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.dsp 2024-01-27 09:00:00.000000000 +0000 @@ -44,7 +44,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GF /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GF /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,7 +69,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -95,7 +95,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -121,7 +121,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -397,6 +397,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -445,6 +449,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -465,6 +477,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -761,6 +777,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File @@ -849,6 +873,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -858,6 +890,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -876,6 +912,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sort.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.mak 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.mak --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.mak 2019-02-19 10:52:35.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.mak 2024-01-29 08:00:00.000000000 +0000 @@ -1,7 +1,8 @@ MY_CONSOLE = 1 !IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE +CFLAGS = $(CFLAGS) -DZ7_DEVICE_FILE +# -DZ7_LONG_PATH -DZ7_LARGE_PAGES !ENDIF CONSOLE_OBJS = \ @@ -41,3 +42,5 @@ C_OBJS = $(C_OBJS) \ $O\DllSecur.obj \ + +# we need empty line after last line above diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.manifest 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.manifest --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/Console.manifest 2018-04-04 13:36:42.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Console.manifest 2023-04-02 08:00:00.000000000 +0000 @@ -10,4 +10,7 @@ + + +true \ No newline at end of file diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.cpp 2021-01-05 15:49:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -16,7 +16,7 @@ namespace NConsoleClose { unsigned g_BreakCounter = 0; -static const unsigned kBreakAbortThreshold = 2; +static const unsigned kBreakAbortThreshold = 3; #ifdef _WIN32 @@ -28,8 +28,7 @@ return TRUE; } - g_BreakCounter++; - if (g_BreakCounter < kBreakAbortThreshold) + if (++g_BreakCounter < kBreakAbortThreshold) return TRUE; return FALSE; /* @@ -47,7 +46,7 @@ CCtrlHandlerSetter::CCtrlHandlerSetter() { if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) - throw "SetConsoleCtrlHandler fails"; + throw 1019; // "SetConsoleCtrlHandler fails"; } CCtrlHandlerSetter::~CCtrlHandlerSetter() @@ -63,8 +62,7 @@ static void HandlerRoutine(int) { - g_BreakCounter++; - if (g_BreakCounter < kBreakAbortThreshold) + if (++g_BreakCounter < kBreakAbortThreshold) return; exit(EXIT_FAILURE); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.h 2021-01-05 15:48:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ConsoleClose.h 2024-10-19 08:00:00.000000000 +0000 @@ -1,11 +1,11 @@ // ConsoleClose.h -#ifndef __CONSOLE_CLOSE_H -#define __CONSOLE_CLOSE_H +#ifndef ZIP7_INC_CONSOLE_CLOSE_H +#define ZIP7_INC_CONSOLE_CLOSE_H namespace NConsoleClose { -class CCtrlBreakException {}; +// class CCtrlBreakException {}; #ifdef UNDER_CE @@ -21,7 +21,7 @@ return (g_BreakCounter != 0); } -class CCtrlHandlerSetter +class CCtrlHandlerSetter Z7_final { #ifndef _WIN32 void (*memo_sig_int)(int); @@ -29,7 +29,7 @@ #endif public: CCtrlHandlerSetter(); - virtual ~CCtrlHandlerSetter(); + ~CCtrlHandlerSetter(); }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 2022-04-29 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -11,7 +11,7 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/PropVariantConv.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -64,7 +64,7 @@ if (_se) { *_se << endl << kError << NError::MyFormatMessage(systemError) << endl; - _se->NormalizePrint_UString(fs2us(path)); + _se->NormalizePrint_UString_Path(fs2us(path)); *_se << endl << endl; _se->Flush(); } @@ -102,7 +102,7 @@ temp[0] = c; s += " ("; Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp); - s += ')'; + s.Add_Char(')'); } static void PrintSize_bytes_Smart_comma(AString &s, UInt64 val) @@ -183,7 +183,7 @@ -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -235,7 +235,7 @@ , "CRC Error" }; -STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) +Z7_COM7F_IMF(CExtractCallbackConsole::SetTotal(UInt64 size)) { MT_LOCK @@ -247,7 +247,7 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)) { MT_LOCK @@ -265,7 +265,7 @@ static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) { *_so << kTab << "Path: "; - _so->NormalizePrint_wstr(path); + _so->NormalizePrint_wstr_Path(path); *_so << endl; if (size && *size != (UInt64)(Int64)-1) { @@ -281,14 +281,14 @@ } } -STDMETHODIMP CExtractCallbackConsole::AskOverwrite( +Z7_COM7F_IMF(CExtractCallbackConsole::AskOverwrite( const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) + Int32 *answer)) { MT_LOCK - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) ClosePercentsAndFlush(); @@ -302,7 +302,7 @@ NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so); - switch (overwriteAnswer) + switch ((int)overwriteAnswer) { case NUserAnswerMode::kQuit: return E_ABORT; case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break; @@ -325,7 +325,7 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position) +Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) { MT_LOCK @@ -341,9 +341,9 @@ case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break; case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; requiredLevel = 0; break; default: s = "???"; requiredLevel = 2; - }; + } - bool show2 = (LogLevel >= requiredLevel && _so); + const bool show2 = (LogLevel >= requiredLevel && _so); if (show2) { @@ -358,7 +358,7 @@ if (name) { _tempU = name; - _so->Normalize_UString(_tempU); + _so->Normalize_UString_Path(_tempU); // 21.04 if (isFolder) { @@ -373,6 +373,7 @@ if (NeedFlush) _so->Flush(); + // _so->Flush(); // for debug only } if (NeedPercents()) @@ -394,11 +395,11 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) +Z7_COM7F_IMF(CExtractCallbackConsole::MessageError(const wchar_t *message)) { MT_LOCK - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) NumFileErrors_in_Current++; NumFileErrors++; @@ -448,6 +449,7 @@ case NArchive::NExtract::NOperationResult::kWrongPassword: s = kWrongPassword; break; + default: break; } dest += kError; @@ -460,7 +462,7 @@ } } -STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted) +Z7_COM7F_IMF(CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted)) { MT_LOCK @@ -489,7 +491,7 @@ if (!_currentName.IsEmpty()) { *_se << " : "; - _se->NormalizePrint_UString(_currentName); + _se->NormalizePrint_UString_Path(_currentName); } *_se << endl; _se->Flush(); @@ -499,7 +501,7 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +Z7_COM7F_IMF(CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) { if (opRes != NArchive::NExtract::NOperationResult::kOK) { @@ -512,7 +514,7 @@ -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT CExtractCallbackConsole::SetPassword(const UString &password) { @@ -521,7 +523,7 @@ return S_OK; } -STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN MT_LOCK @@ -531,9 +533,101 @@ #endif + +#ifndef Z7_SFX + +void CExtractCallbackConsole::PrintTo_se_Path_WithTitle(const UString &path, const char *title) +{ + *_se << title; + _se->NormalizePrint_UString_Path(path); + *_se << endl; +} + +void CExtractCallbackConsole::Add_ArchiveName_Error() +{ + if (_needWriteArchivePath) + { + PrintTo_se_Path_WithTitle(_currentArchivePath, "Archive: "); + _needWriteArchivePath = false; + } +} + + +Z7_COM7F_IMF(CExtractCallbackConsole::RequestMemoryUse( + UInt32 flags, UInt32 /* indexType */, UInt32 /* index */, const wchar_t *path, + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +{ + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0 + && requiredSize <= *allowedSize) + { +#if 0 + // it's expected, that *answerFlags was set to NRequestMemoryAnswerFlags::k_Allow already, + // because it's default answer for (requiredSize <= *allowedSize) case. + // optional code: + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; +#endif + } + else + { + if ((flags & NRequestMemoryUseFlags::k_NoErrorMessage) == 0) + if (_se) + { + const UInt64 num_GB_allowed = (*allowedSize + ((1u << 30) - 1)) >> 30; + const UInt64 num_GB_required = (requiredSize + ((1u << 30) - 1)) >> 30; + ClosePercentsAndFlush(); + Add_ArchiveName_Error(); + if (path) + PrintTo_se_Path_WithTitle(path, "File: "); + *_se << "The extraction operation requires big amount memory (RAM):" << endl + << " " << num_GB_required << " GB : required memory usage size" << endl + << " " << num_GB_allowed << " GB : allowed memory usage limit" << endl + << " Use -smemx{size}g switch to set allowed memory usage limit for extraction." << endl; + *_se << "ERROR: Memory usage limit was exceeded." << endl; + const char *m = NULL; + // if (indexType == NArchive::NEventIndexType::kNoIndex) + if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipArc)) + m = "Archive unpacking was skipped."; +/* + else if ((flags & NRequestMemoryUseFlags::k_SkipBigFiles_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipBigFiles)) + m = "Extraction for some files will be skipped."; + else if ((flags & NRequestMemoryUseFlags::k_SkipBigFile_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipBigFile)) + m = "File extraction was skipped."; +*/ + if (m) + *_se << m; + _se->Flush(); + } + + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + // default answer can be k_Allow, if limit was not forced, + // so we change answer to non-allowed here. + *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded; + if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc; +/* + else if (flags & NRequestMemoryUseFlags::k_SkipBigFile_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipBigFile; + else if (flags & NRequestMemoryUseFlags::k_SkipBigFiles_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipBigFiles; +*/ + } + } + return CheckBreak2(); +} + +#endif + + HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) { - RINOK(CheckBreak2()); + _currentArchivePath = name; + _needWriteArchivePath = true; + + RINOK(CheckBreak2()) NumTryArcs++; ThereIsError_in_Current = false; @@ -544,7 +638,7 @@ if (_so) { *_so << endl << (testMode ? kTesting : kExtracting); - _so->NormalizePrint_wstr(name); + _so->NormalizePrint_wstr_Path(name); *_so << endl; } @@ -560,7 +654,7 @@ { AString s; - for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsMessages); i++) { UInt32 f = (1 << i); if ((errorFlags & f) == 0) @@ -609,7 +703,7 @@ const CArcErrorInfo &er = arc.ErrorInfo; *_so << "WARNING:\n"; - _so->NormalizePrint_UString(arc.Path); + _so->NormalizePrint_UString_Path(arc.Path); UString s; if (arc.FormatIndex == er.ErrorFormatIndex) { @@ -630,6 +724,9 @@ const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) { + _currentArchivePath = name; + _needWriteArchivePath = true; + ClosePercents(); if (NeedPercents()) @@ -656,7 +753,7 @@ *_se << endl; if (level != 0) { - _se->NormalizePrint_UString(arc.Path); + _se->NormalizePrint_UString_Path(arc.Path); *_se << endl; } } @@ -693,7 +790,7 @@ *_so << endl; if (level != 0) { - _so->NormalizePrint_UString(arc.Path); + _so->NormalizePrint_UString_Path(arc.Path); *_so << endl; } } @@ -739,7 +836,7 @@ { if (_so) { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) *_so << endl; } } @@ -751,10 +848,10 @@ if (_se) { *_se << kError; - _se->NormalizePrint_wstr(name); + _se->NormalizePrint_wstr_Path(name); *_se << endl; - HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); + const HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res) if (result == S_FALSE) { } @@ -827,11 +924,11 @@ } else { - NumArcsWithError++; + // we don't update NumArcsWithError, if error is not related to archive data. if (result == E_ABORT - || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL) - ) + || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)) return result; + NumArcsWithError++; if (_se) { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.h 2022-04-29 17:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/ExtractCallbackConsole.h 2024-06-17 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractCallbackConsole.h -#ifndef __EXTRACT_CALLBACK_CONSOLE_H -#define __EXTRACT_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H +#define ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -34,15 +34,17 @@ }; */ -class CExtractScanConsole: public IDirItemsCallback +class CExtractScanConsole Z7_final: public IDirItemsCallback { + Z7_IFACE_IMP(IDirItemsCallback) + CStdOutStream *_so; CStdOutStream *_se; CPercentPrinter _percent; // CErrorPathCodes2 ScanErrors; - bool NeedPercents() const { return _percent._so != NULL; } + bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; } void ClosePercentsAndFlush() { @@ -54,21 +56,22 @@ public: - virtual ~CExtractScanConsole() {} - - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) { _so = outStream; _se = errorStream; _percent._so = percentStream; + _percent.DisablePrint = disablePercents; } void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } void StartScanning(); - INTERFACE_IDirItemsCallback(;) - void CloseScanning() { if (NeedPercents()) @@ -81,21 +84,65 @@ -class CExtractCallbackConsole: +class CExtractCallbackConsole Z7_final: + public IFolderArchiveExtractCallback, public IExtractCallbackUI, // public IArchiveExtractCallbackMessage, public IFolderArchiveExtractCallback2, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif + #ifndef Z7_SFX + public IArchiveRequestMemoryUseCallback, + #endif + public COpenCallbackConsole, public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) + // Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage) + Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + #ifndef Z7_SFX + Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback) + #endif + + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) + Z7_IFACE_IMP(IExtractCallbackUI) + // Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + #ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) + #endif + + bool _needWriteArchivePath; + +public: + bool ThereIsError_in_Current; + bool ThereIsWarning_in_Current; + bool NeedFlush; + +private: AString _tempA; UString _tempU; + UString _currentArchivePath; UString _currentName; +#ifndef Z7_SFX + void PrintTo_se_Path_WithTitle(const UString &path, const char *title); + void Add_ArchiveName_Error(); +#endif + void ClosePercents_for_so() { if (NeedPercents() && _so == _percent._so) @@ -109,37 +156,9 @@ if (_so) _so->Flush(); } - public: - MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) - // MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(SetTotal)(UInt64 total); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - INTERFACE_IFolderArchiveExtractCallback(;) - - INTERFACE_IExtractCallbackUI(;) - // INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - - #ifndef _NO_CRYPTO - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - #endif - UInt64 NumTryArcs; - bool ThereIsError_in_Current; - bool ThereIsWarning_in_Current; - UInt64 NumOkArcs; UInt64 NumCantOpenArcs; UInt64 NumArcsWithError; @@ -151,11 +170,11 @@ UInt64 NumFileErrors; UInt64 NumFileErrors_in_Current; - bool NeedFlush; unsigned PercentsNameLevel; unsigned LogLevel; CExtractCallbackConsole(): + _needWriteArchivePath(true), NeedFlush(false), PercentsNameLevel(1), LogLevel(0) @@ -163,9 +182,13 @@ void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) { - COpenCallbackConsole::Init(outStream, errorStream, percentStream); + COpenCallbackConsole::Init(outStream, errorStream, percentStream, disablePercents); NumTryArcs = 0; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/HashCon.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/HashCon.cpp 2021-12-16 09:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.cpp 2024-02-09 10:00:00.000000000 +0000 @@ -99,7 +99,7 @@ static void AddMinuses(AString &s, unsigned num) { for (unsigned i = 0; i < num; i++) - s += '-'; + s.Add_Minus(); } static void AddSpaces_if_Positive(AString &s, int num) @@ -314,7 +314,7 @@ else { UString temp (_fileName); - _so->Normalize_UString(temp); + _so->Normalize_UString_Path(temp); _so->Convert_UString_to_AString(temp, s); } PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash, s); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/HashCon.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/HashCon.h 2021-10-24 13:58:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/HashCon.h 2023-04-03 07:00:00.000000000 +0000 @@ -1,14 +1,19 @@ // HashCon.h -#ifndef __HASH_CON_H -#define __HASH_CON_H +#ifndef ZIP7_INC_HASH_CON_H +#define ZIP7_INC_HASH_CON_H #include "../Common/HashCalc.h" #include "UpdateCallbackConsole.h" -class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase +class CHashCallbackConsole Z7_final: + public IHashCallbackUI, + public CCallbackConsoleBase { + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IHashCallbackUI) + UString _fileName; AString _s; @@ -33,9 +38,7 @@ public: bool PrintNameInPercents; - bool PrintHeaders; - // bool PrintSize; // bool PrintNewLine; // set it too (false), if you need only hash for single file without LF char. AString PrintFields; @@ -48,10 +51,6 @@ // , PrintSize(true), // , PrintNewLine(true) {} - - virtual ~CHashCallbackConsole() {} - - INTERFACE_IHashCallbackUI(;) }; void PrintHashStat(CStdOutStream &so, const CHashBundle &hb); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/List.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/List.cpp 2022-05-18 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.cpp 2024-06-06 06:00:00.000000000 +0000 @@ -131,6 +131,8 @@ , "Group ID" , "Device Major" , "Device Minor" + , "Dev Major" + , "Dev Minor" }; static const char kEmptyAttribChar = '.'; @@ -238,11 +240,13 @@ { numSpaces = width - s.Len(); unsigned numLeftSpaces = 0; - switch (adj) + switch ((int)adj) { - case kLeft: numLeftSpaces = 0; break; + // case kLeft: numLeftSpaces = 0; break; case kCenter: numLeftSpaces = numSpaces / 2; break; case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; } PrintSpaces(numLeftSpaces); numSpaces -= numLeftSpaces; @@ -261,11 +265,13 @@ { numSpaces = width - len; unsigned numLeftSpaces = 0; - switch (adj) + switch ((int)adj) { - case kLeft: numLeftSpaces = 0; break; + // case kLeft: numLeftSpaces = 0; break; case kCenter: numLeftSpaces = numSpaces / 2; break; case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; } PrintSpaces(numLeftSpaces); numSpaces -= numLeftSpaces; @@ -284,11 +290,13 @@ { numSpaces = width - len; unsigned numLeftSpaces = 0; - switch (adj) + switch ((int)adj) { - case kLeft: numLeftSpaces = 0; break; + // case kLeft: numLeftSpaces = 0; break; case kCenter: numLeftSpaces = numSpaces / 2; break; case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; } PrintSpacesToString(dest, numLeftSpaces); dest += numLeftSpaces; @@ -405,13 +413,13 @@ for (k = 0; k < fii.PrefixSpacesWidth; k++) LinesString.Add_Space(); for (k = 0; k < fii.Width; k++) - LinesString += '-'; + LinesString.Add_Minus(); } } static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU) { - if (propID < ARRAY_SIZE(kPropIdToName)) + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) { nameA = kPropIdToName[propID]; return; @@ -441,10 +449,10 @@ unsigned i; for (i = 0; i < s.Len(); i++) { - wchar_t c = s[i]; + const wchar_t c = s[i]; if (c >= 0x80) break; - sA += (char)c; + sA.Add_Char((char)c); } if (i == s.Len()) f.NameA = sA; @@ -455,13 +463,13 @@ HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) { UInt32 numProps; - RINOK(archive->GetNumberOfProperties(&numProps)); + RINOK(archive->GetNumberOfProperties(&numProps)) for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); + RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)) AddProp(name, propID, false); } return S_OK; @@ -470,12 +478,12 @@ HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps) { UInt32 numProps; - RINOK(getRawProps->GetNumRawProps(&numProps)); + RINOK(getRawProps->GetNumRawProps(&numProps)) for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; - RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)); + RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)) AddProp(name, propID, true); } return S_OK; @@ -502,7 +510,8 @@ if (t.IsZero()) return; int prec = kTimestampPrintLevel_SEC; - if (showNS) + unsigned flags = 0; + if (showNS) // techmode { prec = kTimestampPrintLevel_NTFS; if (t.Prec != 0) @@ -512,33 +521,30 @@ prec = kTimestampPrintLevel_NTFS; } } - - ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec); -} - -#ifndef _SFX - -static inline char GetHex(Byte value) -{ - return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10))); -} - -static void HexToString(char *dest, const Byte *data, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) + else { - Byte b = data[i]; - dest[0] = GetHex((Byte)((b >> 4) & 0xF)); - dest[1] = GetHex((Byte)(b & 0xF)); - dest += 2; + // we want same default number of characters, so we disable 'Z' marker: + flags = kTimestampPrintFlags_DisableZ; } - *dest = 0; + + ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec, flags); } +#ifndef Z7_SFX + #endif #define MY_ENDL endl +inline bool IsPropId_for_PathString(UInt32 propId) +{ + return (propId == kpidPath + // || propId == kpidName + || propId == kpidSymLink + || propId == kpidHardLink + || propId == kpidCopyLink); +} + HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { char temp[128]; @@ -575,7 +581,7 @@ { if (!techMode) g_StdOut << temp; - g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString); + g_StdOut.NormalizePrint_UString_Path(FilePath, TempWString, TempAString); if (techMode) g_StdOut << MY_ENDL; continue; @@ -585,12 +591,12 @@ if (f.IsRawProp) { - #ifndef _SFX + #ifndef Z7_SFX const void *data; UInt32 dataSize; UInt32 propType; - RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)); + RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)) if (dataSize != 0) { @@ -600,7 +606,7 @@ { if (propType != NPropDataType::kRaw) return E_FAIL; - #ifndef _SFX + #ifndef Z7_SFX ConvertNtSecureToString((const Byte *)data, dataSize, TempAString); g_StdOut << TempAString; needPrint = false; @@ -631,7 +637,7 @@ else { char hexStr[kMaxDataSize * 2 + 4]; - HexToString(hexStr, (const Byte *)data, dataSize); + ConvertDataToHex_Lower(hexStr, (const Byte *)data, dataSize); g_StdOut << hexStr; } } @@ -654,7 +660,7 @@ break; } default: - RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)); + RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)) } if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) { @@ -695,11 +701,12 @@ { TempWString.SetFromBstr(prop.bstrVal); // do we need multi-line support here ? - g_StdOut.Normalize_UString(TempWString); + if (IsPropId_for_PathString(f.PropID)) + g_StdOut.Normalize_UString_Path(TempWString); + else + g_StdOut.Normalize_UString(TempWString); if (techMode) - { g_StdOut.PrintUString(TempWString, TempAString); - } else PrintUString(f.TextAdjustment, width, TempWString, TempAString); } @@ -786,7 +793,7 @@ value.Val = 0; value.Def = false; CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); + RINOK(archive->GetProperty(index, propID, &prop)) value.Def = ConvertPropVariantToUInt64(prop, value.Val); return S_OK; } @@ -798,7 +805,7 @@ t.Clear(); // t.Def = false; CPropVariant prop; - RINOK(archive->GetProperty(index, kpidMTime, &prop)); + RINOK(archive->GetProperty(index, kpidMTime, &prop)) if (prop.vt == VT_FILETIME) t.Set_From_Prop(prop); else if (prop.vt != VT_EMPTY) @@ -815,7 +822,7 @@ { const char *s; char temp[16]; - if (propID < ARRAY_SIZE(kPropIdToName)) + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) s = kPropIdToName[propID]; else { @@ -855,10 +862,9 @@ } *dest++ = c; } - s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf())); + s.ReleaseBuf_SetEnd((unsigned)(size_t)(dest - s.GetBuf())); } - static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val) { UString s (val); @@ -868,21 +874,34 @@ so << "{"; so << endl; UString_Replace_CRLF_to_LF(s); - so.Normalize_UString__LF_Allowed(s); - so << s; - so << endl; + UString temp; + unsigned start = 0; + for (;;) + { + unsigned size = s.Len() - start; + if (size == 0) + break; + const int next = s.Find(L'\n', start); + if (next >= 0) + size = (unsigned)next - start; + temp.SetFrom(s.Ptr() + start, size); + so.NormalizePrint_UString(temp); + so << endl; + if (next < 0) + break; + start = (unsigned)next + 1; + } so << "}"; } else { - so.Normalize_UString(s); - so << s; + so.NormalizePrint_UString(s); } so << endl; } -static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine) +static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine, bool isPath = false) { so << name << " = "; if (multiLine) @@ -891,12 +910,22 @@ return; } UString s (val); - so.Normalize_UString(s); + if (isPath) + so.Normalize_UString_Path(s); + else + so.Normalize_UString(s); so << s; so << endl; } +static void PrintPropPair_Path(CStdOutStream &so, const wchar_t *path) +{ + PrintPropPair(so, "Path", path, + false, // multiLine + true); // isPath +} + static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop) { UString s; @@ -919,7 +948,7 @@ static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name) { CPropVariant prop; - RINOK(archive->GetArchiveProperty(propID, &prop)); + RINOK(archive->GetArchiveProperty(propID, &prop)) PrintPropertyPair2(so, propID, name, prop); return S_OK; } @@ -957,7 +986,7 @@ const CArcErrorInfo &er = arc.ErrorInfo; so << "--\n"; - PrintPropPair(so, "Path", arc.Path, false); + PrintPropPair_Path(so, arc.Path); if (er.ErrorFormatIndex >= 0) { if (er.ErrorFormatIndex == arc.FormatIndex) @@ -973,20 +1002,20 @@ if (offset != 0) PrintPropNameAndNumber_Signed(so, kpidOffset, offset); IInArchive *archive = arc.Archive; - RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)); + RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)) if (er.TailSize != 0) PrintPropNameAndNumber(so, kpidTailSize, er.TailSize); { UInt32 numProps; - RINOK(archive->GetNumberOfArchiveProperties(&numProps)); + RINOK(archive->GetNumberOfArchiveProperties(&numProps)) for (UInt32 j = 0; j < numProps; j++) { CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); - RINOK(PrintArcProp(so, archive, propID, name)); + RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)) + RINOK(PrintArcProp(so, archive, propID, name)) } } @@ -1002,9 +1031,9 @@ CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); + RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)) CPropVariant prop; - RINOK(archive->GetProperty(mainIndex, propID, &prop)); + RINOK(archive->GetProperty(mainIndex, propID, &prop)) PrintPropertyPair2(so, propID, name, prop); } } @@ -1016,7 +1045,7 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (arcLink.PasswordWasAsked) so << "Cannot open encrypted archive. Wrong password?"; else @@ -1024,7 +1053,7 @@ { if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { - so.NormalizePrint_UString(arcLink.NonOpen_ArcPath); + so.NormalizePrint_UString_Path(arcLink.NonOpen_ArcPath); so << endl; PrintArcTypeError(so, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } @@ -1051,10 +1080,10 @@ bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool &passwordEnabled, UString &password, #endif - #ifndef _SFX + #ifndef Z7_SFX const CObjectVector *props, #endif UInt64 &numErrors, @@ -1067,7 +1096,7 @@ CFieldPrinter fp; if (!techMode) - fp.Init(kStandardFieldTable, ARRAY_SIZE(kStandardFieldTable)); + fp.Init(kStandardFieldTable, Z7_ARRAY_SIZE(kStandardFieldTable)); CListStat2 stat2total; @@ -1101,7 +1130,7 @@ if (g_ErrStream) { *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; - g_ErrStream->NormalizePrint_UString(arcPath); + g_ErrStream->NormalizePrint_UString_Path(arcPath); *g_ErrStream << endl << endl; } numErrors++; @@ -1113,7 +1142,7 @@ if (g_ErrStream) { *g_ErrStream << endl << kError; - g_ErrStream->NormalizePrint_UString(arcPath); + g_ErrStream->NormalizePrint_UString_Path(arcPath); *g_ErrStream << " is not a file" << endl << endl; } numErrors++; @@ -1126,9 +1155,9 @@ CArchiveLink arcLink; COpenCallbackConsole openCallback; - openCallback.Init(&g_StdOut, g_ErrStream, NULL); + openCallback.Init(&g_StdOut, g_ErrStream, NULL, listOptions.DisablePercents); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; @@ -1142,7 +1171,7 @@ */ COpenOptions options; - #ifndef _SFX + #ifndef Z7_SFX options.props = props; #endif options.codecs = codecs; @@ -1155,7 +1184,7 @@ if (enableHeaders) { g_StdOut << endl << kListing; - g_StdOut.NormalizePrint_UString(arcPath); + g_StdOut.NormalizePrint_UString_Path(arcPath); g_StdOut << endl << endl; } @@ -1171,7 +1200,7 @@ if (g_ErrStream) { *g_ErrStream << endl << kError; - g_ErrStream->NormalizePrint_UString(arcPath); + g_ErrStream->NormalizePrint_UString_Path(arcPath); *g_ErrStream << " : "; if (result == S_FALSE) { @@ -1229,7 +1258,7 @@ if (enableHeaders) { - RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)) g_StdOut << endl; if (techMode) @@ -1251,17 +1280,17 @@ if (techMode) { fp.Clear(); - RINOK(fp.AddMainProps(archive)); + RINOK(fp.AddMainProps(archive)) if (arc.GetRawProps) { - RINOK(fp.AddRawProps(arc.GetRawProps)); + RINOK(fp.AddRawProps(arc.GetRawProps)) } } CListStat2 stat2; UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) CReadArcItem item; UStringVector pathParts; @@ -1275,12 +1304,12 @@ if (stdInMode && res == E_INVALIDARG) break; - RINOK(res); + RINOK(res) if (arc.Ask_Aux) { bool isAux; - RINOK(Archive_IsItem_Aux(archive, i, isAux)); + RINOK(Archive_IsItem_Aux(archive, i, isAux)) if (isAux) continue; } @@ -1288,12 +1317,12 @@ bool isAltStream = false; if (arc.Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); + RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)) if (isAltStream && !processAltStreams) continue; } - RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)); + RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)) if (fp.IsDir ? listOptions.ExcludeDirItems : listOptions.ExcludeFileItems) continue; @@ -1302,7 +1331,7 @@ { if (isAltStream) { - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) if (!CensorNode_CheckPath(wildcardCensor, item)) continue; } @@ -1319,9 +1348,9 @@ CListStat st; - RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)); - RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)); - RINOK(GetItemMTime(archive, i, st.MTime)); + RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)) + RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)) + RINOK(GetItemMTime(archive, i, st.MTime)) if (fp.IsDir) stat2.NumDirs++; @@ -1331,7 +1360,7 @@ if (isAltStream && !showAltStreams) continue; - RINOK(fp.PrintItemInfo(i, st)); + RINOK(fp.PrintItemInfo(i, st)) } UInt64 numStreams = stat2.GetNumStreams(); @@ -1359,7 +1388,7 @@ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { g_StdOut << "----------\n"; - PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false); + PrintPropPair_Path(g_StdOut, arcLink.NonOpen_ArcPath); PrintArcTypeError(g_StdOut, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/List.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/List.h 2021-09-27 12:59:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/List.h 2024-06-06 06:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // List.h -#ifndef __LIST_H -#define __LIST_H +#ifndef ZIP7_INC_LIST_H +#define ZIP7_INC_LIST_H #include "../../../Common/Wildcard.h" @@ -11,10 +11,12 @@ { bool ExcludeDirItems; bool ExcludeFileItems; + bool DisablePercents; CListOptions(): ExcludeDirItems(false), - ExcludeFileItems(false) + ExcludeFileItems(false), + DisablePercents(false) {} }; @@ -28,10 +30,10 @@ bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool &passwordEnabled, UString &password, #endif - #ifndef _SFX + #ifndef Z7_SFX const CObjectVector *props, #endif UInt64 &errors, diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/Main.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Main.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/Main.cpp 2022-04-29 18:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/Main.cpp 2025-01-24 07:00:00.000000000 +0000 @@ -5,13 +5,39 @@ #include "../../../Common/MyWindows.h" #ifdef _WIN32 -#include + +#ifndef Z7_OLD_WIN_SDK + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include #else +#include +#endif + +#else // Z7_OLD_WIN_SDK + +typedef struct { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS; +typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + +#endif // Z7_OLD_WIN_SDK + +#else // _WIN32 #include #include #include #include -#endif +#endif // _WIN32 #include "../../../../C/CpuArch.h" @@ -28,13 +54,14 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/TimeUtils.h" +#include "../../../Windows/FileDir.h" #include "../Common/ArchiveCommandLine.h" #include "../Common/Bench.h" #include "../Common/ExitCode.h" #include "../Common/Extract.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../Common/LoadCodecs.h" #endif @@ -48,7 +75,7 @@ #include "OpenCallbackConsole.h" #include "UpdateCallbackConsole.h" -#ifdef PROG_VARIANT_R +#ifdef Z7_PROG_VARIANT_R #include "../../../../C/7zVersion.h" #else #include "../../MyVersion.h" @@ -59,7 +86,9 @@ using namespace NCommandLineParser; #ifdef _WIN32 -HINSTANCE g_hInstance = 0; +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; #endif extern CStdOutStream *g_StdStream; @@ -71,19 +100,21 @@ extern unsigned g_NumHashers; extern const CHasherInfo *g_Hashers[]; -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS +extern +const CExternalCodecs *g_ExternalCodecs_Ptr; const CExternalCodecs *g_ExternalCodecs_Ptr; #endif DECLARE_AND_SET_CLIENT_VERSION_VAR -#if defined(PROG_VARIANT_Z) +#if defined(Z7_PROG_VARIANT_Z) #define PROG_POSTFIX "z" #define PROG_POSTFIX_2 " (z)" -#elif defined(PROG_VARIANT_R) +#elif defined(Z7_PROG_VARIANT_R) #define PROG_POSTFIX "r" #define PROG_POSTFIX_2 " (r)" -#elif !defined(EXTERNAL_CODECS) +#elif defined(Z7_PROG_VARIANT_A) || !defined(Z7_EXTERNAL_CODECS) #define PROG_POSTFIX "a" #define PROG_POSTFIX_2 " (a)" #else @@ -117,27 +148,34 @@ "\n" "\n" " -- : Stop switches and @listfile parsing\n" - " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" - " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" + " -ai[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : Include archives\n" + " -ax[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : eXclude archives\n" " -ao{a|s|t|u} : set Overwrite mode\n" " -an : disable archive_name field\n" " -bb[0-3] : set output log level\n" " -bd : disable progress indicator\n" " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" " -bt : show execution time statistics\n" - " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" + " -i[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : Include filenames\n" " -m{Parameters} : set compression Method\n" " -mmt[N] : set number of CPU threads\n" " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n" " -o{Directory} : set Output directory\n" - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO " -p{Password} : set Password\n" #endif " -r[-|0] : Recurse subdirectories for name search\n" " -sa{a|e|s} : set Archive name mode\n" - " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" + " -scc{UTF-8|WIN|DOS} : set charset for console input/output\n" " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" - " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" + " -scrc[CRC32|CRC64|SHA256" +#ifndef Z7_PROG_VARIANT_R + "|SHA1|XXH64" +#ifdef Z7_PROG_VARIANT_Z + "|BLAKE2SP" +#endif +#endif + "|*] : set hash function for x, e, h commands\n" " -sdel : delete files after compression\n" " -seml[.] : send archive by email\n" " -sfx[{name}] : Create SFX archive\n" @@ -151,7 +189,7 @@ " -so : write data to stdout\n" " -spd : disable wildcard matching for file names\n" " -spe : eliminate duplication of root folder for extract command\n" - " -spf : use fully qualified file paths\n" + " -spf[2] : use fully qualified file paths\n" " -ssc[-] : set sensitive case mode\n" " -sse : stop archive creating, if it can't open some input file\n" " -ssp : do not change Last Access Time of source files while archiving\n" @@ -163,7 +201,7 @@ " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" " -v{Size}[b|k|m|g] : Create volumes\n" " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" - " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n" + " -x[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : eXclude filenames\n" " -y : assume Yes on all queries\n"; // --------------------------- @@ -175,9 +213,11 @@ static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type"; // static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type"; +#ifndef Z7_EXTRACT_ONLY #define kDefaultSfxModule "7zCon.sfx" +#endif -MY_ATTR_NORETURN +Z7_ATTR_NORETURN static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) { if (g_ErrStream) @@ -213,10 +253,50 @@ #ifdef __ARM_ARCH << " arm_v:" << __ARM_ARCH + #if (__ARM_ARCH == 8) + // for macos: + #if defined(__ARM_ARCH_8_9__) + << ".9" + #elif defined(__ARM_ARCH_8_8__) + << ".8" + #elif defined(__ARM_ARCH_8_7__) + << ".7" + #elif defined(__ARM_ARCH_8_6__) + << ".6" + #elif defined(__ARM_ARCH_8_5__) + << ".5" + #elif defined(__ARM_ARCH_8_4__) + << ".4" + #elif defined(__ARM_ARCH_8_3__) + << ".3" + #elif defined(__ARM_ARCH_8_2__) + << ".2" + #elif defined(__ARM_ARCH_8_1__) + << ".1" + #endif + #endif + + #if defined(__ARM_ARCH_PROFILE) && \ + ( __ARM_ARCH_PROFILE >= 'A' && __ARM_ARCH_PROFILE <= 'Z' \ + || __ARM_ARCH_PROFILE >= 65 && __ARM_ARCH_PROFILE <= 65 + 25) + << "-" << (char)__ARM_ARCH_PROFILE + #endif + #ifdef __ARM_ARCH_ISA_THUMB << " thumb:" << __ARM_ARCH_ISA_THUMB #endif #endif + + #ifdef _MIPS_ARCH + << " mips_arch:" << _MIPS_ARCH + #endif + #ifdef __mips_isa_rev + << " mips_isa_rev:" << __mips_isa_rev + #endif + + #ifdef __iset__ + << " e2k_v:" << __iset__ + #endif ; @@ -247,9 +327,17 @@ { const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors(); *so << " Threads:" << numCpus; + const UInt64 openMAX= NWindows::NSystem::Get_File_OPEN_MAX(); + *so << " OPEN_MAX:" << openMAX; + { + FString temp; + NDir::MyGetTempPath(temp); + if (!temp.IsEqualTo(STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR)) + *so << " temp_path:" << temp; + } } - #ifdef _7ZIP_ASM + #ifdef Z7_7ZIP_ASM *so << ", ASM"; #endif @@ -313,6 +401,17 @@ PrintStringRight(so, s, size); } +#ifdef Z7_EXTERNAL_CODECS +static void PrintNumber(CStdOutStream &so, UInt32 val, unsigned numDigits) +{ + AString s; + s.Add_UInt32(val); + while (s.Len() < numDigits) + s.InsertAtFront('0'); + so << s; +} +#endif + static void PrintLibIndex(CStdOutStream &so, int libIndex) { if (libIndex >= 0) @@ -330,16 +429,11 @@ so << ' '; } -static inline char GetHex(unsigned val) -{ - return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10))); -} - static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) { FOR_VECTOR(i, pc.Paths) { - so.NormalizePrint_UString(fs2us(pc.Paths[i])); + so.NormalizePrint_UString_Path(fs2us(pc.Paths[i])); so << " : "; so << NError::MyFormatMessage(pc.Codes[i]) << endl; } @@ -480,8 +574,12 @@ *g_StdStream << " " << s << " Memory ="; PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); *g_StdStream << " MB"; - - #ifdef _7ZIP_LARGE_PAGES + /* + *g_StdStream << " ="; + PrintNum(SHIFT_SIZE_VALUE(val, 10), 9); + *g_StdStream << " KB"; + */ + #ifdef Z7_LARGE_PAGES AString lp; Add_LargePages_String(lp); if (!lp.IsEmpty()) @@ -516,6 +614,8 @@ #ifndef UNDER_CE +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + PROCESS_MEMORY_COUNTERS m; memset(&m, 0, sizeof(m)); BOOL memDefined = FALSE; @@ -530,22 +630,27 @@ The program with K32GetProcessMemoryInfo will not work on systems before Win7 // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); */ - - HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); - Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo) - (void *)::GetProcAddress(kern, "K32GetProcessMemoryInfo"); + const HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); + Func_GetProcessMemoryInfo + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, kern, + "K32GetProcessMemoryInfo"); if (!my_GetProcessMemoryInfo) { - HMODULE lib = LoadLibraryW(L"Psapi.dll"); + const HMODULE lib = LoadLibraryW(L"Psapi.dll"); if (lib) - my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)(void *)::GetProcAddress(lib, "GetProcessMemoryInfo"); + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, lib, + "GetProcessMemoryInfo"); } if (my_GetProcessMemoryInfo) memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); // FreeLibrary(lib); - - Func_QueryProcessCycleTime my_QueryProcessCycleTime = (Func_QueryProcessCycleTime) - (void *)::GetProcAddress(kern, "QueryProcessCycleTime"); + const + Func_QueryProcessCycleTime + my_QueryProcessCycleTime = Z7_GET_PROC_ADDRESS( + Func_QueryProcessCycleTime, kern, + "QueryProcessCycleTime"); if (my_QueryProcessCycleTime) cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime); } @@ -595,6 +700,7 @@ #ifndef UNDER_CE if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); #endif + *g_StdStream << endl; } @@ -603,7 +709,7 @@ static UInt64 Get_timeofday_us() { struct timeval now; - if (gettimeofday(&now, 0 ) == 0) + if (gettimeofday(&now, NULL) == 0) return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec; return 0; } @@ -666,7 +772,7 @@ *g_StdStream << '%'; } -static void PrintStat(UInt64 startTime) +static void PrintStat(const UInt64 startTime) { tms t; /* clock_t res = */ times(&t); @@ -722,9 +828,23 @@ #endif #ifndef _WIN32 - UInt64 startTime = Get_timeofday_us(); + const UInt64 startTime = Get_timeofday_us(); #endif + /* + { + g_StdOut << "DWORD:" << (unsigned)sizeof(DWORD); + g_StdOut << " LONG:" << (unsigned)sizeof(LONG); + g_StdOut << " long:" << (unsigned)sizeof(long); + #ifdef _WIN64 + // g_StdOut << " long long:" << (unsigned)sizeof(long long); + #endif + g_StdOut << " int:" << (unsigned)sizeof(int); + g_StdOut << " void*:" << (unsigned)sizeof(void *); + g_StdOut << endl; + } + */ + UStringVector commandStrings; #ifdef _WIN32 @@ -737,11 +857,11 @@ for (int i = 0; i < numArgs; i++) { AString a (args[i]); - /* +#if 0 printf("\n%d %s :", i, a.Ptr()); for (unsigned k = 0; k < a.Len(); k++) printf(" %2x", (unsigned)(Byte)a[k]); - */ +#endif const UString s = MultiByteToUnicodeString(a); commandStrings.Add(s); } @@ -778,7 +898,7 @@ CStdOutStream *percentsStream = NULL; if (options.Number_for_Percents != k_OutStream_disabled) - percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;; + percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut; if (options.HelpMode) { @@ -788,9 +908,12 @@ if (options.EnableHeaders) { - ShowCopyrightAndHelp(g_StdStream, false); - if (!parser.Parse1Log.IsEmpty()) - *g_StdStream << parser.Parse1Log; + if (g_StdStream) + { + ShowCopyrightAndHelp(g_StdStream, false); + if (!parser.Parse1Log.IsEmpty()) + *g_StdStream << parser.Parse1Log; + } } parser.Parse2(options); @@ -833,6 +956,8 @@ if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp; if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp; } + g_StdOut.ListPathSeparatorSlash = options.ListPathSeparatorSlash; + g_StdErr.ListPathSeparatorSlash = options.ListPathSeparatorSlash; unsigned percentsNameLevel = 1; if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) @@ -847,15 +972,16 @@ #if !defined(UNDER_CE) CONSOLE_SCREEN_BUFFER_INFO consoleInfo; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) - consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X; + consoleWidth = (USHORT)consoleInfo.dwSize.X; #endif #else +#if !defined(__sun) struct winsize w; if (ioctl(0, TIOCGWINSZ, &w) == 0) consoleWidth = w.ws_col; - +#endif #endif } @@ -866,9 +992,9 @@ ThrowException_if_Error(codecs->Load()); Codecs_AddHashArcHandler(codecs); - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { - g_ExternalCodecs_Ptr = &__externalCodecs; + g_ExternalCodecs_Ptr = &_externalCodecs; UString s; codecs->GetCodecsErrorMessage(s); if (!s.IsEmpty()) @@ -886,7 +1012,7 @@ || options.Command.CommandType == NCommandType::kList || options.Command.IsFromUpdateGroup())) { - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (!codecs->MainDll_ErrorPath.IsEmpty()) { UString s ("Can't load module: "); @@ -918,12 +1044,12 @@ // excludedFormats.Sort(); } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (isExtractGroupCommand || options.Command.IsFromUpdateGroup() || options.Command.CommandType == NCommandType::kHash || options.Command.CommandType == NCommandType::kBenchmark) - ThrowException_if_Error(__externalCodecs.Load()); + ThrowException_if_Error(_externalCodecs.Load()); #endif int retCode = NExitCode::kSuccess; @@ -943,12 +1069,16 @@ CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); unsigned i; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS so << endl << "Libs:" << endl; for (i = 0; i < codecs->Libs.Size(); i++) { PrintLibIndex(so, (int)i); - so << ' ' << codecs->Libs[i].Path << endl; + const CCodecLib &lib = codecs->Libs[i]; + // if (lib.Version != 0) + so << ": " << (lib.Version >> 16) << "."; + PrintNumber(so, lib.Version & 0xffff, 2); + so << " : " << lib.Path << endl; } #endif @@ -963,7 +1093,7 @@ { const CArcInfoEx &arc = codecs->Formats[i]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS PrintLibIndex(so, arc.LibIndex); #else so << " "; @@ -1002,7 +1132,7 @@ { s += " ("; s += ext.AddExt; - s += ')'; + s.Add_Char(')'); } } @@ -1025,15 +1155,15 @@ { if (j != 0) so << ' '; - Byte b = sig[j]; + const unsigned b = sig.ConstData()[j]; if (b > 0x20 && b < 0x80) { so << (char)b; } else { - so << GetHex((b >> 4) & 0xF); - so << GetHex(b & 0xF); + so << GET_HEX_CHAR_UPPER(b >> 4); + so << GET_HEX_CHAR_UPPER(b & 15); } } } @@ -1063,10 +1193,10 @@ } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS UInt32 numMethods; - if (codecs->GetNumMethods(&numMethods) == S_OK) + if (_externalCodecs.GetCodecs->GetNumMethods(&numMethods) == S_OK) for (UInt32 j = 0; j < numMethods; j++) { PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); @@ -1110,9 +1240,9 @@ so << ' ' << codec.Name << endl; } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS - numMethods = codecs->GetNumHashers(); + numMethods = _externalCodecs.GetHashers->GetNumHashers(); for (UInt32 j = 0; j < numMethods; j++) { PrintLibIndex(so, codecs->GetHasherLibIndex(j)); @@ -1153,7 +1283,9 @@ { CExtractScanConsole scan; - scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream); + scan.Init(options.EnableHeaders ? g_StdStream : NULL, + g_ErrStream, percentsStream, + options.DisablePercents); scan.SetWindowWidth(consoleWidth); if (g_StdStream && options.EnableHeaders) @@ -1198,12 +1330,12 @@ CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr extractCallback = ecs; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = options.PasswordEnabled; ecs->Password = options.Password; #endif - ecs->Init(g_StdStream, g_ErrStream, percentsStream); + ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); ecs->LogLevel = options.LogLevel; @@ -1216,7 +1348,7 @@ COpenCallbackConsole openCallback; openCallback.Init(g_StdStream, g_ErrStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = options.PasswordEnabled; openCallback.Password = options.Password; #endif @@ -1230,7 +1362,7 @@ eo.YesToAll = options.YesToAll; eo.TestMode = options.Command.IsTestCommand(); - #ifndef _SFX + #ifndef Z7_SFX eo.Properties = options.Properties; #endif @@ -1254,7 +1386,9 @@ ArchivePathsSorted, ArchivePathsFullSorted, options.Censor.Pairs.Front().Head, - eo, ecs, ecs, hashCalc, errorMessage, stat); + eo, + ecs, ecs, ecs, + hashCalc, errorMessage, stat); ecs->ClosePercents(); @@ -1365,6 +1499,7 @@ CListOptions lo; lo.ExcludeDirItems = options.Censor.ExcludeDirItems; lo.ExcludeFileItems = options.Censor.ExcludeFileItems; + lo.DisablePercents = options.DisablePercents; hresultMain = ListArchives( lo, @@ -1379,7 +1514,7 @@ options.Censor.Pairs.Front().Head, options.EnableHeaders, options.TechMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO options.PasswordEnabled, options.Password, #endif @@ -1401,14 +1536,17 @@ } else if (options.Command.IsFromUpdateGroup()) { + #ifdef Z7_EXTRACT_ONLY + throw "update commands are not implemented"; + #else CUpdateOptions &uo = options.UpdateOptions; if (uo.SfxMode && uo.SfxModule.IsEmpty()) uo.SfxModule = kDefaultSfxModule; COpenCallbackConsole openCallback; - openCallback.Init(g_StdStream, g_ErrStream, percentsStream); + openCallback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool passwordIsDefined = (options.PasswordEnabled && !options.Password.IsEmpty()); openCallback.PasswordIsDefined = passwordIsDefined; @@ -1422,7 +1560,7 @@ if (percentsStream) callback.SetWindowWidth(consoleWidth); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO callback.PasswordIsDefined = passwordIsDefined; callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); callback.Password = options.Password; @@ -1431,7 +1569,7 @@ callback.StdOutMode = uo.StdOutMode; callback.Init( // NULL, - g_StdStream, g_ErrStream, percentsStream); + g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); CUpdateErrorInfo errorInfo; @@ -1456,6 +1594,7 @@ g_StdStream, se, true // options.EnableHeaders ); + #endif } else if (options.Command.CommandType == NCommandType::kHash) { @@ -1465,7 +1604,7 @@ if (percentsStream) callback.SetWindowWidth(consoleWidth); - callback.Init(g_StdStream, g_ErrStream, percentsStream); + callback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); callback.PrintHeaders = options.EnableHeaders; callback.PrintFields = options.ListFields; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/MainAr.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/MainAr.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/MainAr.cpp 2021-02-09 19:48:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/MainAr.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -5,6 +5,7 @@ #ifdef _WIN32 #include "../../../../C/DllSecur.h" #endif +#include "../../../../C/CpuArch.h" #include "../../../Common/MyException.h" #include "../../../Common/StdOutStream.h" @@ -56,7 +57,50 @@ #define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError; #endif -int MY_CDECL main +static inline bool CheckIsa() +{ + // __try + { + // some compilers (e2k) support SSE/AVX, but cpuid() can be unavailable or return lower isa support +#ifdef MY_CPU_X86_OR_AMD64 + #if 0 && (defined(__AVX512F__) && defined(__AVX512VL__)) + if (!CPU_IsSupported_AVX512F_AVX512VL()) + return false; + #elif defined(__AVX2__) + if (!CPU_IsSupported_AVX2()) + return false; + #elif defined(__AVX__) + if (!CPU_IsSupported_AVX()) + return false; + #elif defined(__SSE2__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) + if (!CPU_IsSupported_SSE2()) + return false; + #elif defined(__SSE__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 1) + if (!CPU_IsSupported_SSE() || + !CPU_IsSupported_CMOV()) + return false; + #endif +#endif + /* + __asm + { + _emit 0fH + _emit 038H + _emit 0cbH + _emit (0c0H + 0 * 8 + 0) + } + */ + return true; + } + /* + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + */ +} + +int Z7_CDECL main ( #ifndef _WIN32 int numArgs, char *args[] @@ -66,6 +110,14 @@ g_ErrStream = &g_StdErr; g_StdStream = &g_StdOut; + // #if (defined(_MSC_VER) && defined(_M_IX86)) + if (!CheckIsa()) + { + PrintError("ERROR: processor doesn't support required ISA extension"); + return NExitCode::kFatalError; + } + // #endif + NT_CHECK NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; @@ -88,11 +140,13 @@ PrintError(kMemoryExceptionMessage); return (NExitCode::kMemoryError); } +/* catch(const NConsoleClose::CCtrlBreakException &) { PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } +*/ catch(const CMessagePathException &e) { PrintError(kException_CmdLine_Error_Message); @@ -119,7 +173,7 @@ } return (NExitCode::kFatalError); } - catch(NExitCode::EEnum &exitCode) + catch(NExitCode::EEnum exitCode) { FlushStreams(); if (g_ErrStream) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 2017-02-17 23:42:14.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -77,17 +77,17 @@ } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) { *password = NULL; - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) if (!PasswordIsDefined) { ClosePercents(); - RINOK(GetPassword_HRESULT(_so, Password)); + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } return StringToBstr(Password, password); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.h 2019-08-24 11:15:53.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/OpenCallbackConsole.h 2024-06-06 06:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // OpenCallbackConsole.h -#ifndef __OPEN_CALLBACK_CONSOLE_H -#define __OPEN_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_OPEN_CALLBACK_CONSOLE_H +#define ZIP7_INC_OPEN_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -17,12 +17,12 @@ CStdOutStream *_so; CStdOutStream *_se; - bool _totalFilesDefined; - // bool _totalBytesDefined; // UInt64 _totalFiles; UInt64 _totalBytes; + bool _totalFilesDefined; + // bool _totalBytesDefined; - bool NeedPercents() const { return _percent._so != NULL; } + bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; } public: @@ -35,12 +35,12 @@ } COpenCallbackConsole(): + _totalBytes(0), _totalFilesDefined(false), // _totalBytesDefined(false), - _totalBytes(0), MultiArcMode(false) - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , PasswordIsDefined(false) // , PasswordWasAsked(false) #endif @@ -49,16 +49,21 @@ virtual ~COpenCallbackConsole() {} - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) { _so = outStream; _se = errorStream; _percent._so = percentStream; + _percent.DisablePrint = disablePercents; } - INTERFACE_IOpenCallbackUI(;) + Z7_IFACE_IMP(IOpenCallbackUI) - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordIsDefined; // bool PasswordWasAsked; UString Password; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.cpp 2022-04-13 08:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.cpp 2024-06-17 11:00:00.000000000 +0000 @@ -79,7 +79,7 @@ while (size < kPercentsSize) { - _s += ' '; + _s.Add_Space(); size++; } @@ -88,6 +88,8 @@ void CPercentPrinter::Print() { + if (DisablePrint) + return; DWORD tick = 0; if (_tickStep != 0) tick = GetTickCount(); @@ -125,8 +127,8 @@ char s[32]; ConvertUInt64ToString(Files, s); // unsigned size = (unsigned)strlen(s); - // for (; size < 3; size++) _s += ' '; - _s += ' '; + // for (; size < 3; size++) _s.Add_Space(); + _s.Add_Space(); _s += s; // _s += "f"; } @@ -134,16 +136,16 @@ if (!Command.IsEmpty()) { - _s += ' '; + _s.Add_Space(); _s += Command; } if (!FileName.IsEmpty() && _s.Len() < MaxLen) { - _s += ' '; + _s.Add_Space(); _tempU = FileName; - _so->Normalize_UString(_tempU); + _so->Normalize_UString_Path(_tempU); _so->Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() > MaxLen) { @@ -157,7 +159,7 @@ _tempU = FileName; _tempU.Delete(len / 2, _tempU.Len() - len); _tempU.Insert(len / 2, L" . "); - _so->Normalize_UString(_tempU); + _so->Normalize_UString_Path(_tempU); _so->Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() <= MaxLen) break; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.h 2014-12-20 13:23:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/PercentPrinter.h 2024-10-19 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // PercentPrinter.h -#ifndef __PERCENT_PRINTER_H -#define __PERCENT_PRINTER_H +#ifndef ZIP7_INC_PERCENT_PRINTER_H +#define ZIP7_INC_PERCENT_PRINTER_H #include "../../../Common/StdOutStream.h" @@ -26,6 +26,13 @@ class CPercentPrinter: public CPercentPrinterState { +public: + CStdOutStream *_so; + bool DisablePrint; + bool NeedFlush; + unsigned MaxLen; + +private: UInt32 _tickStep; DWORD _prevTick; @@ -41,16 +48,13 @@ void GetPercents(); public: - CStdOutStream *_so; - - bool NeedFlush; - unsigned MaxLen; CPercentPrinter(UInt32 tickStep = 200): - _tickStep(tickStep), - _prevTick(0), + DisablePrint(false), NeedFlush(true), - MaxLen(80 - 1) + MaxLen(80 - 1), + _tickStep(tickStep), + _prevTick(0) {} ~CPercentPrinter(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/StdAfx.h 2014-04-25 10:55:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 2022-04-29 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 2024-10-20 09:00:00.000000000 +0000 @@ -7,7 +7,7 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileName.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -19,7 +19,7 @@ using namespace NWindows; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -136,7 +136,7 @@ { if (_so) { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) *_so << endl; } } @@ -147,10 +147,10 @@ if (_se) { *_se << kError; - _se->NormalizePrint_wstr(name); + _se->NormalizePrint_wstr_Path(name); *_se << endl; HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); + RINOK(res) _se->Flush(); } } @@ -191,7 +191,7 @@ *_se << endl << (isWarning ? kWarning : kError) << NError::MyFormatMessage(systemError) << endl; - _se->NormalizePrint_UString(fs2us(path)); + _se->NormalizePrint_UString_Path(fs2us(path)); *_se << endl << endl; _se->Flush(); } @@ -312,7 +312,7 @@ { *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); if (name) - _so->NormalizePrint_wstr(name); + _so->NormalizePrint_wstr_Path(name); else *_so << k_StdOut_ArcName; *_so << endl << endl; @@ -333,6 +333,12 @@ s += "Archive size: "; PrintSize_bytes_Smart(s, st.OutArcFileSize); s.Add_LF(); + if (st.IsMultiVolMode) + { + s += "Volumes: "; + s.Add_UInt32(st.NumVolumes); + s.Add_LF(); + } *_so << endl; *_so << s; // *_so << endl; @@ -355,6 +361,119 @@ } + +HRESULT CUpdateCallbackConsole::MoveArc_UpdateStatus() +{ + if (NeedPercents()) + { + AString &s = _percent.Command; + s = " : "; + s.Add_UInt64(_arcMoving_percents); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent.Print(); + } + + // we ignore single Ctrl-C, if (_arcMoving_updateMode) mode + // because we want to get good final archive instead of temp archive. + if (NConsoleClose::g_BreakCounter == 1 && _arcMoving_updateMode) + return S_OK; + return CheckBreak(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Start( + const wchar_t *srcTempPath, const wchar_t *destFinalPath, + UInt64 size, Int32 updateMode) +{ +#if 0 // 1 : for debug + if (LogLevel > 0 && _so) + { + ClosePercents_for_so(); + *_so << "Temporary archive moving:" << endl; + _tempU = srcTempPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + _tempU = destFinalPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + } +#else + UNUSED_VAR(srcTempPath) + UNUSED_VAR(destFinalPath) +#endif + + _arcMoving_updateMode = updateMode; + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize) +{ +#if 0 // 1 : for debug + if (_so) + { + ClosePercents_for_so(); + *_so << totalSize << " : " << currentSize << endl; + } +#endif + + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + // totalSize = (UInt64)(Int64)-1; // for debug + + if (percents == _arcMoving_percents) + return CheckBreak(); + _arcMoving_current = currentSize; + _arcMoving_total = totalSize; + _arcMoving_percents = percents; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Finish() +{ + // _arcMoving_percents = 0; + if (NeedPercents()) + { + _percent.Command.Empty(); + _percent.Print(); + } + // it can return delayed user break (E_ABORT) status, + // if it ignored single CTRL+C in MoveArc_Progress(). + return CheckBreak(); +} + + + HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) { if (LogLevel > 0 && _so) @@ -373,7 +492,7 @@ _tempA.Add_Space(); *_so << _tempA; _tempU = fs2us(path); - _so->Normalize_UString(_tempU); + _so->Normalize_UString_Path(_tempU); _so->PrintUString(_tempU, _tempA); *_so << endl; if (NeedFlush) @@ -510,7 +629,7 @@ _tempU = name; if (isDir) NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU); - _so->Normalize_UString(_tempU); + _so->Normalize_UString_Path(_tempU); } _so->PrintUString(_tempU, _tempA); *_so << endl; @@ -636,7 +755,7 @@ AString s; SetExtractErrorMessage(opRes, isEncrypted, s); *_se << s << " : " << endl; - _se->NormalizePrint_wstr(name); + _se->NormalizePrint_wstr_Path(name); *_se << endl << endl; _se->Flush(); } @@ -681,12 +800,12 @@ /* HRESULT CUpdateCallbackConsole::SetPassword(const UString & - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO password #endif ) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO PasswordIsDefined = true; Password = password; #endif @@ -700,7 +819,7 @@ *password = NULL; - #ifdef _NO_CRYPTO + #ifdef Z7_NO_CRYPTO *passwordIsDefined = false; return S_OK; @@ -711,7 +830,7 @@ { if (AskPassword) { - RINOK(GetPassword_HRESULT(_so, Password)); + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } } @@ -729,7 +848,7 @@ *password = NULL; - #ifdef _NO_CRYPTO + #ifdef Z7_NO_CRYPTO return E_NOTIMPL; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.h 2022-04-29 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UpdateCallbackConsole.h 2024-10-20 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdateCallbackConsole.h -#ifndef __UPDATE_CALLBACK_CONSOLE_H -#define __UPDATE_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H +#define ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -26,32 +26,34 @@ } }; + class CCallbackConsoleBase { -protected: - CPercentPrinter _percent; + void CommonError(const FString &path, DWORD systemError, bool isWarning); +protected: CStdOutStream *_so; CStdOutStream *_se; - void CommonError(const FString &path, DWORD systemError, bool isWarning); - // void CommonError(const char *message); - HRESULT ScanError_Base(const FString &path, DWORD systemError); HRESULT OpenFileError_Base(const FString &name, DWORD systemError); HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); public: - bool NeedPercents() const { return _percent._so != NULL; }; - bool StdOutMode; - bool NeedFlush; unsigned PercentsNameLevel; unsigned LogLevel; +protected: AString _tempA; UString _tempU; + CPercentPrinter _percent; + +public: + CErrorPathCodes FailedFiles; + CErrorPathCodes ScanErrors; + UInt64 NumNonOpenFiles; CCallbackConsoleBase(): StdOutMode(false), @@ -61,15 +63,21 @@ NumNonOpenFiles(0) {} + bool NeedPercents() const { return _percent._so != NULL; } void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) { FailedFiles.Clear(); _so = outStream; _se = errorStream; _percent._so = percentStream; + _percent.DisablePrint = disablePercents; } void ClosePercents2() @@ -84,39 +92,50 @@ _percent.ClosePrint(false); } - CErrorPathCodes FailedFiles; - CErrorPathCodes ScanErrors; - UInt64 NumNonOpenFiles; - HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog); // void PrintInfoLine(const UString &s); // void PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value); }; -class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase + +class CUpdateCallbackConsole Z7_final: + public IUpdateCallbackUI2, + public CCallbackConsoleBase { // void PrintPropPair(const char *name, const wchar_t *val); + Z7_IFACE_IMP(IUpdateCallbackUI) + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IUpdateCallbackUI2) + + HRESULT MoveArc_UpdateStatus(); + + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + Int32 _arcMoving_updateMode; public: bool DeleteMessageWasShown; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordIsDefined; - UString Password; bool AskPassword; + UString Password; #endif CUpdateCallbackConsole(): - DeleteMessageWasShown(false) - #ifndef _NO_CRYPTO + _arcMoving_total(0) + , _arcMoving_current(0) + , _arcMoving_percents(0) + , _arcMoving_updateMode(0) + , DeleteMessageWasShown(false) + #ifndef Z7_NO_CRYPTO , PasswordIsDefined(false) , AskPassword(false) #endif {} - virtual ~CUpdateCallbackConsole() {} - /* void Init(CStdOutStream *outStream) { @@ -124,7 +143,6 @@ } */ // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); } - INTERFACE_IUpdateCallbackUI2(;) }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.cpp 2021-01-25 09:25:39.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -49,6 +49,7 @@ case kNoAll: return NUserAnswerMode::kNoAll; case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll; case kQuit: return NUserAnswerMode::kQuit; + default: break; } } } @@ -73,19 +74,26 @@ #ifdef MY_DISABLE_ECHO - HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + const HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + + /* + GetStdHandle() returns + INVALID_HANDLE_VALUE: If the function fails. + NULL : If an application does not have associated standard handles, + such as a service running on an interactive desktop, + and has not redirected them. */ bool wasChanged = false; DWORD mode = 0; - if (console != INVALID_HANDLE_VALUE && console != 0) + if (console != INVALID_HANDLE_VALUE && console != NULL) if (GetConsoleMode(console, &mode)) wasChanged = (SetConsoleMode(console, mode & ~(DWORD)ENABLE_ECHO_INPUT) != 0); - bool res = g_StdIn.ScanUStringUntilNewLine(psw); + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); if (wasChanged) SetConsoleMode(console, mode); #else - bool res = g_StdIn.ScanUStringUntilNewLine(psw); + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.h 2017-02-17 23:43:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/UserInputUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UserInputUtils.h -#ifndef __USER_INPUT_UTILS_H -#define __USER_INPUT_UTILS_H +#ifndef ZIP7_INC_USER_INPUT_UTILS_H +#define ZIP7_INC_USER_INPUT_UTILS_H #include "../../../Common/StdOutStream.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/makefile 2021-10-07 18:27:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,6 +1,6 @@ PROG = 7z.exe CFLAGS = $(CFLAGS) \ - -DEXTERNAL_CODECS \ + -DZ7_EXTERNAL_CODECS \ COMMON_OBJS = \ $O\CommandLineParser.obj \ @@ -42,6 +42,7 @@ $O\FilterCoder.obj \ $O\LimitedStreams.obj \ $O\MethodProps.obj \ + $O\MultiOutStream.obj \ $O\ProgressUtils.obj \ $O\PropId.obj \ $O\StreamObjects.obj \ @@ -58,10 +59,10 @@ C_OBJS = $(C_OBJS) \ $O\Alloc.obj \ $O\CpuArch.obj \ - $O\Sort.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../Sort.mak" !include "Console.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Console/makefile.gcc 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile.gcc --- 7zip-22.01+dfsg/CPP/7zip/UI/Console/makefile.gcc 2022-07-14 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Console/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -20,7 +20,7 @@ ifdef ST_MODE -LOCAL_FLAGS_ST = -D_7ZIP_ST +LOCAL_FLAGS_ST = -DZ7_ST ifdef IS_MINGW MT_OBJS = \ @@ -38,14 +38,15 @@ -LOCAL_FLAGS_WIN= +LOCAL_FLAGS_SYS= ifdef IS_MINGW -LOCAL_FLAGS_WIN = \ - -D_7ZIP_LARGE_PAGES \ - -DWIN_LONG_PATH \ - -DSUPPORT_DEVICE_FILE \ +LOCAL_FLAGS_SYS = \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES +# -DZ7_LONG_PATH SYS_OBJS = \ $O/FileSystem.o \ @@ -64,9 +65,9 @@ LOCAL_FLAGS = \ - $(LOCAL_FLAGS_WIN) \ + $(LOCAL_FLAGS_SYS) \ $(LOCAL_FLAGS_ST) \ - -DEXTERNAL_CODECS \ + -DZ7_EXTERNAL_CODECS \ @@ -147,6 +148,7 @@ $O/LimitedStreams.o \ $O/MethodId.o \ $O/MethodProps.o \ + $O/MultiOutStream.o \ $O/OffsetStream.o \ $O/OutBuffer.o \ $O/ProgressUtils.o \ diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.cpp 2022-05-26 11:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.cpp 2024-11-26 11:00:00.000000000 +0000 @@ -9,12 +9,12 @@ #include "../../../Windows/COM.h" #include "../../../Windows/DLL.h" #include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" #include "../../../Windows/FileName.h" -#include "../../../Windows/MemoryGlobal.h" #include "../../../Windows/Menu.h" #include "../../../Windows/ProcessUtils.h" -#include "../../../Windows/Shell.h" + +// for IS_INTRESOURCE(): +#include "../../../Windows/Window.h" #include "../../PropID.h" @@ -24,11 +24,8 @@ #include "../Common/ZipRegistry.h" #include "../FileManager/FormatUtils.h" -#include "../FileManager/PropertyName.h" - -#ifdef LANG #include "../FileManager/LangUtils.h" -#endif +#include "../FileManager/PropertyName.h" #include "ContextMenu.h" #include "ContextMenuFlags.h" @@ -36,6 +33,7 @@ #include "resource.h" + // #define SHOW_DEBUG_CTX_MENU #ifdef SHOW_DEBUG_CTX_MENU @@ -56,50 +54,117 @@ extern HINSTANCE g_hInstance; #endif +#ifdef UNDER_CE + #define MY_IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0) +#else + #define MY_IS_INTRESOURCE(_r) IS_INTRESOURCE(_r) +#endif + + #ifdef SHOW_DEBUG_CTX_MENU -void Print_Ptr(void *p, char *s) +static void PrintStringA(const char *name, LPCSTR ptr) { - char temp[64]; - ConvertUInt64ToHex((UInt64)(void *)p, temp); - AString s2; - s2 += temp; - s2.Add_Space(); - s2 += s; - OutputDebugStringA(s2); -} - -void Print_Number(UInt32 number, char *s) -{ - char temp[64]; - ConvertUInt64ToString(number, temp); - AString s2; - s2 += temp; - s2.Add_Space(); - s2 += s; - OutputDebugStringA(s2); -} - -#define ODS(sz) Print_Ptr(this, sz) -#define ODS_U(s) OutputDebugStringW(s); -// #define ODS(sz) -// #define ODS_U(s) + AString m; + m += name; + m += ": "; + char s[32]; + sprintf(s, "%p", (const void *)ptr); + m += s; + if (!MY_IS_INTRESOURCE(ptr)) + { + m += ": \""; + m += ptr; + m += "\""; + } + OutputDebugStringA(m); +} -#define ODS2(sz) Print_Ptr(this, sz) +#if !defined(UNDER_CE) +static void PrintStringW(const char *name, LPCWSTR ptr) +{ + UString m; + m += name; + m += ": "; + char s[32]; + sprintf(s, "%p", (const void *)ptr); + m += s; + if (!MY_IS_INTRESOURCE(ptr)) + { + m += ": \""; + m += ptr; + m += "\""; + } + OutputDebugStringW(m); +} +#endif + +static void Print_Ptr(const void *p, const char *s) +{ + char temp[32]; + sprintf(temp, "%p", (const void *)p); + AString m; + m += temp; + m.Add_Space(); + m += s; + OutputDebugStringA(m); +} + +static void Print_Number(UInt32 number, const char *s) +{ + AString m; + m.Add_UInt32(number); + m.Add_Space(); + m += s; + OutputDebugStringA(m); +} + +#define ODS(sz) { Print_Ptr(this, sz); } +#define ODS_U(s) { OutputDebugStringW(s); } +#define ODS_(op) { op; } +#define ODS_SPRF_s(x) { char s[256]; x; OutputDebugStringA(s); } #else -#define Print_Number(number, s) #define ODS(sz) #define ODS_U(s) -#define ODS2(sz) +#define ODS_(op) +#define ODS_SPRF_s(x) #endif +/* +DOCs: In Windows 7 and later, the number of items passed to + a verb is limited to 16 when a shortcut menu is queried. + The verb is then re-created and re-initialized with the full + selection when that verb is invoked. +win10 tests: + if (the number of selected file/dir objects > 16) + { + Explorer does the following actions: + - it creates ctx_menu_1 IContextMenu object + - it calls ctx_menu_1->Initialize() with list of only up to 16 items + - it calls ctx_menu_1->QueryContextMenu(menu_1) + - if (some menu command is pressed) + { + - it gets shown string from selected menu item : shown_menu_1_string + - it creates another ctx_menu_2 IContextMenu object + - it calls ctx_menu_2->Initialize() with list of all items + - it calls ctx_menu_2->QueryContextMenu(menu_2) + - if there is menu item with shown_menu_1_string string in menu_2, + Explorer calls ctx_menu_2->InvokeCommand() for that item. + Explorer probably doesn't use VERB from first object ctx_menu_1. + So we must provide same shown menu strings for both objects: + ctx_menu_1 and ctx_menu_2. + } + } +*/ + CZipContextMenu::CZipContextMenu(): - _isMenuForFM(false), + _isMenuForFM(true), + _fileNames_WereReduced(true), _dropMode(false), _bitmap(NULL), _writeZone((UInt32)(Int32)-1), @@ -107,87 +172,81 @@ IsRoot(true), CurrentSubCommand(0) { - ODS("-- CZipContextMenu()"); - + ODS("== CZipContextMenu()"); InterlockedIncrement(&g_DllRefCount); - _bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO)); } CZipContextMenu::~CZipContextMenu() { ODS("== ~CZipContextMenu"); - if (_bitmap != NULL) + if (_bitmap) DeleteObject(_bitmap); InterlockedDecrement(&g_DllRefCount); } -HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames) -{ - fileNames.Clear(); - if (!dataObject) - return E_INVALIDARG; - - #ifndef UNDER_CE - - FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - NCOM::CStgMedium stgMedium; - HRESULT result = dataObject->GetData(&fmte, &stgMedium); - if (result != S_OK) - return result; - stgMedium._mustBeReleased = true; - - NShell::CDrop drop(false); - NMemory::CGlobalLock globalLock(stgMedium->hGlobal); - drop.Attach((HDROP)globalLock.GetPointer()); - drop.QueryFileNames(fileNames); - - #endif - - return S_OK; -} - // IShellExtInit -STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY /* hkeyProgID */) +/* +IShellExtInit::Initialize() + pidlFolder: + - for property sheet extension: + NULL + - for shortcut menu extensions: + pidl of folder that contains the item whose shortcut menu is being displayed: + - for nondefault drag-and-drop menu extensions: + pidl of target folder: for nondefault drag-and-drop menu extensions + pidlFolder == NULL in (win10): for context menu +*/ + +Z7_COMWF_B CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY /* hkeyProgID */) { - // OutputDebugString(TEXT("::Initialize\r\n")); + COM_TRY_BEGIN + ODS("==== CZipContextMenu::Initialize START") + _isMenuForFM = false; + _fileNames_WereReduced = true; _dropMode = false; + _attribs.Clear(); + _fileNames.Clear(); _dropPath.Empty(); - if (pidlFolder != 0) + + if (pidlFolder) { - #ifndef UNDER_CE + ODS("==== CZipContextMenu::Initialize (pidlFolder != 0)") + #ifndef UNDER_CE if (NShell::GetPathFromIDList(pidlFolder, _dropPath)) { - // OutputDebugString(path); - // OutputDebugString(TEXT("\r\n")); + ODS("==== CZipContextMenu::Initialize path from (pidl):") + ODS_U(_dropPath); + /* win10 : path with "\\\\?\\\" prefix is returned by GetPathFromIDList, if path is long + we can remove super prefix here. But probably prefix + is not problem for following 7-zip code. + so we don't remove super prefix */ + NFile::NName::If_IsSuperPath_RemoveSuperPrefix(_dropPath); NName::NormalizeDirPathPrefix(_dropPath); _dropMode = !_dropPath.IsEmpty(); } else - #endif + #endif _dropPath.Empty(); } - /* - m_IsFolder = false; - if (pidlFolder == 0) - */ - // pidlFolder is NULL :( - return GetFileNames(dataObject, _fileNames); -} + if (!dataObject) + return E_INVALIDARG; + + #ifndef UNDER_CE + + RINOK(NShell::DataObject_GetData_HDROP_or_IDLIST_Names(dataObject, _fileNames)) + // for (unsigned y = 0; y < 10000; y++) + if (NShell::DataObject_GetData_FILE_ATTRS(dataObject, _attribs) != S_OK) + _attribs.Clear(); + + #endif + + ODS_SPRF_s(sprintf(s, "==== CZipContextMenu::Initialize END _files=%d", + _fileNames.Size())) -HRESULT CZipContextMenu::InitContextMenu(const wchar_t * /* folder */, const wchar_t * const *names, unsigned numFiles) -{ - _isMenuForFM = true; - _fileNames.Clear(); - for (UInt32 i = 0; i < numFiles; i++) - { - // MessageBoxW(0, names[i], NULL, 0); - // OutputDebugStringW(names[i]); - _fileNames.Add(names[i]); - } - _dropMode = false; return S_OK; + COM_TRY_END } @@ -202,7 +261,7 @@ struct CContextMenuCommand { UInt32 flag; - CZipContextMenu::ECommandInternalID CommandInternalID; + CZipContextMenu::enum_CommandInternalID CommandInternalID; LPCSTR Verb; UINT ResourceID; }; @@ -227,7 +286,7 @@ struct CHashCommand { - CZipContextMenu::ECommandInternalID CommandInternalID; + CZipContextMenu::enum_CommandInternalID CommandInternalID; LPCSTR UserName; LPCSTR MethodName; }; @@ -236,27 +295,33 @@ { { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" }, { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" }, + { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" }, + { CZipContextMenu::kHash_MD5, "MD5", "MD5" }, { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" }, { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" }, + { CZipContextMenu::kHash_SHA384, "SHA-384", "SHA384" }, + { CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" }, + { CZipContextMenu::kHash_SHA3_256, "SHA3-256", "SHA3-256" }, + { CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" }, { CZipContextMenu::kHash_All, "*", "*" }, { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" }, { CZipContextMenu::kHash_TestArc, "Checksum : Test", "Hash" } }; -static int FindCommand(CZipContextMenu::ECommandInternalID &id) +static int FindCommand(CZipContextMenu::enum_CommandInternalID &id) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Commands); i++) if (g_Commands[i].CommandInternalID == id) - return i; + return (int)i; return -1; } -void CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi) +void CZipContextMenu::FillCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) const { mainString.Empty(); - int i = FindCommand(id); + const int i = FindCommand(id); if (i < 0) throw 201908; const CContextMenuCommand &command = g_Commands[(unsigned)i]; @@ -266,7 +331,6 @@ // cmi.HelpString = cmi.Verb; LangString(command.ResourceID, mainString); cmi.UserString = mainString; - // return true; } @@ -279,14 +343,39 @@ } -void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi) +void CZipContextMenu::AddCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) { FillCommand(id, mainString, cmi); _commandMap.Add(cmi); } -static void MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMAP bitmap) + +/* +note: old msdn article: +Duplicate Menu Items In the File Menu For a Shell Context Menu Extension (214477) +---------- + On systems with Shell32.dll version 4.71 or higher, a context menu extension + for a file folder that inserts one or more pop-up menus results in duplicates + of these menu items. + This occurs when the file menu is activated more than once for the selected object. + +CAUSE + In a context menu extension, if pop-up menus are inserted using InsertMenu + or AppendMenu, then the ID for the pop-up menu item cannot be specified. + Instead, this field should take in the HMENU of the pop-up menu. + Because the ID is not specified for the pop-up menu item, the Shell does + not keep track of the menu item if the file menu is pulled down multiple times. + As a result, the pop-up menu items are added multiple times in the context menu. + + This problem occurs only when the file menu is pulled down, and does not happen + when the context menu is invoked by using the right button or the context menu key. +RESOLUTION + To work around this problem, use InsertMenuItem and specify the ID of the + pop-up menu item in the wID member of the MENUITEMINFO structure. +*/ + +static void MyInsertMenu(CMenu &menu, unsigned pos, UINT id, const UString &s, HBITMAP bitmap) { if (!menu) return; @@ -310,7 +399,7 @@ static void MyAddSubMenu( CObjectVector &_commandMap, const char *verb, - CMenu &menu, int pos, UINT id, const UString &s, HMENU hSubMenu, HBITMAP bitmap) + CMenu &menu, unsigned pos, UINT id, const UString &s, HMENU hSubMenu, HBITMAP bitmap) { CZipContextMenu::CCommandMapItem cmi; cmi.CommandInternalID = CZipContextMenu::kCommandNULL; @@ -349,7 +438,7 @@ static bool IsItArcExt(const UString &ext) { - for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kArcExts); i++) if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i])) return true; return false; @@ -422,7 +511,7 @@ " sed sh shn shtml sln sql srt swa" " tcl tex tiff tta txt" " vb vcproj vbs" - " wav wma wv" + " mkv wav webm wma wv" " xml xsd xsl xslt" " "; @@ -444,39 +533,22 @@ , "rar" }; -static bool FindExt(const char *p, const FString &name) + +bool FindExt(const char *p, const UString &name, CStringFinder &finder); +bool FindExt(const char *p, const UString &name, CStringFinder &finder) { - int dotPos = name.ReverseFind_Dot(); - if (dotPos < 0 || dotPos == (int)name.Len() - 1) + const int dotPos = name.ReverseFind_Dot(); + int len = (int)name.Len() - (dotPos + 1); + if (len == 0 || len > 32 || dotPos < 0) return false; - - AString s; - - for (unsigned pos = dotPos + 1;; pos++) - { - wchar_t c = name[pos]; - if (c == 0) - break; - if (c >= 0x80) - return false; - s += (char)MyCharLower_Ascii((char)c); - } - - for (unsigned i = 0; p[i] != 0;) - { - unsigned j; - for (j = i; p[j] != ' '; j++); - if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0) - return true; - i = j + 1; - } - - return false; + return finder.FindWord_In_LowCaseAsciiList_NoCase(p, name.Ptr(dotPos + 1)); } -static bool DoNeedExtract(const FString &name) +/* returns false, if extraction of that file extension is not expected */ +static bool DoNeedExtract(const UString &name, CStringFinder &finder) { - return !FindExt(kExtractExcludeExtensions, name); + // for (int y = 0; y < 1000; y++) FindExt(kExtractExcludeExtensions, name); + return !FindExt(kExtractExcludeExtensions, name, finder); } // we must use diferent Verbs for Popup subMenu. @@ -510,66 +582,72 @@ */ - -STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, +Z7_COMWF_B CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT commandIDFirst, UINT commandIDLast, UINT flags) { - ODS("+ QueryContextMenu()"); + ODS("+ QueryContextMenu()") COM_TRY_BEGIN try { - #ifdef SHOW_DEBUG_CTX_MENU - { char s[256]; sprintf(s, "QueryContextMenu: index=%d first=%d last=%d flags=%x _files=%d", - indexMenu, commandIDFirst, commandIDLast, flags, _fileNames.Size()); OutputDebugStringA(s); } + _commandMap.Clear(); + ODS_SPRF_s(sprintf(s, "QueryContextMenu: index=%u first=%u last=%u flags=%x _files=%u", + indexMenu, commandIDFirst, commandIDLast, flags, _fileNames.Size())) /* for (UInt32 i = 0; i < _fileNames.Size(); i++) { - OutputDebugStringW(_fileNames[i]); + ODS_U(_fileNames[i]) } */ - #endif - LoadLangOneTime(); - + #define MAKE_HRESULT_SUCCESS_FAC0(code) (HRESULT)(code) + if (_fileNames.Size() == 0) { - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); + return MAKE_HRESULT_SUCCESS_FAC0(0); // return E_INVALIDARG; } if (commandIDFirst > commandIDLast) return E_INVALIDARG; - UINT currentCommandID = commandIDFirst; if ((flags & 0x000F) != CMF_NORMAL && (flags & CMF_VERBSONLY) == 0 && (flags & CMF_EXPLORE) == 0) - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst); - // return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID); + return MAKE_HRESULT_SUCCESS_FAC0(currentCommandID - commandIDFirst); + // return MAKE_HRESULT_SUCCESS_FAC0(currentCommandID); // 19.01 : we changed from (currentCommandID) to (currentCommandID - commandIDFirst) // why it was so before? - _commandMap.Clear(); +#ifdef Z7_LANG + LoadLangOneTime(); +#endif CMenu popupMenu; CMenuDestroyer menuDestroyer; + ODS("### 40") CContextMenuInfo ci; ci.Load(); + ODS("### 44") _elimDup = ci.ElimDup; _writeZone = ci.WriteZone; HBITMAP bitmap = NULL; if (ci.MenuIcons.Val) + { + ODS("### 45") + if (!_bitmap) + _bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO)); bitmap = _bitmap; + } UINT subIndex = indexMenu; - ODS("### 50"); + ODS("### 50") if (ci.Cascaded.Val) { @@ -596,7 +674,7 @@ popupMenu.InsertItem(subIndex++, true, mi); } - UInt32 contextMenuFlags = ci.Flags; + const UInt32 contextMenuFlags = ci.Flags; NFind::CFileInfo fi0; FString folderPrefix; @@ -610,7 +688,7 @@ { // CFileInfo::Find can be slow for device files. So we don't call it. // we need only name here. - fi0.Name = us2fs(fileName.Ptr(NName::kDevicePathPrefixSize)); // change it 4 - must be constant + fi0.Name = us2fs(fileName.Ptr(NName::kDevicePathPrefixSize)); folderPrefix = #ifdef UNDER_CE "\\"; @@ -630,16 +708,42 @@ } } - ODS("### 100"); + ODS("### 100") UString mainString; + CStringFinder finder; + UStringVector fileNames_Reduced; + const unsigned k_Explorer_NumReducedItems = 16; + const bool needReduce = !_isMenuForFM && (_fileNames.Size() >= k_Explorer_NumReducedItems); + _fileNames_WereReduced = needReduce; + // _fileNames_WereReduced = true; // for debug; + const UStringVector *fileNames = &_fileNames; + if (needReduce) + { + for (unsigned i = 0; i < k_Explorer_NumReducedItems + && i < _fileNames.Size(); i++) + fileNames_Reduced.Add(_fileNames[i]); + fileNames = &fileNames_Reduced; + } + /* + if (_fileNames.Size() == k_Explorer_NumReducedItems) // for debug + { + for (int i = 0; i < 10; i++) + { + CCommandMapItem cmi; + AddCommand(kCompressToZipEmail, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + } + */ + if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast) { - if (!fi0.IsDir() && DoNeedExtract(fi0.Name)) + if (!fi0.IsDir() && DoNeedExtract(fs2us(fi0.Name), finder)) { // Open - bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0); + const bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0); if (thereIsMainOpenItem) { CCommandMapItem cmi; @@ -658,7 +762,7 @@ _commandMap.Back().CtxCommandType = CtxCommandType_OpenRoot; UINT subIndex2 = 0; - for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < ARRAY_SIZE(kOpenTypes); i++) + for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < Z7_ARRAY_SIZE(kOpenTypes); i++) { CCommandMapItem cmi; if (i == 0) @@ -685,29 +789,40 @@ } } + ODS("### 150") + if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) { - bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name)); - - if (!needExtract) + ODS("### needExtract list START") + const bool needExtendedVerbs = ((flags & Z7_WIN_CMF_EXTENDEDVERBS) != 0); + // || _isMenuForFM; + bool needExtract = true; + bool areDirs = fi0.IsDir() || (unsigned)_attribs.FirstDirIndex < k_Explorer_NumReducedItems; + if (!needReduce) + areDirs = areDirs || (_attribs.FirstDirIndex != -1); + if (areDirs) + needExtract = false; + + if (!needExtendedVerbs) + if (needExtract) { - for (unsigned i = 1; i < _fileNames.Size(); i++) + UString name; + const unsigned numItemsCheck = fileNames->Size(); + for (unsigned i = 0; i < numItemsCheck; i++) { - NFind::CFileInfo fi; - if (!fi.Find(us2fs(_fileNames[i]))) + const UString &a = (*fileNames)[i]; + const int slash = a.ReverseFind_PathSepar(); + name = a.Ptr(slash + 1); + // for (int y = 0; y < 600; y++) // for debug + const bool needExtr2 = DoNeedExtract(name, finder); + if (!needExtr2) { - throw 20190821; - // return RETURN_WIN32_LastError_AS_HRESULT(); - } - if (!fi.IsDir() && DoNeedExtract(fi.Name)) - { - needExtract = true; + needExtract = needExtr2; break; } } } - - // const UString &fileName = _fileNames.Front(); + ODS("### needExtract list END") if (needExtract) { @@ -757,16 +872,46 @@ // Test CCommandMapItem cmi; AddCommand(kTest, mainString, cmi); + // if (_fileNames.Size() == 16) mainString += "_[16]"; // for debug MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); } } - - const UString arcName = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL); - UString arcName7z = arcName; - arcName7z += ".7z"; - UString arcNameZip = arcName; - arcNameZip += ".zip"; + ODS("### CreateArchiveName START") + UString arcName_base; + const UString arcName = CreateArchiveName( + *fileNames, + false, // isHash + fileNames->Size() == 1 ? &fi0 : NULL, + arcName_base); + ODS("### CreateArchiveName END") + UString arcName_Show = arcName; + if (needReduce) + { + /* we need same arcName_Show for two calls from Explorer: + 1) reduced call (only first 16 items) + 2) full call with all items (can be >= 16 items) + (fileNames) array was reduced to 16 items. + So we will have same (arcName) in both reduced and full calls. + If caller (Explorer) uses (reduce_to_first_16_items) scheme, + we can use (arcName) here instead of (arcName_base). + (arcName_base) has no number in name. + */ + arcName_Show = arcName_base; // we can comment that line + /* we use "_" in archive name as sign to user + that shows that final archive name can be changed. */ + arcName_Show += "_"; + } + + UString arcName_7z = arcName; + arcName_7z += ".7z"; + UString arcName_7z_Show = arcName_Show; + arcName_7z_Show += ".7z"; + UString arcName_zip = arcName; + arcName_zip += ".zip"; + UString arcName_zip_Show = arcName_Show; + arcName_zip_Show += ".zip"; + // Compress if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0) @@ -794,7 +939,7 @@ // CompressTo7z if (contextMenuFlags & NContextMenuFlags::kCompressTo7z && - !arcName7z.IsEqualTo_NoCase(fs2us(fi0.Name))) + !arcName_7z.IsEqualTo_NoCase(fs2us(fi0.Name))) { CCommandMapItem cmi; UString s; @@ -802,10 +947,10 @@ cmi.Folder = _dropPath; else cmi.Folder = fs2us(folderPrefix); - cmi.ArcName = arcName7z; + cmi.ArcName = arcName_7z; cmi.ArcType = "7z"; AddCommand(kCompressTo7z, s, cmi); - MyFormatNew_ReducedName(s, arcName7z); + MyFormatNew_ReducedName(s, arcName_7z_Show); Set_UserString_in_LastCommand(s); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); } @@ -816,10 +961,10 @@ { CCommandMapItem cmi; UString s; - cmi.ArcName = arcName7z; + cmi.ArcName = arcName_7z; cmi.ArcType = "7z"; AddCommand(kCompressTo7zEmail, s, cmi); - MyFormatNew_ReducedName(s, arcName7z); + MyFormatNew_ReducedName(s, arcName_7z_Show); Set_UserString_in_LastCommand(s); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); } @@ -827,7 +972,7 @@ // CompressToZip if (contextMenuFlags & NContextMenuFlags::kCompressToZip && - !arcNameZip.IsEqualTo_NoCase(fs2us(fi0.Name))) + !arcName_zip.IsEqualTo_NoCase(fs2us(fi0.Name))) { CCommandMapItem cmi; UString s; @@ -835,10 +980,10 @@ cmi.Folder = _dropPath; else cmi.Folder = fs2us(folderPrefix); - cmi.ArcName = arcNameZip; + cmi.ArcName = arcName_zip; cmi.ArcType = "zip"; AddCommand(kCompressToZip, s, cmi); - MyFormatNew_ReducedName(s, arcNameZip); + MyFormatNew_ReducedName(s, arcName_zip_Show); Set_UserString_in_LastCommand(s); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); } @@ -849,16 +994,17 @@ { CCommandMapItem cmi; UString s; - cmi.ArcName = arcNameZip; + cmi.ArcName = arcName_zip; cmi.ArcType = "zip"; AddCommand(kCompressToZipEmail, s, cmi); - MyFormatNew_ReducedName(s, arcNameZip); + MyFormatNew_ReducedName(s, arcName_zip_Show); Set_UserString_in_LastCommand(s); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); } #endif } + ODS("### 300") // don't use InsertMenu: See MSDN: // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension @@ -879,6 +1025,8 @@ indexMenu = subIndex; } + ODS("### 350") + const bool needCrc = ((contextMenuFlags & (NContextMenuFlags::kCRC | NContextMenuFlags::kCRC_Cascaded)) != 0); @@ -901,7 +1049,7 @@ CMenu menu; { - int indexInParent; + unsigned indexInParent; if (insertHashMenuTo7zipMenu) { indexInParent = subIndex; @@ -920,7 +1068,9 @@ indexMenu = indexInParent; } - for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++) + ODS("### HashCommands") + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_HashCommands); i++) { if (currentCommandID >= commandIDLast) break; @@ -928,13 +1078,13 @@ CCommandMapItem cmi; cmi.CommandInternalID = hc.CommandInternalID; cmi.Verb = kCheckSumCascadedVerb; - cmi.Verb += '.'; - cmi.Verb += hc.MethodName; + cmi.Verb.Add_Dot(); UString s; s += hc.UserName; if (hc.CommandInternalID == kHash_Generate_SHA256) { + cmi.Verb += "Generate"; { popupMenu.Attach(hMenu); CMenuItem mi; @@ -944,28 +1094,47 @@ } UString name; - if (_fileNames.Size() > 1) - name = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL); + UString showName; + ODS("### Hash CreateArchiveName Start") + // for (int y = 0; y < 10000; y++) // for debug + // if (fileNames->Size() == 1) name = fs2us(fi0.Name); else + name = CreateArchiveName( + *fileNames, + true, // isHash + fileNames->Size() == 1 ? &fi0 : NULL, + showName); + if (needReduce) + showName += "_"; else - name = fs2us(fi0.Name); + showName = name; + + ODS("### Hash CreateArchiveName END") name += ".sha256"; + showName += ".sha256"; cmi.Folder = fs2us(folderPrefix); cmi.ArcName = name; s = "SHA-256 -> "; - s += name; + s += showName; } else if (hc.CommandInternalID == kHash_TestArc) { + cmi.Verb += "Test"; s = LangStringAlt(IDS_CONTEXT_TEST, "Test archive"); s += " : "; s += GetNameOfProperty(kpidChecksum, UString("Checksum")); } + else + cmi.Verb += "Calc"; + + cmi.Verb.Add_Dot(); + cmi.Verb += hc.MethodName; // cmi.HelpString = cmi.Verb; cmi.UserString = s; cmi.CtxCommandType = CtxCommandType_CrcChild; _commandMap.Add(cmi); MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, s, bitmap); + ODS("### 380") } subMenu.Detach(); @@ -973,49 +1142,45 @@ } popupMenu.Detach(); - /* if (!ci.Cascaded.Val) indexMenu = subIndex; */ - - ODS("### 400"); - - #ifdef SHOW_DEBUG_CTX_MENU - { char s[256]; sprintf(s, "Commands=%d currentCommandID - commandIDFirst = %d", - _commandMap.Size(), currentCommandID - commandIDFirst); OutputDebugStringA(s); } - #endif - - if (_commandMap.Size() != currentCommandID - commandIDFirst) + const unsigned numCommands = currentCommandID - commandIDFirst; + ODS("+ QueryContextMenu() END") + ODS_SPRF_s(sprintf(s, "Commands=%u currentCommandID - commandIDFirst = %u", + _commandMap.Size(), numCommands)) + if (_commandMap.Size() != numCommands) throw 20190818; - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst); - + /* + FOR_VECTOR (k, _commandMap) + { + ODS_U(_commandMap[k].Verb); + } + */ } catch(...) { + ODS_SPRF_s(sprintf(s, "catch() exception: Commands=%u", _commandMap.Size())) + if (_commandMap.Size() == 0) + throw; + } /* we added some menu items already : num_added_menu_items, So we MUST return (number_of_defined_ids), where (number_of_defined_ids >= num_added_menu_items) This will prevent incorrect menu working, when same IDs can be assigned in multiple menu items from different subhandlers. And we must add items to _commandMap before adding to menu. */ - #ifdef SHOW_DEBUG_CTX_MENU - { char s[256]; sprintf(s, "catch() exception: Commands=%d", - _commandMap.Size()); OutputDebugStringA(s); } - #endif - // if (_commandMap.Size() != 0) - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, _commandMap.Size()); - // throw; - } + return MAKE_HRESULT_SUCCESS_FAC0(_commandMap.Size()); COM_TRY_END } -int CZipContextMenu::FindVerb(const UString &verb) +int CZipContextMenu::FindVerb(const UString &verb) const { FOR_VECTOR (i, _commandMap) if (_commandMap[i].Verb == verb) - return i; + return (int)i; return -1; } @@ -1025,66 +1190,16 @@ } -#ifdef UNDER_CE - #define MY__IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0) -#else - #define MY__IS_INTRESOURCE(_r) IS_INTRESOURCE(_r) -#endif - - -#ifdef SHOW_DEBUG_CTX_MENU -static void PrintStringA(const char *name, LPCSTR ptr) -{ - AString m; - m += name; - m += ": "; - char s[32]; - sprintf(s, "%p", ptr); - m += s; - if (!MY__IS_INTRESOURCE(ptr)) - { - m += ": \""; - m += ptr; - m += "\""; - } - OutputDebugStringA(m); -} - -#if !defined(UNDER_CE) -static void PrintStringW(const char *name, LPCWSTR ptr) -{ - UString m; - m += name; - m += ": "; - char s[32]; - sprintf(s, "%p", ptr); - m += s; - if (!MY__IS_INTRESOURCE(ptr)) - { - m += ": \""; - m += ptr; - m += "\""; - } - OutputDebugStringW(m); -} -#endif -#endif - - -STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) +Z7_COMWF_B CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) { COM_TRY_BEGIN + ODS("==== CZipContextMenu::InvokeCommand()") + #ifdef SHOW_DEBUG_CTX_MENU - { char s[1280]; sprintf(s, - #ifdef _WIN64 - "64" - #else - "32" - #endif - ": InvokeCommand: cbSize=%d flags=%x " - , commandInfo->cbSize, commandInfo->fMask); OutputDebugStringA(s); } + ODS_SPRF_s(sprintf(s, ": InvokeCommand: cbSize=%u flags=%x ", + (unsigned)commandInfo->cbSize, (unsigned)commandInfo->fMask)) PrintStringA("Verb", commandInfo->lpVerb); PrintStringA("Parameters", commandInfo->lpParameters); @@ -1094,16 +1209,16 @@ int commandOffset = -1; // xp64 / Win10 : explorer.exe sends 0 in lpVerbW - // MSDN: if (IS_INTRESOURCE(lpVerbW)), we must use LOWORD(lpVerb) as sommand offset + // MSDN: if (IS_INTRESOURCE(lpVerbW)), we must use LOWORD(lpVerb) as command offset - // FIXME: MINGW doesn't define CMINVOKECOMMANDINFOEX - #if !defined(UNDER_CE) /* && defined(_MSC_VER) */ + // FIXME: old MINGW doesn't define CMINVOKECOMMANDINFOEX / CMIC_MASK_UNICODE + #if !defined(UNDER_CE) && defined(CMIC_MASK_UNICODE) bool unicodeVerb = false; if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && (commandInfo->fMask & CMIC_MASK_UNICODE) != 0) { LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo; - if (!MY__IS_INTRESOURCE(commandInfoEx->lpVerbW)) + if (!MY_IS_INTRESOURCE(commandInfoEx->lpVerbW)) { unicodeVerb = true; commandOffset = FindVerb(commandInfoEx->lpVerbW); @@ -1120,22 +1235,17 @@ if (!unicodeVerb) #endif { - #ifdef SHOW_DEBUG_CTX_MENU - OutputDebugStringA("use non-UNICODE verb"); - #endif + ODS("use non-UNICODE verb") // if (HIWORD(commandInfo->lpVerb) == 0) - if (MY__IS_INTRESOURCE(commandInfo->lpVerb)) + if (MY_IS_INTRESOURCE(commandInfo->lpVerb)) commandOffset = LOWORD(commandInfo->lpVerb); else commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb)); } - #ifdef SHOW_DEBUG_CTX_MENU - { char s[128]; sprintf(s, "commandOffset=%d", - commandOffset); OutputDebugStringA(s); } - #endif + ODS_SPRF_s(sprintf(s, "commandOffset=%d", commandOffset)) - if (commandOffset < 0 || (unsigned)commandOffset >= _commandMap.Size()) + if (/* commandOffset < 0 || */ (unsigned)commandOffset >= _commandMap.Size()) return E_INVALIDARG; const CCommandMapItem &cmi = _commandMap[(unsigned)commandOffset]; return InvokeCommandCommon(cmi); @@ -1145,7 +1255,7 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi) { - const ECommandInternalID cmdID = cmi.CommandInternalID; + const enum_CommandInternalID cmdID = cmi.CommandInternalID; try { @@ -1167,6 +1277,11 @@ case kExtractHere: case kExtractTo: { + if (_attribs.FirstDirIndex != -1) + { + ShowErrorMessageRes(IDS_SELECT_FILES); + break; + } ExtractArchives(_fileNames, cmi.Folder, (cmdID == kExtract), // showDialog (cmdID == kExtractTo) && _elimDup.Val, // elimDup @@ -1186,16 +1301,37 @@ case kCompressToZip: case kCompressToZipEmail: { + UString arcName = cmi.ArcName; + if (_fileNames_WereReduced) + { + UString arcName_base; + arcName = CreateArchiveName( + _fileNames, + false, // isHash + NULL, // fi0 + arcName_base); + const char *postfix = NULL; + if (cmdID == kCompressTo7z || + cmdID == kCompressTo7zEmail) + postfix = ".7z"; + else if ( + cmdID == kCompressToZip || + cmdID == kCompressToZipEmail) + postfix = ".zip"; + if (postfix) + arcName += postfix; + } + const bool email = - (cmdID == kCompressEmail) || - (cmdID == kCompressTo7zEmail) || - (cmdID == kCompressToZipEmail); + cmdID == kCompressEmail || + cmdID == kCompressTo7zEmail || + cmdID == kCompressToZipEmail; const bool showDialog = - (cmdID == kCompress) || - (cmdID == kCompressEmail); - const bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail); + cmdID == kCompress || + cmdID == kCompressEmail; + const bool addExtension = showDialog; CompressFiles(cmi.Folder, - cmi.ArcName, cmi.ArcType, + arcName, cmi.ArcType, addExtension, _fileNames, email, showDialog, false // waitFinish @@ -1205,13 +1341,19 @@ case kHash_CRC32: case kHash_CRC64: + case kHash_XXH64: + case kHash_MD5: case kHash_SHA1: case kHash_SHA256: + case kHash_SHA384: + case kHash_SHA512: + case kHash_SHA3_256: + case kHash_BLAKE2SP: case kHash_All: case kHash_Generate_SHA256: case kHash_TestArc: { - for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_HashCommands); i++) { const CHashCommand &hc = g_HashCommands[i]; if (hc.CommandInternalID == cmdID) @@ -1223,7 +1365,18 @@ } UString generateName; if (cmdID == kHash_Generate_SHA256) + { generateName = cmi.ArcName; + if (_fileNames_WereReduced) + { + UString arcName_base; + generateName = CreateArchiveName(_fileNames, + true, // isHash + NULL, // fi0 + arcName_base); + generateName += ".sha256"; + } + } CalcChecksum(_fileNames, (UString)hc.MethodName, cmi.Folder, generateName); break; @@ -1237,14 +1390,14 @@ } catch(...) { - ::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR); + ShowErrorMessage(NULL, L"Error"); } return S_OK; } -static void MyCopyString(void *dest, const UString &src, bool writeInUnicode, UINT size) +static void MyCopyString_isUnicode(void *dest, UINT size, const UString &src, bool writeInUnicode) { if (size != 0) size--; @@ -1253,6 +1406,7 @@ UString s = src; s.DeleteFrom(size); MyStringCopy((wchar_t *)dest, s); + ODS_U(s) } else { @@ -1263,50 +1417,48 @@ } -STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uType, +Z7_COMWF_B CZipContextMenu::GetCommandString( + #ifdef Z7_OLD_WIN_SDK + UINT + #else + UINT_PTR + #endif + commandOffset, + UINT uType, UINT * /* pwReserved */ , LPSTR pszName, UINT cchMax) { COM_TRY_BEGIN + ODS("GetCommandString") + const int cmdOffset = (int)commandOffset; - #ifdef SHOW_DEBUG_CTX_MENU - { char s[256]; sprintf(s, "GetCommandString: cmdOffset=%d uType=%d cchMax = %d", - cmdOffset, uType, cchMax); OutputDebugStringA(s); } - #endif + ODS_SPRF_s(sprintf(s, "GetCommandString: cmdOffset=%d uType=%d cchMax = %d", + cmdOffset, uType, cchMax)) - if (uType == GCS_VALIDATEA || uType == GCS_VALIDATEW) + if ((uType | GCS_UNICODE) == GCS_VALIDATEW) { - if (cmdOffset < 0 || (unsigned)cmdOffset >= _commandMap.Size()) + if (/* cmdOffset < 0 || */ (unsigned)cmdOffset >= _commandMap.Size()) return S_FALSE; - else - return S_OK; + return S_OK; } - if (cmdOffset < 0 || (unsigned)cmdOffset >= _commandMap.Size()) + if (/* cmdOffset < 0 || */ (unsigned)cmdOffset >= _commandMap.Size()) { - #ifdef SHOW_DEBUG_CTX_MENU - OutputDebugStringA("---------------- cmdOffset: E_INVALIDARG"); - #endif + ODS("------ cmdOffset: E_INVALIDARG") return E_INVALIDARG; } - const CCommandMapItem &cmi = _commandMap[(unsigned)cmdOffset]; - - if (uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW) - { - // we can return "Verb" here for debug purposes. - // HelpString; - MyCopyString(pszName, cmi.Verb, uType == GCS_HELPTEXTW, cchMax); - return S_OK; - } - - if (uType == GCS_VERBA || uType == GCS_VERBW) + // we use Verb as HelpString + if (cchMax != 0) + if ((uType | GCS_UNICODE) == GCS_VERBW || + (uType | GCS_UNICODE) == GCS_HELPTEXTW) { - MyCopyString(pszName, cmi.Verb, uType == GCS_VERBW, cchMax); + const CCommandMapItem &cmi = _commandMap[(unsigned)cmdOffset]; + MyCopyString_isUnicode(pszName, cchMax, cmi.Verb, (uType & GCS_UNICODE) != 0); return S_OK; } - + return E_INVALIDARG; COM_TRY_END @@ -1339,7 +1491,7 @@ class CCoTaskWSTR { LPWSTR m_str; - CLASS_NO_COPY(CCoTaskWSTR) + Z7_CLASS_NO_COPY(CCoTaskWSTR) public: CCoTaskWSTR(): m_str(NULL) {} ~CCoTaskWSTR() { ::CoTaskMemFree(m_str); } @@ -1380,41 +1532,47 @@ */ }; -static void LoadPaths(IShellItemArray *psiItemArray, UStringVector &paths) +static HRESULT LoadPaths(IShellItemArray *psiItemArray, UStringVector &paths) { if (psiItemArray) { DWORD numItems = 0; - if (psiItemArray->GetCount(&numItems) == S_OK) + RINOK(psiItemArray->GetCount(&numItems)) { + ODS_(Print_Number(numItems, " ==== LoadPaths START === ")) for (DWORD i = 0; i < numItems; i++) { CMyComPtr item; - if (psiItemArray->GetItemAt(i, &item) == S_OK && item) + RINOK(psiItemArray->GetItemAt(i, &item)) + if (item) { CCoTaskWSTR displayName; if (item->GetDisplayName(SIGDN_FILESYSPATH, &displayName) == S_OK && (bool)displayName) { - OutputDebugStringW(displayName); + ODS_U(displayName) paths.Add((LPCWSTR)displayName); } } } + ODS_(Print_Number(numItems, " ==== LoadPaths END === ")) } } + return S_OK; } void CZipExplorerCommand::LoadItems(IShellItemArray *psiItemArray) { SubCommands.Clear(); - - UStringVector paths; - LoadPaths(psiItemArray, paths); - _fileNames = paths; - - HRESULT res = QueryContextMenu( + _fileNames.Clear(); + { + UStringVector paths; + if (LoadPaths(psiItemArray, paths) != S_OK) + return; + _fileNames = paths; + } + const HRESULT res = QueryContextMenu( NULL, // hMenu, 0, // indexMenu, 0, // commandIDFirst, @@ -1424,7 +1582,6 @@ if (FAILED(res)) return /* res */; - CZipExplorerCommand *crcHandler = NULL; CZipExplorerCommand *openHandler = NULL; @@ -1435,7 +1592,6 @@ { const CCommandMapItem &cmi = _commandMap[i]; - if (cmi.IsPopup) if (!cmi.IsSubMenu()) continue; @@ -1459,22 +1615,22 @@ shellExt->_commandMap_Cur.Add(cmi); - ODS_U(cmi.UserString); + ODS_U(cmi.UserString) if (cmi.CtxCommandType == CtxCommandType_CrcRoot && useCascadedCrc) crcHandler = shellExt; if (cmi.CtxCommandType == CtxCommandType_OpenRoot && useCascadedOpen) { - // ODS2("cmi.CtxCommandType == CtxCommandType_OpenRoot"); + // ODS("cmi.CtxCommandType == CtxCommandType_OpenRoot"); openHandler = shellExt; } } } -STDMETHODIMP CZipExplorerCommand::GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName) +Z7_COMWF_B CZipExplorerCommand::GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName) { - ODS("- GetTitle()"); + ODS("- GetTitle()") // COM_TRY_BEGIN if (IsSeparator) { @@ -1505,9 +1661,9 @@ } -STDMETHODIMP CZipExplorerCommand::GetIcon(IShellItemArray * /* psiItemArray */, LPWSTR *ppszIcon) +Z7_COMWF_B CZipExplorerCommand::GetIcon(IShellItemArray * /* psiItemArray */, LPWSTR *ppszIcon) { - ODS("- GetIcon()"); + ODS("- GetIcon()") // COM_TRY_BEGIN *ppszIcon = NULL; // return E_NOTIMPL; @@ -1520,30 +1676,30 @@ } -STDMETHODIMP CZipExplorerCommand::GetToolTip (IShellItemArray * /* psiItemArray */, LPWSTR *ppszInfotip) +Z7_COMWF_B CZipExplorerCommand::GetToolTip (IShellItemArray * /* psiItemArray */, LPWSTR *ppszInfotip) { // COM_TRY_BEGIN - ODS("- GetToolTip()"); + ODS("- GetToolTip()") *ppszInfotip = NULL; return E_NOTIMPL; // COM_TRY_END } -STDMETHODIMP CZipExplorerCommand::GetCanonicalName(GUID *pguidCommandName) +Z7_COMWF_B CZipExplorerCommand::GetCanonicalName(GUID *pguidCommandName) { // COM_TRY_BEGIN - ODS("- GetCanonicalName()"); + ODS("- GetCanonicalName()") *pguidCommandName = GUID_NULL; return E_NOTIMPL; // COM_TRY_END } -STDMETHODIMP CZipExplorerCommand::GetState(IShellItemArray * /* psiItemArray */, BOOL /* fOkToBeSlow */, EXPCMDSTATE *pCmdState) +Z7_COMWF_B CZipExplorerCommand::GetState(IShellItemArray * /* psiItemArray */, BOOL /* fOkToBeSlow */, EXPCMDSTATE *pCmdState) { // COM_TRY_BEGIN - ODS("- GetState()"); + ODS("- GetState()") *pCmdState = ECS_ENABLED; return S_OK; // COM_TRY_END @@ -1552,16 +1708,17 @@ -STDMETHODIMP CZipExplorerCommand::Invoke(IShellItemArray *psiItemArray, IBindCtx * /* pbc */) +Z7_COMWF_B CZipExplorerCommand::Invoke(IShellItemArray *psiItemArray, IBindCtx * /* pbc */) { COM_TRY_BEGIN if (_commandMap_Cur.IsEmpty()) return E_INVALIDARG; - ODS("- Invoke()"); + ODS("- Invoke()") + _fileNames.Clear(); UStringVector paths; - LoadPaths(psiItemArray, paths); + RINOK(LoadPaths(psiItemArray, paths)) _fileNames = paths; return InvokeCommandCommon(_commandMap_Cur[0]); @@ -1569,9 +1726,9 @@ } -STDMETHODIMP CZipExplorerCommand::GetFlags(EXPCMDFLAGS *pFlags) +Z7_COMWF_B CZipExplorerCommand::GetFlags(EXPCMDFLAGS *pFlags) { - ODS("- GetFlags()"); + ODS("- GetFlags()") // COM_TRY_BEGIN EXPCMDFLAGS f = ECF_DEFAULT; if (IsSeparator) @@ -1585,7 +1742,7 @@ // const CCommandMapItem &cmi = ; if (_commandMap_Cur[0].IsSubMenu()) { - // ODS("ECF_HASSUBCOMMANDS"); + // ODS("ECF_HASSUBCOMMANDS") f = ECF_HASSUBCOMMANDS; } } @@ -1596,9 +1753,9 @@ } -STDMETHODIMP CZipExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum) +Z7_COMWF_B CZipExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum) { - ODS("- EnumSubCommands()"); + ODS("- EnumSubCommands()") // COM_TRY_BEGIN *ppEnum = NULL; @@ -1623,12 +1780,12 @@ } -STDMETHODIMP CZipContextMenu::Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) +Z7_COMWF_B CZipContextMenu::Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) { - ODS("CZipContextMenu::Next()"); - Print_Number(celt, "celt"); - Print_Number(CurrentSubCommand, "CurrentSubCommand"); - Print_Number(SubCommands.Size(), "SubCommands.Size()"); + ODS("CZipContextMenu::Next()") + ODS_(Print_Number(celt, "celt")) + ODS_(Print_Number(CurrentSubCommand, "CurrentSubCommand")) + ODS_(Print_Number(SubCommands.Size(), "SubCommands.Size()")) COM_TRY_BEGIN ULONG fetched = 0; @@ -1649,7 +1806,7 @@ if (pceltFetched) *pceltFetched = fetched; - ODS(fetched == celt ? " === OK === " : "=== ERROR ==="); + ODS(fetched == celt ? " === OK === " : "=== ERROR ===") // we return S_FALSE for (fetched == 0) return (fetched == celt) ? S_OK : S_FALSE; @@ -1657,25 +1814,24 @@ } -STDMETHODIMP CZipContextMenu::Skip(ULONG celt) +Z7_COMWF_B CZipContextMenu::Skip(ULONG /* celt */) { - ODS("CZipContextMenu::Skip()"); - celt = celt; + ODS("CZipContextMenu::Skip()") return E_NOTIMPL; } -STDMETHODIMP CZipContextMenu::Reset(void) +Z7_COMWF_B CZipContextMenu::Reset(void) { - ODS("CZipContextMenu::Reset()"); + ODS("CZipContextMenu::Reset()") CurrentSubCommand = 0; return S_OK; } -STDMETHODIMP CZipContextMenu::Clone(IEnumExplorerCommand **ppenum) +Z7_COMWF_B CZipContextMenu::Clone(IEnumExplorerCommand **ppenum) { - ODS("CZipContextMenu::Clone()"); + ODS("CZipContextMenu::Clone()") *ppenum = NULL; return E_NOTIMPL; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.h 2022-06-06 10:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenu.h 2024-11-25 14:00:00.000000000 +0000 @@ -1,38 +1,77 @@ // ContextMenu.h -#ifndef __CONTEXT_MENU_H -#define __CONTEXT_MENU_H +#ifndef ZIP7_INC_CONTEXT_MENU_H +#define ZIP7_INC_CONTEXT_MENU_H -#include "../../../Common/MyWindows.h" - -#include +#include "../../../Windows/Shell.h" #include "MyExplorerCommand.h" -#include "../../../Common/MyString.h" - #include "../FileManager/MyCom2.h" -enum ECtxCommandType +#ifdef CMF_EXTENDEDVERBS +#define Z7_WIN_CMF_EXTENDEDVERBS CMF_EXTENDEDVERBS +#else +#define Z7_WIN_CMF_EXTENDEDVERBS 0x00000100 +#endif + +enum enum_CtxCommandType { CtxCommandType_Normal, CtxCommandType_OpenRoot, CtxCommandType_OpenChild, CtxCommandType_CrcRoot, - CtxCommandType_CrcChild, + CtxCommandType_CrcChild }; -class CZipContextMenu: +class CZipContextMenu Z7_final: public IContextMenu, public IShellExtInit, public IExplorerCommand, public IEnumExplorerCommand, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_4_MT( + IContextMenu, + IShellExtInit, + IExplorerCommand, + IEnumExplorerCommand + ) + + // IShellExtInit + STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID) Z7_override; + + // IContextMenu + STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) Z7_override; + STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici) Z7_override; + STDMETHOD(GetCommandString)( + #ifdef Z7_OLD_WIN_SDK + UINT + #else + UINT_PTR + #endif + idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax) Z7_override; + + // IExplorerCommand + STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName) Z7_override; + STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon) Z7_override; + STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) Z7_override; + STDMETHOD (GetCanonicalName) (GUID *pguidCommandName) Z7_override; + STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) Z7_override; + STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc) Z7_override; + STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags) Z7_override; + STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum) Z7_override; + + // IEnumExplorerCommand + STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) Z7_override; + STDMETHOD (Skip) (ULONG celt) Z7_override; + STDMETHOD (Reset) (void) Z7_override; + STDMETHOD (Clone) (IEnumExplorerCommand **ppenum) Z7_override; + public: - enum ECommandInternalID + enum enum_CommandInternalID { kCommandNULL, kOpen, @@ -48,54 +87,34 @@ kCompressToZipEmail, kHash_CRC32, kHash_CRC64, + kHash_XXH64, + kHash_MD5, kHash_SHA1, kHash_SHA256, + kHash_SHA384, + kHash_SHA512, + kHash_SHA3_256, + kHash_BLAKE2SP, kHash_All, kHash_Generate_SHA256, kHash_TestArc }; - - MY_UNKNOWN_IMP4_MT( - IContextMenu, - IShellExtInit, - IExplorerCommand, - IEnumExplorerCommand - ) - - // IShellExtInit - STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID); - - // IContextMenu - STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); - STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici); - STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax); - HRESULT InitContextMenu(const wchar_t *folder, const wchar_t * const *names, unsigned numFiles); +public: + void Init_For_7zFM() + { + // _isMenuForFM = true; + // _fileNames_WereReduced = false; + } void LoadItems(IShellItemArray *psiItemArray); - // IExplorerCommand - STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName); - STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon); - STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip); - STDMETHOD (GetCanonicalName) (GUID *pguidCommandName); - STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState); - STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc); - STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags); - STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum); - - // IEnumExplorerCommand - STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched); - STDMETHOD (Skip) (ULONG celt); - STDMETHOD (Reset) (void); - STDMETHOD (Clone) (IEnumExplorerCommand **ppenum); - CZipContextMenu(); ~CZipContextMenu(); struct CCommandMapItem { - ECommandInternalID CommandInternalID; + enum_CommandInternalID CommandInternalID; UString Verb; UString UserString; // UString HelpString; @@ -103,7 +122,7 @@ UString ArcName; UString ArcType; bool IsPopup; - ECtxCommandType CtxCommandType; + enum_CtxCommandType CtxCommandType; CCommandMapItem(): IsPopup(false), @@ -118,33 +137,34 @@ } }; -private: + UStringVector _fileNames; + NWindows::NShell::CFileAttribs _attribs; +private: bool _isMenuForFM; - UStringVector _fileNames; + bool _fileNames_WereReduced; // = true, if only first 16 items were used in QueryContextMenu() bool _dropMode; UString _dropPath; CObjectVector _commandMap; CObjectVector _commandMap_Cur; HBITMAP _bitmap; - CBoolPair _elimDup; UInt32 _writeZone; + CBoolPair _elimDup; bool IsSeparator; bool IsRoot; CObjectVector< CMyComPtr > SubCommands; - ULONG CurrentSubCommand; + unsigned CurrentSubCommand; void Set_UserString_in_LastCommand(const UString &s) { _commandMap.Back().UserString = s; } - HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames); - int FindVerb(const UString &verb); - void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi); - void AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi); + int FindVerb(const UString &verb) const; + void FillCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) const; + void AddCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi); void AddMapItem_ForSubMenu(const char *ver); HRESULT InvokeCommandCommon(const CCommandMapItem &cmi); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenuFlags.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenuFlags.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/ContextMenuFlags.h 2021-09-29 17:53:12.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/ContextMenuFlags.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ContextMenuFlags.h -#ifndef __CONTEXT_MENU_FLAGS_H -#define __CONTEXT_MENU_FLAGS_H +#ifndef ZIP7_INC_CONTEXT_MENU_FLAGS_H +#define ZIP7_INC_CONTEXT_MENU_FLAGS_H namespace NContextMenuFlags { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp 2021-10-24 11:41:05.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp 2024-03-20 07:00:00.000000000 +0000 @@ -1,4 +1,4 @@ -// DLLExports.cpp +// DLLExportsExplorer.cpp // // Notes: // Win2000: @@ -9,9 +9,23 @@ #include "StdAfx.h" #include "../../../Common/MyWindows.h" -// #include "../../../Common/IntToString.h" +#if defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wnonportable-system-include-path" +#endif +// : in new Windows Kit 10.0.2**** (NTDDI_WIN10_MN is defined) +// : in another Windows Kit versions +#if defined(NTDDI_WIN10_MN) || defined(__MINGW32__) || defined(__MINGW64__) +#include +#else #include +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif #include "../../../Common/MyInitGuid.h" @@ -32,7 +46,7 @@ // {23170F69-40C1-278A-1000-000100020000} static LPCTSTR const k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}"); -DEFINE_GUID(CLSID_CZipContextMenu, +Z7_DEFINE_GUID(CLSID_CZipContextMenu, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -42,35 +56,38 @@ extern HINSTANCE g_hInstance; -HINSTANCE g_hInstance = 0; +HINSTANCE g_hInstance = NULL; extern HWND g_HWND; -HWND g_HWND = 0; +HWND g_HWND = NULL; extern LONG g_DllRefCount; LONG g_DllRefCount = 0; // Reference count of this DLL. +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + // #define ODS(sz) OutputDebugStringW(L#sz) #define ODS(sz) -class CShellExtClassFactory: +class CShellExtClassFactory Z7_final: public IClassFactory, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_1_MT(IClassFactory) + + STDMETHOD(CreateInstance)(LPUNKNOWN, REFIID, void**) Z7_override Z7_final; + STDMETHOD(LockServer)(BOOL) Z7_override Z7_final; public: - CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } + CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); } - - MY_UNKNOWN_IMP1_MT(IClassFactory) - - STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, void**); - STDMETHODIMP LockServer(BOOL); }; -STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, +Z7_COMWF_B CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj) { ODS("CShellExtClassFactory::CreateInstance()\r\n"); @@ -92,14 +109,15 @@ if (!shellExt) return E_OUTOFMEMORY; - HRESULT res = shellExt->QueryInterface(riid, ppvObj); + IContextMenu *ctxm = shellExt; + const HRESULT res = ctxm->QueryInterface(riid, ppvObj); if (res != S_OK) delete shellExt; return res; } -STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */) +Z7_COMWF_B CShellExtClassFactory::LockServer(BOOL /* fLock */) { return S_OK; // Check it } @@ -169,7 +187,8 @@ catch(...) { return E_OUTOFMEMORY; } if (!cf) return E_OUTOFMEMORY; - HRESULT res = cf->QueryInterface(riid, ppv); + IClassFactory *cf2 = cf; + const HRESULT res = cf2->QueryInterface(riid, ppv); if (res != S_OK) delete cf; return res; @@ -217,7 +236,7 @@ STDAPI DllRegisterServer(void) { - return RegisterServer() ? S_OK: SELFREG_E_CLASS; + return RegisterServer() ? S_OK: SELFREG_E_CLASS; } static BOOL UnregisterServer() diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/Explorer.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/Explorer.dsp --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/Explorer.dsp 2021-10-24 12:01:16.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/Explorer.dsp 2024-03-20 07:00:00.000000000 +0000 @@ -45,7 +45,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -72,7 +72,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -98,8 +98,8 @@ # PROP Intermediate_Dir "ReleaseU" # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -127,8 +127,8 @@ # PROP Intermediate_Dir "DebugU" # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -270,6 +270,10 @@ # End Source File # Begin Source File +SOURCE=..\FileManager\MyCom2.h +# End Source File +# Begin Source File + SOURCE=..\FileManager\ProgramLocation.cpp # End Source File # Begin Source File @@ -298,6 +302,18 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -307,6 +323,15 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -320,6 +345,10 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -356,6 +385,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -440,6 +473,10 @@ # End Group # Begin Source File +SOURCE=..\..\..\Windows\COM.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\DLL.cpp # End Source File # Begin Source File @@ -552,6 +589,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -567,5 +612,9 @@ SOURCE=.\ContextMenuFlags.h # End Source File +# Begin Source File + +SOURCE=..\FileManager\FM.ico +# End Source File # End Target # End Project diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyExplorerCommand.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyExplorerCommand.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyExplorerCommand.h 2021-12-25 12:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyExplorerCommand.h 2023-09-14 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // MyExplorerCommand.h -#ifndef __MY_EXPLORER_COMMAND_H -#define __MY_EXPLORER_COMMAND_H +#ifndef ZIP7_INC_MY_EXPLORER_COMMAND_H +#define ZIP7_INC_MY_EXPLORER_COMMAND_H #if _MSC_VER >= 1910 #define USE_SYS_shobjidl_core @@ -17,7 +17,9 @@ ShObjIdl.h : old Windows SDK ShObjIdl_core.h : new Windows 10 SDK */ +#ifndef Z7_OLD_WIN_SDK #include +#endif #ifndef __IShellItem_INTERFACE_DEFINED__ #define __IShellItem_INTERFACE_DEFINED__ @@ -87,7 +89,7 @@ #define PROPERTYKEY_DEFINED typedef -struct _tagpropertykey +struct { GUID fmtid; DWORD pid; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.cpp 2021-01-22 20:33:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.cpp 2024-03-10 09:00:00.000000000 +0000 @@ -11,19 +11,25 @@ using namespace NWindows; +extern bool g_DisableUserQuestions; + void ShowErrorMessage(HWND window, LPCWSTR message) { - ::MessageBoxW(window, message, L"7-Zip", MB_OK | MB_ICONSTOP); + if (!g_DisableUserQuestions) + ::MessageBoxW(window, message, L"7-Zip", MB_OK | MB_ICONSTOP); } -void ShowErrorMessageHwndRes(HWND window, UINT resID) +void ShowErrorMessageHwndRes(HWND window, UInt32 resID) { - ShowErrorMessage(window, LangString(resID)); + UString s = LangString(resID); + if (s.IsEmpty()) + s.Add_UInt32(resID); + ShowErrorMessage(window, s); } -void ShowErrorMessageRes(UINT resID) +void ShowErrorMessageRes(UInt32 resID) { - ShowErrorMessageHwndRes(0, resID); + ShowErrorMessageHwndRes(NULL, resID); } static void ShowErrorMessageDWORD(HWND window, DWORD errorCode) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.h 2013-01-17 10:33:38.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/MyMessages.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,16 +1,16 @@ // MyMessages.h -#ifndef __MY_MESSAGES_H -#define __MY_MESSAGES_H +#ifndef ZIP7_INC_MY_MESSAGES_H +#define ZIP7_INC_MY_MESSAGES_H #include "../../../Common/MyString.h" void ShowErrorMessage(HWND window, LPCWSTR message); -inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(0, message); } +inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(NULL, message); } void ShowErrorMessageHwndRes(HWND window, UInt32 langID); void ShowErrorMessageRes(UInt32 langID); -void ShowLastErrorMessage(HWND window = 0); +void ShowLastErrorMessage(HWND window = NULL); #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp 2021-02-10 17:38:20.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp 2024-01-25 06:00:00.000000000 +0000 @@ -48,17 +48,16 @@ }; -// can we use static RegDeleteKeyExW in _WIN64 mode? -// is it supported by Windows 2003 x64? - -/* -#ifdef _WIN64 - -#define INIT_REG_WOW - -#else -*/ +// RegDeleteKeyExW is supported starting from win2003sp1/xp-pro-x64 +// Z7_WIN32_WINNT_MIN < 0x0600 // Vista +#if !defined(Z7_WIN32_WINNT_MIN) \ + || Z7_WIN32_WINNT_MIN < 0x0502 /* < win2003 */ \ + || Z7_WIN32_WINNT_MIN == 0x0502 && !defined(_M_AMD64) +#define Z7_USE_DYN_RegDeleteKeyExW +#endif +#ifdef Z7_USE_DYN_RegDeleteKeyExW +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION typedef // WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved); @@ -67,28 +66,28 @@ static void Init_RegDeleteKeyExW() { if (!func_RegDeleteKeyExW) - func_RegDeleteKeyExW = (Func_RegDeleteKeyExW) - (void *)GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW"); + func_RegDeleteKeyExW = Z7_GET_PROC_ADDRESS( + Func_RegDeleteKeyExW, GetModuleHandleW(L"advapi32.dll"), + "RegDeleteKeyExW"); } - #define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW(); +#else +#define INIT_REG_WOW +#endif -// #endif static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow) { if (wow == 0) return RegDeleteKey(parentKey, name); - - /* - #ifdef _WIN64 - return RegDeleteKeyExW - #else - */ + +#ifdef Z7_USE_DYN_RegDeleteKeyExW if (!func_RegDeleteKeyExW) return E_NOTIMPL; return func_RegDeleteKeyExW - // #endif +#else + return RegDeleteKeyExW +#endif (parentKey, GetUnicodeString(name), wow, 0); } @@ -205,7 +204,7 @@ if (setMode) for (unsigned i = 0; i < 2; i++) { - for (unsigned k = 0; k < ARRAY_SIZE(k_shellex_Prefixes); k++) + for (unsigned k = 0; k < Z7_ARRAY_SIZE(k_shellex_Prefixes); k++) { CSysString s (k_shellex_Prefixes[k]); s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.h 2015-12-08 07:26:40.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/RegistryContextMenu.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // RegistryContextMenu.h -#ifndef __REGISTRY_CONTEXT_MENU_H -#define __REGISTRY_CONTEXT_MENU_H +#ifndef ZIP7_INC_REGISTRY_CONTEXT_MENU_H +#define ZIP7_INC_REGISTRY_CONTEXT_MENU_H #ifndef UNDER_CE diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/StdAfx.h 2014-04-23 08:53:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/StdAfx.h 2023-03-06 18:00:00.000000000 +0000 @@ -1,14 +1,6 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H - -// #define _WIN32_WINNT 0x0400 -#define _WIN32_WINNT 0x0500 -#define WINVER _WIN32_WINNT - -#include "../../../Common/Common.h" - -#include - +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../FileManager/StdAfx.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/makefile --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/makefile 2021-10-08 12:29:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,13 +1,14 @@ PROG = 7-zip.dll DEF_FILE = Explorer.def CFLAGS = $(CFLAGS) \ - -DLANG \ + -DZ7_LANG \ !IFDEF UNDER_CE LIBS = $(LIBS) Commctrl.lib !ELSE LIBS = $(LIBS) htmlhelp.lib comdlg32.lib Mpr.lib Gdi32.lib -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH +# CFLAGS = $(CFLAGS) -DZ7_LONG_PATH +# -DZ7_NO_LARGE_PAGES !ENDIF EXPLORER_OBJS = \ @@ -41,6 +42,7 @@ $O\ResourceString.obj \ $O\Shell.obj \ $O\Synchronization.obj \ + $O\TimeUtils.obj \ $O\Window.obj \ !IFDEF UNDER_CE @@ -72,4 +74,5 @@ $O\CpuArch.obj \ $O\Threads.obj \ +!include "../../Sort.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/resource.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/resource.h 2014-04-23 07:52:29.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource.h 2023-01-04 20:00:00.000000000 +0000 @@ -10,4 +10,6 @@ #define IDS_CONTEXT_COMPRESS_EMAIL 2329 #define IDS_CONTEXT_COMPRESS_TO_EMAIL 2330 +#define IDS_SELECT_FILES 3015 + #define IDB_MENU_LOGO 190 diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/resource2.rc 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource2.rc --- 7zip-22.01+dfsg/CPP/7zip/UI/Explorer/resource2.rc 2013-12-30 08:37:01.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Explorer/resource2.rc 2023-01-04 20:00:00.000000000 +0000 @@ -13,6 +13,7 @@ IDS_CONTEXT_COMPRESS_TO "Add to {0}" IDS_CONTEXT_COMPRESS_EMAIL "Compress and email..." IDS_CONTEXT_COMPRESS_TO_EMAIL "Compress to {0} and email" + IDS_SELECT_FILES "You must select one or more files" END IDB_MENU_LOGO BITMAP "../../UI/Explorer/MenuLogo.bmp" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.cpp 2021-10-21 18:19:13.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.cpp 2023-03-20 17:00:00.000000000 +0000 @@ -2,7 +2,7 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -16,7 +16,7 @@ using namespace NWindows; using namespace NFar; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -31,10 +31,6 @@ extern void PrintMessage(const char *message); -CExtractCallbackImp::~CExtractCallbackImp() -{ -} - void CExtractCallbackImp::Init( UINT codePage, CProgressBox *progressBox, @@ -47,7 +43,7 @@ _percent = progressBox; } -STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) { MT_LOCK @@ -59,7 +55,7 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) { MT_LOCK @@ -72,15 +68,15 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackImp::AskOverwrite( +Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) + Int32 *answer)) { MT_LOCK NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo; - oldFileInfo.TimeIsDefined = (existTime != 0); + oldFileInfo.TimeIsDefined = (existTime != NULL); if (oldFileInfo.TimeIsDefined) oldFileInfo.Time = *existTime; oldFileInfo.SizeIsDefined = (existSize != NULL); @@ -88,7 +84,7 @@ oldFileInfo.Size = *existSize; oldFileInfo.Name = existName; - newFileInfo.TimeIsDefined = (newTime != 0); + newFileInfo.TimeIsDefined = (newTime != NULL); if (newFileInfo.TimeIsDefined) newFileInfo.Time = *newTime; newFileInfo.SizeIsDefined = (newSize != NULL); @@ -99,7 +95,7 @@ NOverwriteDialog::NResult::EEnum result = NOverwriteDialog::Execute(oldFileInfo, newFileInfo); - switch (result) + switch ((int)result) { case NOverwriteDialog::NResult::kCancel: // *answer = NOverwriteAnswer::kCancel; @@ -132,7 +128,7 @@ static const char * const kSkipString = "Skipping"; static const char * const kReadString = "Reading"; -STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */) +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */)) { MT_LOCK @@ -146,7 +142,7 @@ case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break; case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; break; default: s = "???"; // return E_FAIL; - }; + } if (_percent) { @@ -158,7 +154,7 @@ return CheckBreak2(); } -STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message) +Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *message)) { MT_LOCK @@ -199,7 +195,7 @@ } if (messageID != 0) { - s = g_StartupInfo.GetMsgString(messageID); + s = g_StartupInfo.GetMsgString((int)messageID); s.Replace((AString)" '%s'", AString()); } else if (opRes == NArchive::NExtract::NOperationResult::kUnavailable) @@ -217,13 +213,13 @@ else { s = "Error #"; - s.Add_UInt32(opRes); + s.Add_UInt32((UInt32)opRes); } } } } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted) +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)) { MT_LOCK @@ -248,7 +244,7 @@ } -STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) { MT_LOCK @@ -265,13 +261,13 @@ extern HRESULT GetPassword(UString &password); -STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)) { MT_LOCK if (!m_PasswordIsDefined) { - RINOK(GetPassword(m_Password)); + RINOK(GetPassword(m_Password)) m_PasswordIsDefined = true; } return StringToBstr(m_Password, password); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.h 2015-03-19 11:47:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ExtractEngine.h 2023-03-19 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ExtractEngine.h -#ifndef __EXTRACT_ENGINE_H -#define __EXTRACT_ENGINE_H +#ifndef ZIP7_INC_EXTRACT_ENGINE_H +#define ZIP7_INC_EXTRACT_ENGINE_H #include "../../../Common/MyCom.h" #include "../../../Common/MyString.h" @@ -11,26 +11,14 @@ #include "ProgressBox.h" -class CExtractCallbackImp: - public IFolderArchiveExtractCallback, - public IFolderArchiveExtractCallback2, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP2(ICryptoGetTextPassword, IFolderArchiveExtractCallback2) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - INTERFACE_IFolderArchiveExtractCallback(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *password); +Z7_CLASS_IMP_COM_3( + CExtractCallbackImp + , IFolderArchiveExtractCallback + , IFolderArchiveExtractCallback2 + , ICryptoGetTextPassword +) + Z7_IFACE_COM7_IMP(IProgress) -private: UString m_CurrentFilePath; CProgressBox *_percent; @@ -47,8 +35,6 @@ */ void AddErrorMessage(LPCTSTR message); public: - // CExtractCallbackImp() {} - ~CExtractCallbackImp(); void Init(UINT codePage, CProgressBox *progressBox, bool passwordIsDefined, const UString &password); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/Far.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/Far.cpp 2021-03-05 19:07:55.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -3,12 +3,7 @@ #include "StdAfx.h" -#ifdef __clang__ - #pragma clang diagnostic ignored "-Wmissing-prototypes" -#endif - #include "../../../Common/MyWindows.h" - #include "../../../Common/MyInitGuid.h" #include "../../../Common/StringConvert.h" @@ -35,10 +30,14 @@ static const char * const kHelpTopicConfig = "Config"; static bool kPluginEnabledDefault = true; +extern +HINSTANCE g_hInstance; HINSTANCE g_hInstance; namespace NFar { +extern +const char *g_PluginName_for_Error; const char *g_PluginName_for_Error = "7-Zip"; } @@ -49,9 +48,16 @@ BOOL WINAPI DllMain( #ifdef UNDER_CE - HANDLE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID); +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE #else - HINSTANCE + HINSTANCE #endif hInstance, DWORD dwReason, LPVOID) { @@ -89,7 +95,7 @@ EXTERN_C void WINAPI SetStartupInfo(const PluginStartupInfo *info) { - MY_TRY_BEGIN; + MY_TRY_BEGIN g_StartupInfo.Init(*info, kPliginNameForRegistry); g_Options.Enabled = g_StartupInfo.QueryRegKeyValue( HKEY_CURRENT_USER, kRegisrtryMainKeyName, @@ -98,72 +104,35 @@ // OutputDebugStringA("SetStartupInfo"); // LoadGlobalCodecs(); - MY_TRY_END1("SetStartupInfo"); + MY_TRY_END1("SetStartupInfo") } -class COpenArchiveCallback: - public IArchiveOpenCallback, - public IArchiveOpenVolumeCallback, - public IArchiveOpenSetSubArchiveName, - public IProgress, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ - DWORD m_StartTickValue; +Z7_CLASS_IMP_COM_3( + COpenArchiveCallback + , IArchiveOpenCallback + , IProgress + , ICryptoGetTextPassword +) + // DWORD m_StartTickValue; bool m_MessageBoxIsShown; - CProgressBox _progressBox; - bool _numFilesTotalDefined; bool _numBytesTotalDefined; - - NFind::CFileInfo _fileInfo; - bool _subArchiveMode; - UString _subArchiveName; public: bool PasswordIsDefined; UString Password; - FString _folderPrefix; - +private: + CProgressBox _progressBox; public: - MY_UNKNOWN_IMP4( - IArchiveOpenVolumeCallback, - IArchiveOpenSetSubArchiveName, - IProgress, - ICryptoGetTextPassword - ) - // IProgress - STDMETHOD(SetTotal)(UInt64 total); - STDMETHOD(SetCompleted)(const UInt64 *aCompleteValue); - - // IArchiveOpenCallback - STDMETHOD(SetTotal)(const UInt64 *numFiles, const UInt64 *numBytes); - STDMETHOD(SetCompleted)(const UInt64 *numFiles, const UInt64 *numBytes); - - // IArchiveOpenVolumeCallback - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); - - STDMETHOD(SetSubArchiveName(const wchar_t *name)) - { - _subArchiveMode = true; - _subArchiveName = name; - return S_OK; - } - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - COpenArchiveCallback(): _subArchiveMode(false) {} + COpenArchiveCallback() + {} void Init() { PasswordIsDefined = false; - _subArchiveMode = false; - _numFilesTotalDefined = false; _numBytesTotalDefined = false; @@ -174,13 +143,6 @@ g_StartupInfo.GetMsgString(NMessageID::kReading)); } void ShowMessage(); - - void LoadFileInfo(const FString &folderPrefix, const FString &fileName) - { - _folderPrefix = folderPrefix; - if (!_fileInfo.Find(_folderPrefix + fileName)) - throw 1; - } }; static HRESULT CheckBreak2() @@ -202,7 +164,7 @@ _progressBox.Print(); } -STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes) +Z7_COM7F_IMF(COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes)) { _numFilesTotalDefined = (numFiles != NULL); if (_numFilesTotalDefined) @@ -215,7 +177,7 @@ return CheckBreak2(); } -STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes) +Z7_COM7F_IMF(COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes)) { if (numFiles) _progressBox.Files = *numFiles; @@ -228,63 +190,18 @@ } -STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 /* total */) +Z7_COM7F_IMF(COpenArchiveCallback::SetTotal(const UInt64 /* total */)) { return CheckBreak2(); } -STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 * /* completed */) +Z7_COM7F_IMF(COpenArchiveCallback::SetCompleted(const UInt64 * /* completed */)) { ShowMessage(); return CheckBreak2(); } -STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream) -{ - if (WasEscPressed()) - return E_ABORT; - if (_subArchiveMode) - return S_FALSE; - *inStream = NULL; - FString fullPath = _folderPrefix + us2fs(name); - if (!_fileInfo.Find(fullPath)) - return S_FALSE; - if (_fileInfo.IsDir()) - return S_FALSE; - CInFileStream *inFile = new CInFileStream; - CMyComPtr inStreamTemp = inFile; - if (!inFile->Open(fullPath)) - return ::GetLastError(); - *inStream = inStreamTemp.Detach(); - return S_OK; -} - - -STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - if (_subArchiveMode) - { - switch (propID) - { - case kpidName: prop = _subArchiveName; break; - } - } - else - switch (propID) - { - case kpidName: prop = GetUnicodeString(_fileInfo.Name, CP_OEMCP); break; - case kpidIsDir: prop = _fileInfo.IsDir(); break; - case kpidSize: prop = _fileInfo.Size; break; - case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break; - case kpidCTime: prop = _fileInfo.CTime; break; - case kpidATime: prop = _fileInfo.ATime; break; - case kpidMTime: prop = _fileInfo.MTime; break; - } - prop.Detach(value); - return S_OK; -} - +HRESULT GetPassword(UString &password); HRESULT GetPassword(UString &password) { if (WasEscPressed()) @@ -297,7 +214,7 @@ { DI_PSWEDIT, 5, 3, 70, 3, true, false, 0, true, -1, "", NULL } }; - const int kNumItems = ARRAY_SIZE(initItems); + const int kNumItems = Z7_ARRAY_SIZE(initItems); FarDialogItem dialogItems[kNumItems]; g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumItems); @@ -309,11 +226,11 @@ return S_OK; } -STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)) { if (!PasswordIsDefined) { - RINOK(GetPassword(Password)); + RINOK(GetPassword(Password)) PasswordIsDefined = true; } return StringToBstr(Password, password); @@ -357,14 +274,19 @@ } COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback; - CMyComPtr openArchiveCallback = openArchiveCallbackSpec; + CMyComPtr uiCallback = openArchiveCallbackSpec; + + /* COpenCallbackImp object will exist after Open stage for multivolume archioves */ + COpenCallbackImp *impSpec = new COpenCallbackImp; + CMyComPtr impCallback = impSpec; + impSpec->ReOpenCallback = openArchiveCallbackSpec; // we set pointer without reference counter // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) openArchiveCallbackSpec->Init(); { FString dirPrefix, fileName; GetFullPathAndSplit(fullName, dirPrefix, fileName); - openArchiveCallbackSpec->LoadFileInfo(dirPrefix, fileName); + impSpec->Init2(dirPrefix, fileName); } // ::OutputDebugStringA("before OpenArchive\n"); @@ -373,7 +295,7 @@ archiveHandler = agent; CMyComBSTR archiveType; HRESULT result = archiveHandler->Open(NULL, - GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, openArchiveCallback); + GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, impCallback); /* HRESULT result = ::OpenArchive(fullName, &archiveHandler, archiverInfoResult, defaultName, openArchiveCallback); @@ -425,9 +347,9 @@ return MyOpenFilePluginW(GetUnicodeString(name, codePage), isAbortCodeSupported); } -EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char * /* data */, int /* dataSize */) +EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const Byte * /* data */, int /* dataSize */) { - MY_TRY_BEGIN; + MY_TRY_BEGIN // OutputDebugStringA("--- OpenFilePlugin"); if (name == NULL || (!g_Options.Enabled)) { @@ -435,13 +357,13 @@ return(INVALID_HANDLE_VALUE); } return MyOpenFilePlugin(name, true); // isAbortCodeSupported - MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE); + MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE) } /* -EXTERN_C HANDLE WINAPI OpenFilePluginW(const wchar_t *name,const unsigned char *Data,int DataSize,int OpMode) +EXTERN_C HANDLE WINAPI OpenFilePluginW(const wchar_t *name,const Byte *Data,int DataSize,int OpMode) { - MY_TRY_BEGIN; + MY_TRY_BEGIN if (name == NULL || (!g_Options.Enabled)) { // if (!Opt.ProcessShiftF1) @@ -455,7 +377,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) { - MY_TRY_BEGIN; + MY_TRY_BEGIN if (openFrom == OPEN_COMMANDLINE) { @@ -511,13 +433,13 @@ } return INVALID_HANDLE_VALUE; - MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE); + MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE) } EXTERN_C void WINAPI ClosePlugin(HANDLE plugin) { // OutputDebugStringA("-- ClosePlugin --- START"); - // MY_TRY_BEGIN; + // MY_TRY_BEGIN delete (CPlugin *)plugin; // OutputDebugStringA("-- ClosePlugin --- END"); // MY_TRY_END1("ClosePlugin"); @@ -525,14 +447,14 @@ EXTERN_C int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, int *itemsNumber, int opMode) { - MY_TRY_BEGIN; + MY_TRY_BEGIN return(((CPlugin *)plugin)->GetFindData(panelItems, itemsNumber, opMode)); - MY_TRY_END2("GetFindData", FALSE); + MY_TRY_END2("GetFindData", FALSE) } EXTERN_C void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber) { - // MY_TRY_BEGIN; + // MY_TRY_BEGIN ((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber); // MY_TRY_END1("FreeFindData"); } @@ -540,43 +462,43 @@ EXTERN_C int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber, int move, char *destPath, int opMode) { - MY_TRY_BEGIN; - return(((CPlugin *)plugin)->GetFiles(panelItems, itemsNumber, move, destPath, opMode)); - MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError); + MY_TRY_BEGIN + return(((CPlugin *)plugin)->GetFiles(panelItems, (unsigned)itemsNumber, move, destPath, opMode)); + MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError) } EXTERN_C int WINAPI SetDirectory(HANDLE plugin, const char *dir, int opMode) { - MY_TRY_BEGIN; + MY_TRY_BEGIN return(((CPlugin *)plugin)->SetDirectory(dir, opMode)); - MY_TRY_END2("SetDirectory", FALSE); + MY_TRY_END2("SetDirectory", FALSE) } EXTERN_C void WINAPI GetPluginInfo(struct PluginInfo *info) { - MY_TRY_BEGIN; + MY_TRY_BEGIN info->StructSize = sizeof(*info); info->Flags = 0; info->DiskMenuStrings = NULL; info->DiskMenuNumbers = NULL; info->DiskMenuStringsNumber = 0; - static const char *pluginMenuStrings[2]; - pluginMenuStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); - pluginMenuStrings[1] = g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString); + static char *pluginMenuStrings[2]; + pluginMenuStrings[0] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString)); + pluginMenuStrings[1] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString)); info->PluginMenuStrings = (char **)pluginMenuStrings; info->PluginMenuStringsNumber = 2; - static const char *pluginCfgStrings[1]; - pluginCfgStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); + static char *pluginCfgStrings[1]; + pluginCfgStrings[0] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString)); info->PluginConfigStrings = (char **)pluginCfgStrings; - info->PluginConfigStringsNumber = ARRAY_SIZE(pluginCfgStrings); - info->CommandPrefix = (char *)kCommandPrefix; - MY_TRY_END1("GetPluginInfo"); + info->PluginConfigStringsNumber = Z7_ARRAY_SIZE(pluginCfgStrings); + info->CommandPrefix = const_cast(kCommandPrefix); + MY_TRY_END1("GetPluginInfo") } EXTERN_C int WINAPI Configure(int /* itemNumber */) { - MY_TRY_BEGIN; + MY_TRY_BEGIN const int kEnabledCheckBoxIndex = 1; @@ -591,7 +513,7 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }, }; - const int kNumDialogItems = ARRAY_SIZE(initItems); + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); const int kOkButtonIndex = kNumDialogItems - 2; FarDialogItem dialogItems[kNumDialogItems]; @@ -608,33 +530,59 @@ g_StartupInfo.SetRegKeyValue(HKEY_CURRENT_USER, kRegisrtryMainKeyName, kRegisrtryValueNameEnabled, g_Options.Enabled); return(TRUE); - MY_TRY_END2("Configure", FALSE); + MY_TRY_END2("Configure", FALSE) } EXTERN_C void WINAPI GetOpenPluginInfo(HANDLE plugin,struct OpenPluginInfo *info) { - MY_TRY_BEGIN; + MY_TRY_BEGIN ((CPlugin *)plugin)->GetOpenPluginInfo(info); - MY_TRY_END1("GetOpenPluginInfo"); + MY_TRY_END1("GetOpenPluginInfo") } EXTERN_C int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber, int move, int opMode) { - MY_TRY_BEGIN; - return (((CPlugin *)plugin)->PutFiles(panelItems, itemsNumber, move, opMode)); - MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError); + MY_TRY_BEGIN + return (((CPlugin *)plugin)->PutFiles(panelItems, (unsigned)itemsNumber, move, opMode)); + MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError) } EXTERN_C int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, int itemsNumber, int opMode) { - MY_TRY_BEGIN; - return (((CPlugin *)plugin)->DeleteFiles(panelItems, itemsNumber, opMode)); - MY_TRY_END2("DeleteFiles", FALSE); + MY_TRY_BEGIN + return (((CPlugin *)plugin)->DeleteFiles(panelItems, (unsigned)itemsNumber, opMode)); + MY_TRY_END2("DeleteFiles", FALSE) } -EXTERN_C int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState) +EXTERN_C int WINAPI ProcessKey(HANDLE plugin, int key, unsigned controlState) { - MY_TRY_BEGIN; + MY_TRY_BEGIN + /* FIXME: after folder creation with F7, it doesn't reload new file list + We need some to reload it */ return (((CPlugin *)plugin)->ProcessKey(key, controlState)); - MY_TRY_END2("ProcessKey", FALSE); + MY_TRY_END2("ProcessKey", FALSE) } + +/* +struct MakeDirectoryInfo +{ + size_t StructSize; + HANDLE hPanel; + const wchar_t *Name; + OPERATION_MODES OpMode; + void* Instance; +}; + +typedef INT_PTR MY_intptr_t; + +MY_intptr_t WINAPI MakeDirectoryW(struct MakeDirectoryInfo *Info) +{ + MY_TRY_BEGIN + if (Info->StructSize < sizeof(MakeDirectoryInfo)) + { + return 0; + } + return 0; + MY_TRY_END2("MakeDirectoryW", FALSE); +} +*/ diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/Far.dsp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.dsp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/Far.dsp 2021-10-07 18:28:11.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Far.dsp 2023-03-25 16:00:00.000000000 +0000 @@ -43,7 +43,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "EXTERNAL_CODECS" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "EXTERNAL_CODECS" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -114,6 +114,10 @@ # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -134,6 +138,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -142,6 +150,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyVector.cpp # End Source File # Begin Source File @@ -150,6 +162,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -334,6 +350,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -374,6 +398,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\TimeUtils.cpp # End Source File # Begin Source File @@ -562,10 +594,6 @@ # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveFolderOpen.cpp -# End Source File -# Begin Source File - SOURCE=..\Agent\ArchiveFolderOut.cpp # End Source File # Begin Source File @@ -700,6 +728,14 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -709,6 +745,10 @@ # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarPlugin.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarPlugin.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarPlugin.h 2015-03-21 12:27:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarPlugin.h 2024-01-27 13:00:00.000000000 +0000 @@ -7,7 +7,7 @@ // #define __FAR_PLUGIN_H #ifdef UNDER_CE -typedef struct _CHAR_INFO { +typedef struct { union { WCHAR UnicodeChar; CHAR AsciiChar; @@ -16,8 +16,8 @@ } CHAR_INFO, *PCHAR_INFO; #endif -#ifndef __FAR_PLUGIN_H -#define __FAR_PLUGIN_H +#ifndef ZIP7_INC_FAR_PLUGIN_H +#define ZIP7_INC_FAR_PLUGIN_H #ifndef _WIN64 #if defined(__BORLANDC__) && (__BORLANDC <= 0x520) @@ -29,9 +29,9 @@ #endif #endif - #if _MSC_VER + // #if _MSC_VER #define _export - #endif + // #endif #define NM 260 @@ -82,7 +82,7 @@ int X, int Y, int MaxHeight, - unsigned int Flags, + unsigned Flags, char *Title, char *Bottom, char *HelpTopic, @@ -122,7 +122,7 @@ typedef int (WINAPI *FARAPIMESSAGE)( INT_PTR PluginNumber, - unsigned int Flags, + unsigned Flags, const char *HelpTopic, const char * const *Items, int ItemsNumber, @@ -177,7 +177,7 @@ int ListPos; CHAR_INFO *VBuf; }; - unsigned int Flags; + unsigned Flags; int DefaultButton; char Data[512]; }; @@ -495,7 +495,7 @@ EXTERN_C_BEGIN void WINAPI _export ClosePluginW(HANDLE hPlugin); - int WINAPI _export CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned int Mode); + int WINAPI _export CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned Mode); int WINAPI _export ConfigureW(int ItemNumber); int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); void WINAPI _export ExitFARW(void); @@ -515,7 +515,7 @@ int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec); int WINAPI _export ProcessEventW(HANDLE hPlugin,int Event,void *Param); int WINAPI _export ProcessHostFileW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); - int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState); + int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned ControlState); int WINAPI _export ProcessSynchroEventW(int Event,void *Param); int WINAPI _export ProcessViewerEventW(int Event,void *Param); int WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath,int OpMode); @@ -525,5 +525,36 @@ EXTERN_C_END */ +EXTERN_C_BEGIN + + void WINAPI _export ClosePlugin(HANDLE hPlugin); + int WINAPI _export Compare(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned Mode); + int WINAPI _export Configure(int ItemNumber); + int WINAPI _export DeleteFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + void WINAPI _export ExitFAR(void); + void WINAPI _export FreeFindData(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export FreeVirtualFindData(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + int WINAPI _export GetFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,char *DestPath,int OpMode); + int WINAPI _export GetFindData(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode); + int WINAPI _export GetMinFarVersion(void); + void WINAPI _export GetOpenPluginInfo(HANDLE hPlugin,struct OpenPluginInfo *Info); + void WINAPI _export GetPluginInfo(struct PluginInfo *Info); + int WINAPI _export GetVirtualFindData(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const char *Path); + int WINAPI _export MakeDirectory(HANDLE hPlugin,char *Name,int OpMode); + HANDLE WINAPI _export OpenFilePlugin(char *Name,const BYTE *Data,int DataSize); + HANDLE WINAPI _export OpenPlugin(int OpenFrom,INT_PTR Item); + int WINAPI _export ProcessDialogEvent(int Event,void *Param); + int WINAPI _export ProcessEditorEvent(int Event,void *Param); + int WINAPI _export ProcessEditorInput(const INPUT_RECORD *Rec); + int WINAPI _export ProcessEvent(HANDLE hPlugin,int Event,void *Param); + int WINAPI _export ProcessHostFile(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + int WINAPI _export ProcessKey(HANDLE hPlugin,int Key,unsigned ControlState); + int WINAPI _export ProcessViewerEvent(int Event,void *Param); + int WINAPI _export PutFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,int OpMode); + int WINAPI _export SetDirectory(HANDLE hPlugin,const char *Dir,int OpMode); + int WINAPI _export SetFindList(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info); + +EXTERN_C_END #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarUtils.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarUtils.cpp 2021-12-15 19:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -35,11 +35,11 @@ return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId); } -int CStartupInfo::ShowMessage(unsigned int flags, - const char *helpTopic, const char **items, int numItems, int numButtons) +int CStartupInfo::ShowMessage(UInt32 flags, + const char *helpTopic, const char **items, unsigned numItems, int numButtons) { return m_Data.Message(m_Data.ModuleNumber, flags, helpTopic, - items, numItems, numButtons); + items, (int)numItems, numButtons); } namespace NMessageID @@ -53,7 +53,7 @@ }; } -int CStartupInfo::ShowWarningWithOk(const char **items, int numItems) +int CStartupInfo::ShowWarningWithOk(const char **items, unsigned numItems) { return ShowMessage(FMSG_WARNING | FMSG_MB_OK, NULL, items, numItems, 0); } @@ -76,7 +76,7 @@ AString s; SetErrorTitle(s); const char *items[]= { s, message }; - return ShowWarningWithOk(items, ARRAY_SIZE(items)); + return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items)); } */ @@ -85,7 +85,7 @@ AString s; SetErrorTitle(s); const char *items[]= { s, m1, m2 }; - return ShowWarningWithOk(items, ARRAY_SIZE(items)); + return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items)); } static void SplitString(const AString &src, AStringVector &destStrings) @@ -145,14 +145,14 @@ } int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, - const char *helpTopic, struct FarDialogItem *items, int numItems) + const char *helpTopic, struct FarDialogItem *items, unsigned numItems) { - return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)helpTopic, - items, numItems); + return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, const_cast(helpTopic), + items, (int)numItems); } int CStartupInfo::ShowDialog(int sizeX, int sizeY, - const char *helpTopic, struct FarDialogItem *items, int numItems) + const char *helpTopic, struct FarDialogItem *items, unsigned numItems) { return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems); } @@ -160,9 +160,9 @@ inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); } void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems, - FarDialogItem *destItems, int numItems) + FarDialogItem *destItems, unsigned numItems) { - for (int i = 0; i < numItems; i++) + for (unsigned i = 0; i < numItems; i++) { const CInitDialogItem &srcItem = srcItems[i]; FarDialogItem &destItem = destItems[i]; @@ -186,8 +186,8 @@ MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId)); /* - if ((unsigned int)Init[i].Data < 0xFFF) - MyStringCopy(destItem.Data, GetMsg((unsigned int)srcItem.Data)); + if ((unsigned)Init[i].Data < 0xFFF) + MyStringCopy(destItem.Data, GetMsg((unsigned)srcItem.Data)); else MyStringCopy(destItem.Data,srcItem.Data); */ @@ -281,7 +281,7 @@ return valueDefault; UInt32 value; - if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS) return valueDefault; return value; @@ -295,7 +295,7 @@ return valueDefault; bool value; - if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS) return valueDefault; return value; @@ -356,7 +356,7 @@ if (!ControlGetActivePanelInfo(panelInfo)) return false; for (int i = 0; i < panelInfo.ItemsNumber; i++) - panelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED; + panelInfo.PanelItems[i].Flags &= ~(DWORD)PPIF_SELECTED; return ControlSetSelection(panelInfo); } @@ -367,32 +367,35 @@ int x, int y, int maxHeight, - unsigned int flags, + unsigned flags, const char *title, const char *aBottom, const char *helpTopic, int *breakKeys, int *breakCode, struct FarMenuItem *items, - int numItems) + unsigned numItems) { - return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, (char *)title, - (char *)aBottom, (char *)helpTopic, breakKeys, breakCode, items, numItems); + return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, + const_cast(title), + const_cast(aBottom), + const_cast(helpTopic), + breakKeys, breakCode, items, (int)numItems); } int CStartupInfo::Menu( - unsigned int flags, + unsigned flags, const char *title, const char *helpTopic, struct FarMenuItem *items, - int numItems) + unsigned numItems) { return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL, NULL, items, numItems); } int CStartupInfo::Menu( - unsigned int flags, + unsigned flags, const char *title, const char *helpTopic, const AStringVector &items, @@ -405,11 +408,11 @@ item.Checked = 0; item.Separator = 0; item.Selected = ((int)i == selectedItem); - const AString reducedString (items[i].Left(ARRAY_SIZE(item.Text) - 1)); + const AString reducedString (items[i].Left(Z7_ARRAY_SIZE(item.Text) - 1)); MyStringCopy(item.Text, reducedString); farMenuItems.Add(item); } - return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size()); + return Menu(flags, title, helpTopic, farMenuItems.NonConstData(), farMenuItems.Size()); } @@ -435,7 +438,7 @@ g_StartupInfo.RestoreScreen(m_HANDLE); m_Saved = false; } -}; +} int PrintErrorMessage(const char *message, unsigned code) { @@ -471,7 +474,7 @@ int ShowSysErrorMessage(DWORD errorCode) { - UString message = NError::MyFormatMessage(errorCode); + const UString message = NError::MyFormatMessage(errorCode); return g_StartupInfo.ShowErrorMessage(UnicodeStringToMultiByte(message, CP_OEMCP)); } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarUtils.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/FarUtils.h 2017-03-26 10:32:33.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/FarUtils.h 2023-09-06 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // FarUtils.h -#ifndef __FAR_UTILS_H -#define __FAR_UTILS_H +#ifndef ZIP7_INC_FAR_UTILS_H +#define ZIP7_INC_FAR_UTILS_H #include "FarPlugin.h" @@ -36,7 +36,7 @@ int X1,Y1,X2,Y2; bool Focus; bool Selected; - unsigned int Flags; //FarDialogItemFlags Flags; + UInt32 Flags; //FarDialogItemFlags Flags; bool DefaultButton; int DataMessageId; const char *DataString; @@ -60,9 +60,9 @@ const char *pluginNameForRegistry); const char *GetMsgString(int messageId); - int ShowMessage(unsigned int flags, const char *helpTopic, - const char **items, int numItems, int numButtons); - int ShowWarningWithOk(const char **items, int numItems); + int ShowMessage(UInt32 flags, const char *helpTopic, + const char **items, unsigned numItems, int numButtons); + int ShowWarningWithOk(const char **items, unsigned numItems); void SetErrorTitle(AString &s); int ShowErrorMessage(const char *message); @@ -71,12 +71,12 @@ int ShowMessage(int messageId); int ShowDialog(int X1, int Y1, int X2, int Y2, - const char *helpTopic, struct FarDialogItem *items, int numItems); + const char *helpTopic, struct FarDialogItem *items, unsigned numItems); int ShowDialog(int sizeX, int sizeY, - const char *helpTopic, struct FarDialogItem *items, int numItems); + const char *helpTopic, struct FarDialogItem *items, unsigned numItems); void InitDialogItems(const CInitDialogItem *srcItems, - FarDialogItem *destItems, int numItems); + FarDialogItem *destItems, unsigned numItems); HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); HANDLE SaveScreen(); @@ -112,23 +112,23 @@ int x, int y, int maxHeight, - unsigned int flags, + unsigned flags, const char *title, const char *aBottom, const char *helpTopic, int *breakKeys, int *breakCode, FarMenuItem *items, - int numItems); + unsigned numItems); int Menu( - unsigned int flags, + unsigned flags, const char *title, const char *helpTopic, FarMenuItem *items, - int numItems); + unsigned numItems); int Menu( - unsigned int flags, + unsigned flags, const char *title, const char *helpTopic, const AStringVector &items, @@ -136,14 +136,14 @@ int Editor(const char *fileName, const char *title, int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar) - { return m_Data.Editor((char *)fileName, (char *)title, X1, Y1, X2, Y2, + { return m_Data.Editor(const_cast(fileName), const_cast(title), X1, Y1, X2, Y2, flags, startLine, startChar); } int Editor(const char *fileName) { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); } int Viewer(const char *fileName, const char *title, int X1, int Y1, int X2, int Y2, DWORD flags) - { return m_Data.Viewer((char *)fileName, (char *)title, X1, Y1, X2, Y2, flags); } + { return m_Data.Viewer(const_cast(fileName), const_cast(title), X1, Y1, X2, Y2, flags); } int Viewer(const char *fileName) { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } @@ -154,7 +154,7 @@ bool m_Saved; HANDLE m_HANDLE; public: - CScreenRestorer(): m_Saved(false){}; + CScreenRestorer(): m_Saved(false) {} ~CScreenRestorer(); void Save(); void Restore(); @@ -184,10 +184,16 @@ catch(const wchar_t *s) { PrintErrorMessage(x, s); return y; }\ catch(...) { g_StartupInfo.ShowErrorMessage(x); return y; } + int ShowSysErrorMessage(DWORD errorCode); int ShowSysErrorMessage(DWORD errorCode, const wchar_t *name); int ShowLastErrorMessage(); +inline int ShowSysErrorMessage(HRESULT errorCode) + { return ShowSysErrorMessage((DWORD)errorCode); } +inline int ShowSysErrorMessage(HRESULT errorCode, const wchar_t *name) + { return ShowSysErrorMessage((DWORD)errorCode, name); } + bool WasEscPressed(); void ReduceString(UString &s, unsigned size); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/Messages.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Messages.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/Messages.h 2017-05-05 09:10:41.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Messages.h 2023-03-25 13:00:00.000000000 +0000 @@ -1,13 +1,13 @@ // Far/Messages.h -#ifndef __7ZIP_FAR_MESSAGES_H -#define __7ZIP_FAR_MESSAGES_H +#ifndef ZIP7_INC_FAR_MESSAGES_H +#define ZIP7_INC_FAR_MESSAGES_H #include "../../PropID.h" namespace NMessageID { -const unsigned k_Last_PropId_supported_by_plugin = kpidCopyLink; +const unsigned k_Last_PropId_supported_by_plugin = kpidDevMinor; enum EEnum { diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.cpp 2021-02-10 17:49:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.cpp 2024-03-13 06:00:00.000000000 +0000 @@ -35,7 +35,7 @@ { ConvertUInt64ToString(fileInfo.Size, buffer); fileInfoStrings.Size = buffer; - fileInfoStrings.Size += ' '; + fileInfoStrings.Size.Add_Space(); fileInfoStrings.Size += g_StartupInfo.GetMsgString(NMessageID::kOverwriteBytes); } else @@ -46,10 +46,10 @@ fileInfoStrings.Time.Empty(); if (fileInfo.TimeIsDefined) { - char timeString[32]; + char timeString[64]; ConvertUtcFileTimeToString(fileInfo.Time, timeString); fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn); - fileInfoStrings.Time += ' '; + fileInfoStrings.Time.Add_Space(); fileInfoStrings.Time += timeString; } } @@ -96,12 +96,12 @@ ReduceString2(name2, maxNameLen - kNameOffset); } - AString pref1A (UnicodeStringToMultiByte(pref1, CP_OEMCP)); - AString pref2A (UnicodeStringToMultiByte(pref2, CP_OEMCP)); - AString name1A (UnicodeStringToMultiByte(name1, CP_OEMCP)); - AString name2A (UnicodeStringToMultiByte(name2, CP_OEMCP)); + const AString pref1A (UnicodeStringToMultiByte(pref1, CP_OEMCP)); + const AString pref2A (UnicodeStringToMultiByte(pref2, CP_OEMCP)); + const AString name1A (UnicodeStringToMultiByte(name1, CP_OEMCP)); + const AString name2A (UnicodeStringToMultiByte(name2, CP_OEMCP)); - struct CInitDialogItem initItems[]={ + const struct CInitDialogItem initItems[]={ { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL }, { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessage1, NULL, NULL }, @@ -131,10 +131,10 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteCancel, NULL, NULL } }; - const int kNumDialogItems = ARRAY_SIZE(initItems); + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); FarDialogItem aDialogItems[kNumDialogItems]; g_StartupInfo.InitDialogItems(initItems, aDialogItems, kNumDialogItems); - int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + const int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize, NULL, aDialogItems, kNumDialogItems); const int kButtonStartPos = kNumDialogItems - 6; if (anAskCode >= kButtonStartPos && anAskCode < kNumDialogItems) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.h 2013-01-25 07:27:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/OverwriteDialogFar.h 2023-01-22 20:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // OverwriteDialogFar.h -#ifndef __OVERWRITE_DIALOG_FAR_H -#define __OVERWRITE_DIALOG_FAR_H +#ifndef ZIP7_INC_OVERWRITE_DIALOG_FAR_H +#define ZIP7_INC_OVERWRITE_DIALOG_FAR_H #include "../../../Common/MyString.h" #include "../../../Common/MyTypes.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/Plugin.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/Plugin.cpp 2021-10-21 18:31:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -20,13 +20,13 @@ using namespace NDir; using namespace NFar; -// This function is unused +// This function is used by CAgentFolder +int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2); int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2) { return MyStringCompareNoCase(s1, s2); } - CPlugin::CPlugin(const FString &fileName, CAgent *agent, UString archiveTypeName): _agent(agent), m_FileName(fileName), @@ -61,7 +61,6 @@ } #define kDotsReplaceString "[[..]]" -#define kDotsReplaceStringU L"[[..]]" static void CopyStrLimited(char *dest, const AString &src, unsigned len) { @@ -72,7 +71,7 @@ dest[len] = 0; } -#define COPY_STR_LIMITED(dest, src) CopyStrLimited(dest, src, ARRAY_SIZE(dest)) +#define COPY_STR_LIMITED(dest, src) CopyStrLimited(dest, src, Z7_ARRAY_SIZE(dest)) void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UInt32 itemIndex) { @@ -84,7 +83,7 @@ throw 272340; AString oemString (UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP)); - if (oemString == "..") + if (oemString.IsEqualTo("..")) oemString = kDotsReplaceString; COPY_STR_LIMITED(panelItem.FindData.cFileName, oemString); @@ -156,7 +155,7 @@ g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), g_StartupInfo.GetMsgString(NMessageID::kReadingList) }; - g_StartupInfo.ShowMessage(0, NULL, msgItems, ARRAY_SIZE(msgItems), 0); + g_StartupInfo.ShowMessage(0, NULL, msgItems, Z7_ARRAY_SIZE(msgItems), 0); */ } @@ -177,7 +176,7 @@ delete [](*panelItems); throw; } - *itemsNumber = numItems; + *itemsNumber = (int)numItems; return(TRUE); } @@ -193,7 +192,7 @@ { CMyComPtr newFolder; UString s = dirName; - if (dirName == kDotsReplaceStringU) + if (dirName.IsEqualTo(kDotsReplaceString)) s = ".."; _folder->BindToFolder(s, &newFolder); if (!newFolder) @@ -209,12 +208,12 @@ int CPlugin::SetDirectory(const char *aszDir, int /* opMode */) { UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP); - if (path == WSTRING_PATH_SEPARATOR) + if (path.IsEqualTo(STRING_PATH_SEPARATOR)) { _folder.Release(); m_ArchiveHandler->BindToRootFolder(&_folder); } - else if (path == L"..") + else if (path.IsEqualTo("..")) { CMyComPtr newFolder; _folder->BindToParentFolder(&newFolder); @@ -291,7 +290,7 @@ { if (propID > NMessageID::k_Last_PropId_supported_by_plugin) return -1; - return NMessageID::kNoProperty + propID; + return NMessageID::kNoProperty + (int)propID; } /* @@ -324,7 +323,7 @@ // { kpidType, L"Type" } }; -static const int kNumPropertyIDInfos = ARRAY_SIZE(kPropertyIDInfos); +static const int kNumPropertyIDInfos = Z7_ARRAY_SIZE(kPropertyIDInfos); static int FindPropertyInfo(PROPID propID) { @@ -395,7 +394,7 @@ char s[32]; ConvertUInt64ToString(value, s); unsigned i = MyStringLen(s); - unsigned pos = ARRAY_SIZE(s); + unsigned pos = Z7_ARRAY_SIZE(s); s[--pos] = 0; while (i > 3) { @@ -509,7 +508,7 @@ m_PannelTitle = ' '; m_PannelTitle += _archiveTypeName; - m_PannelTitle += ':'; + m_PannelTitle.Add_Colon(); m_PannelTitle += name; m_PannelTitle.Add_Space(); if (!m_CurrentDir.IsEmpty()) @@ -597,7 +596,7 @@ case -2: propID = kpidType; break; case -1: propID = kpidError; break; default: - if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK) + if (getProps->GetArcPropInfo(level, (UInt32)i, &name, &propID, &vt) != S_OK) continue; } NCOM::CPropVariant prop; @@ -619,7 +618,7 @@ CMyComBSTR name; PROPID propID; VARTYPE vt; - if (getProps->GetArcPropInfo2(level, i, &name, &propID, &vt) != S_OK) + if (getProps->GetArcPropInfo2(level, (UInt32)i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (getProps->GetArcProp2(level, propID, &prop) != S_OK) @@ -636,7 +635,7 @@ //m_InfoLines[1].Separator = 0; info->InfoLines = m_InfoLines; - info->InfoLinesNumber = numItems; + info->InfoLinesNumber = (int)numItems; info->DescrFiles = NULL; @@ -654,19 +653,19 @@ AddColumn(kpidATime); AddColumn(kpidAttrib); - _PanelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; - _PanelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; - _PanelMode.ColumnTitles = NULL; - _PanelMode.FullScreen = TRUE; - _PanelMode.DetailedStatus = FALSE; - _PanelMode.AlignExtensions = FALSE; - _PanelMode.CaseConversion = FALSE; - _PanelMode.StatusColumnTypes = "N"; - _PanelMode.StatusColumnWidths = "0"; - _PanelMode.Reserved[0] = 0; - _PanelMode.Reserved[1] = 0; + _panelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; + _panelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; + _panelMode.ColumnTitles = NULL; + _panelMode.FullScreen = TRUE; + _panelMode.DetailedStatus = FALSE; + _panelMode.AlignExtensions = FALSE; + _panelMode.CaseConversion = FALSE; + _panelMode.StatusColumnTypes = "N"; + _panelMode.StatusColumnWidths = "0"; + _panelMode.Reserved[0] = 0; + _panelMode.Reserved[1] = 0; - info->PanelModesArray = &_PanelMode; + info->PanelModesArray = &_panelMode; info->PanelModesNumber = 1; */ @@ -686,14 +685,9 @@ VARTYPE Type; }; -static inline char GetHex_Upper(unsigned v) -{ - return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); -} - -static inline char GetHex_Lower(unsigned v) +static inline char GetHex_A_minus10(unsigned v, unsigned a10) { - return (char)((v < 10) ? ('0' + v) : ('a' + (v - 10))); + return (char)(v < 10 ? v + '0' : v + a10); } HRESULT CPlugin::ShowAttributesWindow() @@ -704,18 +698,18 @@ if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 && NFind::NAttributes::IsDir(pluginPanelItem.FindData.dwFileAttributes)) return S_FALSE; - int itemIndex = (int)pluginPanelItem.UserData; + const UInt32 itemIndex = (UInt32)pluginPanelItem.UserData; CObjectVector properties; UInt32 numProps; - RINOK(_folder->GetNumberOfProperties(&numProps)); + RINOK(_folder->GetNumberOfProperties(&numProps)) unsigned i; for (i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(_folder->GetPropertyInfo(i, &name, &propID, &vt)); + RINOK(_folder->GetPropertyInfo(i, &name, &propID, &vt)) CArchiveItemProperty prop; prop.Type = vt; prop.ID = propID; @@ -743,7 +737,7 @@ { const CArchiveItemProperty &property = properties[i]; - int startY = kStartY + values.Size(); + const int startY = kStartY + (int)values.Size(); { CInitDialogItem idi = @@ -755,7 +749,7 @@ } NCOM::CPropVariant prop; - RINOK(_folder->GetProperty(itemIndex, property.ID, &prop)); + RINOK(_folder->GetProperty(itemIndex, property.ID, &prop)) values.Add(PropToString(prop, property.ID)); { @@ -815,26 +809,19 @@ } else { - const bool needUpper = (dataSize <= 8) - && (property.ID == kpidCRC || property.ID == kpidChecksum); + const unsigned a = dataSize <= 8 + && (property.ID == kpidCRC || property.ID == kpidChecksum) + ? 'A' - 10 : 'a' - 10; for (UInt32 k = 0; k < dataSize; k++) { - unsigned b = ((const Byte *)data)[k]; - if (needUpper) - { - s += GetHex_Upper((b >> 4) & 0xF); - s += GetHex_Upper(b & 0xF); - } - else - { - s += GetHex_Lower((b >> 4) & 0xF); - s += GetHex_Lower(b & 0xF); - } + const unsigned b = ((const Byte *)data)[k]; + s += GetHex_A_minus10(b >> 4, a); + s += GetHex_A_minus10(b & 15, a); } } } - int startY = kStartY + values.Size(); + const int startY = kStartY + (int)values.Size(); { CInitDialogItem idi = @@ -856,17 +843,17 @@ } } - unsigned numLines = values.Size(); + const unsigned numLines = values.Size(); for (i = 0; i < numLines; i++) { CInitDialogItem &idi = initDialogItems[1 + i * 2 + 1]; idi.DataString = values[i]; } - unsigned numDialogItems = initDialogItems.Size(); + const unsigned numDialogItems = initDialogItems.Size(); CObjArray dialogItems(numDialogItems); - g_StartupInfo.InitDialogItems(&initDialogItems.Front(), dialogItems, numDialogItems); + g_StartupInfo.InitDialogItems(initDialogItems.ConstData(), dialogItems, numDialogItems); unsigned maxLen = 0; @@ -884,14 +871,14 @@ for (i = 0; i < numLines; i++) { FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1]; - unsigned len = (int)strlen(dialogItem.Data); + const unsigned len = (unsigned)strlen(dialogItem.Data); if (len > maxLen2) maxLen2 = len; - dialogItem.X1 = maxLen + kSpace; + dialogItem.X1 = (int)(maxLen + kSpace); } - size = numLines + 6; - xSize = maxLen + kSpace + maxLen2 + 5; + size = (int)numLines + 6; + xSize = (int)(maxLen + kSpace + maxLen2 + 5); FarDialogItem &firstDialogItem = dialogItems[0]; firstDialogItem.Y2 = size - 2; firstDialogItem.X2 = xSize - 4; @@ -900,7 +887,7 @@ return S_OK; } -int CPlugin::ProcessKey(int key, unsigned int controlState) +int CPlugin::ProcessKey(int key, unsigned controlState) { if (key == VK_F7 && controlState == 0) { @@ -926,7 +913,7 @@ PanelInfo panelInfo; g_StartupInfo.ControlGetActivePanelInfo(panelInfo); GetFilesReal(panelInfo.SelectedItems, - panelInfo.SelectedItemsNumber, FALSE, + (unsigned)panelInfo.SelectedItemsNumber, FALSE, UnicodeStringToMultiByte(fs2us(folderPath), CP_OEMCP), OPM_SILENT, true); g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL); g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/Plugin.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/Plugin.h 2015-06-09 07:59:22.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/Plugin.h 2023-09-06 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // 7zip/Far/Plugin.h -#ifndef __7ZIP_FAR_PLUGIN_H -#define __7ZIP_FAR_PLUGIN_H +#ifndef ZIP7_INC_7ZIP_FAR_PLUGIN_H +#define ZIP7_INC_7ZIP_FAR_PLUGIN_H #include "../../../Common/MyCom.h" @@ -40,7 +40,7 @@ AString PanelModeColumnTypes; AString PanelModeColumnWidths; - // PanelMode _PanelMode; + // PanelMode _panelMode; void AddColumn(PROPID aPropID); void EnterToDirectory(const UString &dirName); @@ -62,7 +62,7 @@ void FreeFindData(PluginPanelItem *panelItem,int ItemsNumber); int SetDirectory(const char *aszDir, int opMode); void GetOpenPluginInfo(struct OpenPluginInfo *info); - int DeleteFiles(PluginPanelItem *panelItems, int itemsNumber, int opMode); + int DeleteFiles(PluginPanelItem *panelItems, unsigned itemsNumber, int opMode); HRESULT ExtractFiles( bool decompressAllItems, @@ -74,19 +74,19 @@ const UString &destPath, bool passwordIsDefined, const UString &password); - NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *panelItem, int itemsNumber, + NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *panelItem, unsigned itemsNumber, int move, char *destPath, int opMode); NFar::NFileOperationReturnCode::EEnum GetFilesReal(struct PluginPanelItem *panelItems, - int itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox); + unsigned itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox); - NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *panelItems, int itemsNumber, + NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *panelItems, unsigned itemsNumber, int move, int opMode); HRESULT CreateFolder(); HRESULT ShowAttributesWindow(); - int ProcessKey(int key, unsigned int controlState); + int ProcessKey(int key, unsigned controlState); }; HRESULT CompressFiles(const CObjectVector &pluginPanelItems); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginDelete.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginDelete.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginDelete.cpp 2021-10-27 12:20:37.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginDelete.cpp 2023-03-19 09:00:00.000000000 +0000 @@ -13,7 +13,7 @@ using namespace NFar; -int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode) +int CPlugin::DeleteFiles(PluginPanelItem *panelItems, unsigned numItems, int opMode) { if (numItems == 0) return FALSE; @@ -63,7 +63,7 @@ // sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), numItems); // msgItems[1] = msg; } - if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, ARRAY_SIZE(msgItems), 2) != 0) + if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, Z7_ARRAY_SIZE(msgItems), 2) != 0) return (FALSE); } @@ -87,7 +87,7 @@ */ CObjArray indices(numItems); - int i; + unsigned i; for (i = 0; i < numItems; i++) indices[i] = (UInt32)panelItems[i].UserData; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginRead.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginRead.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginRead.cpp 2021-10-22 10:38:30.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginRead.cpp 2023-03-19 09:00:00.000000000 +0000 @@ -86,14 +86,14 @@ } NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems, - int itemsNumber, int move, char *destPath, int opMode) + unsigned itemsNumber, int move, char *destPath, int opMode) { return GetFilesReal(panelItems, itemsNumber, move, destPath, opMode, (opMode & OPM_SILENT) == 0); } NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems, - int itemsNumber, int move, const char *destPathLoc, int opMode, bool showBox) + unsigned itemsNumber, int move, const char *destPathLoc, int opMode, bool showBox) { if (move != 0) { @@ -112,7 +112,7 @@ extractionInfo.PathMode = NExtract::NPathMode::kCurPaths; extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite; - bool silent = (opMode & OPM_SILENT) != 0; + const bool silent = (opMode & OPM_SILENT) != 0; bool decompressAllItems = false; UString password = Password; bool passwordIsDefined = PasswordIsDefined; @@ -184,9 +184,9 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL } }; - const int kNumDialogItems = ARRAY_SIZE(initItems); - const int kOkButtonIndex = kNumDialogItems - 2; - const int kPasswordIndex = kNumDialogItems - 4; + const unsigned kNumDialogItems = Z7_ARRAY_SIZE(initItems); + const unsigned kOkButtonIndex = kNumDialogItems - 2; + const unsigned kPasswordIndex = kNumDialogItems - 4; FarDialogItem dialogItems[kNumDialogItems]; g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); @@ -275,10 +275,10 @@ GetRealIndexes(panelItems, itemsNumber, realIndices); */ CObjArray indices(itemsNumber); - for (int i = 0; i < itemsNumber; i++) + for (unsigned i = 0; i < itemsNumber; i++) indices[i] = (UInt32)panelItems[i].UserData; - HRESULT result = ExtractFiles(decompressAllItems, indices, itemsNumber, + const HRESULT result = ExtractFiles(decompressAllItems, indices, itemsNumber, !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode, destPathU, passwordIsDefined, password); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginWrite.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginWrite.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/PluginWrite.cpp 2021-10-27 12:20:57.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/PluginWrite.cpp 2024-01-24 19:00:00.000000000 +0000 @@ -49,7 +49,7 @@ */ NCOM::CPropVariant value = (UInt32)method; const wchar_t *name = L"x"; - RINOK(setProperties->SetProperties(&name, &value, 1)); + RINOK(setProperties->SetProperties(&name, &value, 1)) } return S_OK; } @@ -78,7 +78,7 @@ */ NFileOperationReturnCode::EEnum CPlugin::PutFiles( - struct PluginPanelItem *panelItems, int numItems, + struct PluginPanelItem *panelItems, unsigned numItems, int moveMode, int opMode) { if (moveMode != 0 @@ -106,7 +106,7 @@ unsigned methodIndex = 0; unsigned i; - for (i = ARRAY_SIZE(g_MethodMap); i != 0;) + for (i = Z7_ARRAY_SIZE(g_MethodMap); i != 0;) { i--; if (compressionInfo.Level >= g_MethodMap[i]) @@ -144,17 +144,17 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } }; - const int kNumDialogItems = ARRAY_SIZE(initItems); + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); const int kOkButtonIndex = kNumDialogItems - 2; FarDialogItem dialogItems[kNumDialogItems]; g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); - int askCode = g_StartupInfo.ShowDialog(76, kYSize, + const int askCode = g_StartupInfo.ShowDialog(76, kYSize, kHelpTopic, dialogItems, kNumDialogItems); if (askCode != kOkButtonIndex) return NFileOperationReturnCode::kInterruptedByUser; compressionInfo.Level = g_MethodMap[0]; - for (i = 0; i < ARRAY_SIZE(g_MethodMap); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_MethodMap); i++) if (dialogItems[kMethodRadioIndex + i].Selected) compressionInfo.Level = g_MethodMap[i]; @@ -168,7 +168,7 @@ compressionInfo.Save(); - CWorkDirTempFile tempFile;; + CWorkDirTempFile tempFile; if (tempFile.CreateTempFile(m_FileName) != S_OK) return NFileOperationReturnCode::kError; @@ -322,7 +322,7 @@ { case NPathType::kLocal: { - int posDiskDelimiter = path.Find(kDiskDelimiter); + const int posDiskDelimiter = path.Find(kDiskDelimiter); if (posDiskDelimiter >= 0) { curPos = posDiskDelimiter + 1; @@ -337,7 +337,7 @@ // the bug was fixed: curPos = path.Find((wchar_t)kDirDelimiter, 2); if (curPos < 0) - curPos = path.Len(); + curPos = (int)path.Len(); else curPos++; } @@ -352,7 +352,8 @@ FOR_VECTOR (i, PathParts) { if (i != 0) - result += kDirDelimiter; + // result += kDirDelimiter; + result.Add_PathSepar(); result += PathParts[i]; } return result; @@ -368,7 +369,7 @@ if (dotPos > slashPos + 1) arcName.DeleteFrom(dotPos); } - arcName += '.'; + arcName.Add_Dot(); arcName += arcInfo.GetMainExt(); } @@ -420,9 +421,9 @@ if (arcInfo.UpdateEnabled) { if (archiverIndex == -1) - archiverIndex = i; + archiverIndex = (int)i; if (MyStringCompareNoCase(arcInfo.Name, compressionInfo.ArcType) == 0) - archiverIndex = i; + archiverIndex = (int)i; } } } @@ -480,7 +481,7 @@ unsigned methodIndex = 0; unsigned i; - for (i = ARRAY_SIZE(g_MethodMap); i != 0;) + for (i = Z7_ARRAY_SIZE(g_MethodMap); i != 0;) { i--; if (compressionInfo.Level >= g_MethodMap[i]) @@ -522,7 +523,7 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } }; - const int kNumDialogItems = ARRAY_SIZE(initItems); + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); const int kOkButtonIndex = kNumDialogItems - 3; const int kSelectarchiverButtonIndex = kNumDialogItems - 2; @@ -537,7 +538,7 @@ MultiByteToUnicodeString2(arcName, archiveNameA, CP_OEMCP); compressionInfo.Level = g_MethodMap[0]; - for (i = 0; i < ARRAY_SIZE(g_MethodMap); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_MethodMap); i++) if (dialogItems[kMethodRadioIndex + i].Selected) compressionInfo.Level = g_MethodMap[i]; @@ -549,7 +550,7 @@ if (askCode == kSelectarchiverButtonIndex) { - CIntVector indices; + CUIntVector indices; AStringVector archiverNames; FOR_VECTOR (k, codecs->Formats) { @@ -561,7 +562,7 @@ } } - int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT, + const int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT, g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle), NULL, archiverNames, archiverIndex); if (index >= 0) @@ -574,7 +575,7 @@ if (arcName.Len() >= prevExtensionLen && MyStringCompareNoCase(arcName.RightPtr(prevExtensionLen), prevExtension) == 0) { - int pos = arcName.Len() - prevExtensionLen; + const unsigned pos = arcName.Len() - prevExtensionLen; if (pos > 2) { if (arcName[pos - 1] == '.') @@ -583,7 +584,7 @@ } } - archiverIndex = indices[index]; + archiverIndex = (int)indices[index]; const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex]; prevFormat = archiverIndex; @@ -612,8 +613,7 @@ return E_FAIL; CWorkDirTempFile tempFile; - RINOK(tempFile.CreateTempFile(fullArcName)); - + RINOK(tempFile.CreateTempFile(fullArcName)) CScreenRestorer screenRestorer; CProgressBox progressBox; CProgressBox *progressBoxPointer = NULL; @@ -640,15 +640,15 @@ archiveHandler = agentSpec; // CLSID realClassID; CMyComBSTR archiveType; - RINOK(agentSpec->Open(NULL, + RINOK(archiveHandler->Open(NULL, GetUnicodeString(fullArcName, CP_OEMCP), UString(), // &realClassID, &archiveType, - NULL)); + NULL)) if (MyStringCompareNoCase(archiverInfoFinal.Name, (const wchar_t *)archiveType) != 0) throw "Type of existing archive differs from specified type"; - HRESULT result = archiveHandler.QueryInterface( + const HRESULT result = archiveHandler.QueryInterface( IID_IOutFolderArchive, &outArchive); if (result != S_OK) { @@ -690,7 +690,7 @@ updateCallbackSpec->Init(/* archiveHandler, */ progressBoxPointer); - RINOK(SetOutProperties(outArchive, compressionInfo.Level)); + RINOK(SetOutProperties(outArchive, compressionInfo.Level)) // FStringVector requestedPaths; // FStringVector processedPaths; @@ -754,7 +754,7 @@ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } }; - const int kNumDialogItems = ARRAY_SIZE(initItems); + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); const int kOkButtonIndex = kNumDialogItems - 2; FarDialogItem dialogItems[kNumDialogItems]; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/ProgressBox.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/ProgressBox.cpp 2017-02-08 08:44:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.cpp 2023-03-06 17:00:00.000000000 +0000 @@ -67,9 +67,9 @@ static void GetTimeString(UInt64 timeValue, char *s) { - UInt64 hours = timeValue / 3600; + const UInt64 hours = timeValue / 3600; UInt32 seconds = (UInt32)(timeValue - hours * 3600); - UInt32 minutes = seconds / 60; + const UInt32 minutes = seconds / 60; seconds %= 60; if (hours > 99) { @@ -78,11 +78,11 @@ } else { - UInt32 hours32 = (UInt32)hours; - UINT_TO_STR_2(hours32); + const UInt32 hours32 = (UInt32)hours; + UINT_TO_STR_2(hours32) } - *s++ = ':'; UINT_TO_STR_2(minutes); - *s++ = ':'; UINT_TO_STR_2(seconds); + *s++ = ':'; UINT_TO_STR_2(minutes) + *s++ = ':'; UINT_TO_STR_2(seconds) *s = 0; } @@ -280,10 +280,10 @@ else */ { - int slashPos = FileName.ReverseFind_PathSepar(); + const int slashPos = FileName.ReverseFind_PathSepar(); if (slashPos >= 0) { - _name1U.SetFrom(FileName, slashPos + 1); + _name1U.SetFrom(FileName, (unsigned)(slashPos + 1)); _name2U = FileName.Ptr(slashPos + 1); } else @@ -295,7 +295,7 @@ { const char *strings[] = { _title, _timeStr, _files, _sizesStr, Command, _name1, _name2, _perc }; - NFar::g_StartupInfo.ShowMessage(FMSG_LEFTALIGN, NULL, strings, ARRAY_SIZE(strings), 0); + NFar::g_StartupInfo.ShowMessage(FMSG_LEFTALIGN, NULL, strings, Z7_ARRAY_SIZE(strings), 0); } _wasPrinted = true; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/ProgressBox.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/ProgressBox.h 2017-02-08 08:44:43.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/ProgressBox.h 2024-11-08 11:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // ProgressBox.h -#ifndef __PROGRESS_BOX_H -#define __PROGRESS_BOX_H +#ifndef ZIP7_INC_PROGRESS_BOX_H +#define ZIP7_INC_PROGRESS_BOX_H #include "../../../Common/MyString.h" #include "../../../Common/MyTypes.h" @@ -45,7 +45,12 @@ DWORD _prevElapsedSec; bool _wasPrinted; +public: + bool UseBytesForPercents; + DWORD StartTick; + unsigned MaxLen; +private: UString _tempU; UString _name1U; UString _name2U; @@ -64,15 +69,12 @@ void ReduceString(const UString &src, AString &dest); public: - DWORD StartTick; - bool UseBytesForPercents; - unsigned MaxLen; CProgressBox(UInt32 tickStep = 200): _tickStep(tickStep), _prevTick(0), - StartTick(0), UseBytesForPercents(true), + StartTick(0), MaxLen(60) {} diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/StdAfx.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/StdAfx.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/StdAfx.h 2014-04-25 10:55:08.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.cpp 2017-04-08 12:17:23.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.cpp 2024-10-22 09:00:00.000000000 +0000 @@ -2,7 +2,7 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -14,7 +14,7 @@ using namespace NWindows; using namespace NFar; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -27,7 +27,7 @@ } -STDMETHODIMP CUpdateCallback100Imp::ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */) +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */)) { MT_LOCK @@ -43,14 +43,14 @@ return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode) +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode)) { if (ShowSysErrorMessage(errorCode, path) == -1) return E_ABORT; return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles) +Z7_COM7F_IMF(CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)) { MT_LOCK @@ -63,12 +63,12 @@ } -STDMETHODIMP CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) { return S_OK; } -STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) { MT_LOCK return CheckBreak2(); @@ -76,7 +76,7 @@ -STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size) +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(UInt64 size)) { MT_LOCK @@ -88,7 +88,7 @@ return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 *completeValue)) { MT_LOCK @@ -101,7 +101,7 @@ return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name) +Z7_COM7F_IMF(CUpdateCallback100Imp::CompressOperation(const wchar_t *name)) { MT_LOCK @@ -111,10 +111,10 @@ _percent->FileName = name; _percent->Print(); } - return CheckBreak2();; + return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *name) +Z7_COM7F_IMF(CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)) { MT_LOCK @@ -124,10 +124,10 @@ _percent->FileName = name; _percent->Print(); } - return CheckBreak2();; + return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::OperationResult(Int32 /* opRes */) +Z7_COM7F_IMF(CUpdateCallback100Imp::OperationResult(Int32 /* opRes */)) { MT_LOCK @@ -138,7 +138,7 @@ return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +Z7_COM7F_IMF(CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)) { MT_LOCK @@ -147,14 +147,14 @@ return CheckBreak2(); } -HRESULT CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode) +Z7_COM7F_IMF(CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode)) { if (ShowSysErrorMessage(errorCode, path) == -1) return E_ABORT; return CheckBreak2(); } -STDMETHODIMP CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode) +Z7_COM7F_IMF(CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode)) { if (ShowSysErrorMessage(errorCode, path) == -1) return E_ABORT; @@ -163,7 +163,7 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s); -STDMETHODIMP CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)) { MT_LOCK @@ -179,7 +179,7 @@ } -STDMETHODIMP CUpdateCallback100Imp::ReportUpdateOperation(UInt32 op, const wchar_t *name, Int32 /* isDir */) +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportUpdateOperation(UInt32 op, const wchar_t *name, Int32 /* isDir */)) { const char *s; switch (op) @@ -206,26 +206,116 @@ _percent->Print(); } - return CheckBreak2();; + return CheckBreak2(); +} + + +HRESULT CUpdateCallback100Imp::MoveArc_UpdateStatus() +{ + MT_LOCK + + if (_percent) + { + AString s; + s.Add_UInt64(_arcMoving_percents); + // status.Add_Space(); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent->Command = s; + _percent->Print(); + } + + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t * /* destFinalPath */ , UInt64 size, Int32 /* updateMode */)) +{ + MT_LOCK + + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = updateMode; + // _name2 = fs2us(destFinalPath); + if (_percent) + _percent->FileName = srcTempPath; + return MoveArc_UpdateStatus(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) +{ + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + if (percents == _arcMoving_percents) + return CheckBreak2(); + _arcMoving_total = totalSize; + _arcMoving_current = currentSize; + _arcMoving_percents = percents; + // if (_arcMoving_percents > 100) return E_FAIL; + return MoveArc_UpdateStatus(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish()) +{ + // _arcMoving_percents = 0; + if (_percent) + { + _percent->Command.Empty(); + _percent->FileName.Empty(); + _percent->Print(); + } + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen()) +{ + // fixme: we can use Clear_Stop_Status() here + return CheckBreak2(); } extern HRESULT GetPassword(UString &password); -STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) { MT_LOCK *password = NULL; if (!PasswordIsDefined) { - RINOK(GetPassword(Password)); + RINOK(GetPassword(Password)) PasswordIsDefined = true; } return StringToBstr(Password, password); } -STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) { MT_LOCK diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.h --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.h 2017-04-08 12:30:56.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/UpdateCallbackFar.h 2024-10-22 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // UpdateCallbackFar.h -#ifndef __UPDATE_CALLBACK_FAR_H -#define __UPDATE_CALLBACK_FAR_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_FAR_H +#define ZIP7_INC_UPDATE_CALLBACK_FAR_H #include "../../../Common/MyCom.h" @@ -11,49 +11,47 @@ #include "ProgressBox.h" -class CUpdateCallback100Imp: - public IFolderArchiveUpdateCallback, - public IFolderArchiveUpdateCallback2, - public IFolderScanProgress, - public ICryptoGetTextPassword2, - public ICryptoGetTextPassword, - public IArchiveOpenCallback, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_7( + CUpdateCallback100Imp + , IFolderArchiveUpdateCallback + , IFolderArchiveUpdateCallback2 + , IFolderArchiveUpdateCallback_MoveArc + , IFolderScanProgress + , ICryptoGetTextPassword2 + , ICryptoGetTextPassword + , IArchiveOpenCallback +) + Z7_IFACE_COM7_IMP(IProgress) + // CMyComPtr _archiveHandler; CProgressBox *_percent; - UInt64 _total; + // UInt64 _total; -public: + HRESULT MoveArc_UpdateStatus(); + +private: + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + // Int32 _arcMoving_updateMode; +public: bool PasswordIsDefined; UString Password; - MY_UNKNOWN_IMP6( - IFolderArchiveUpdateCallback, - IFolderArchiveUpdateCallback2, - IFolderScanProgress, - ICryptoGetTextPassword2, - ICryptoGetTextPassword, - IArchiveOpenCallback - ) - - INTERFACE_IProgress(;) - INTERFACE_IFolderArchiveUpdateCallback(;) - INTERFACE_IFolderArchiveUpdateCallback2(;) - INTERFACE_IFolderScanProgress(;) - INTERFACE_IArchiveOpenCallback(;) - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); - - CUpdateCallback100Imp(): _total(0) {} + CUpdateCallback100Imp() + // : _total(0) + {} void Init(/* IInFolderArchive *archiveHandler, */ CProgressBox *progressBox) { // _archiveHandler = archiveHandler; _percent = progressBox; PasswordIsDefined = false; Password.Empty(); + _arcMoving_total = 0; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = 0; } }; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/Far/makefile 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/makefile --- 7zip-22.01+dfsg/CPP/7zip/UI/Far/makefile 2021-10-08 12:31:25.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Far/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,11 +1,11 @@ PROG = 7-ZipFar.dll DEF_FILE = Far.def CFLAGS = $(CFLAGS) \ - -DEXTERNAL_CODECS \ - -DNEW_FOLDER_INTERFACE + -DZ7_EXTERNAL_CODECS \ !IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH +# CFLAGS = $(CFLAGS) -DZ7_LONG_PATH +# -DZ7_NO_LARGE_PAGES !ENDIF CURRENT_OBJS = \ @@ -40,11 +40,13 @@ $O\FileIO.obj \ $O\FileLink.obj \ $O\FileName.obj \ + $O\FileSystem.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ $O\Registry.obj \ $O\ResourceString.obj \ $O\Synchronization.obj \ + $O\System.obj \ $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ @@ -88,7 +90,6 @@ $O\AgentOut.obj \ $O\AgentProxy.obj \ $O\ArchiveFolder.obj \ - $O\ArchiveFolderOpen.obj \ $O\ArchiveFolderOut.obj \ $O\UpdateCallbackAgent.obj \ @@ -98,9 +99,9 @@ C_OBJS = \ $O\Alloc.obj \ $O\CpuArch.obj \ - $O\Sort.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../Sort.mak" !include "../../7zip.mak" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/7zFM.exe.manifest 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/7zFM.exe.manifest --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/7zFM.exe.manifest 2018-04-25 11:15:28.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/7zFM.exe.manifest 2023-04-02 08:00:00.000000000 +0000 @@ -17,4 +17,7 @@ true + + +true diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.cpp 2021-05-18 06:45:36.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -14,10 +14,12 @@ #include "HelpUtils.h" #include "LangUtils.h" +#ifdef Z7_LANG static const UInt32 kLangIDs[] = { IDT_ABOUT_INFO }; +#endif #define kHomePageURL TEXT("https://www.7-zip.org/") #define kHelpTopic "start.htm" @@ -29,7 +31,7 @@ bool CAboutDialog::OnInit() { - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (g_CodecsObj) { UString s; @@ -39,11 +41,13 @@ } #endif - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_ABOUT); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif SetItemText(IDT_ABOUT_VERSION, UString("7-Zip " MY_VERSION_CPU)); SetItemText(IDT_ABOUT_DATE, LLL(MY_DATE)); - LangSetWindowText(*this, IDD_ABOUT); NormalizePosition(); return CModalDialog::OnInit(); } @@ -53,7 +57,7 @@ ShowHelpWindow(kHelpTopic); } -bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool CAboutDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { LPCTSTR url; switch (buttonID) diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.h --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.h 2013-01-17 10:21:21.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AboutDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // AboutDialog.h -#ifndef __ABOUT_DIALOG_H -#define __ABOUT_DIALOG_H +#ifndef ZIP7_INC_ABOUT_DIALOG_H +#define ZIP7_INC_ABOUT_DIALOG_H #include "../../../Windows/Control/Dialog.h" @@ -10,10 +10,10 @@ class CAboutDialog: public NWindows::NControl::CModalDialog { public: - virtual bool OnInit(); - virtual void OnHelp(); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_ABOUT, wndParent); } + virtual bool OnInit() Z7_override; + virtual void OnHelp() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + INT_PTR Create(HWND wndParent = NULL) { return CModalDialog::Create(IDD_ABOUT, wndParent); } }; #endif diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp 2021-02-11 08:53:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp 2024-07-09 09:00:00.000000000 +0000 @@ -2,10 +2,32 @@ #include "StdAfx.h" +#ifdef __MINGW32_VERSION +// #if !defined(_MSC_VER) && (__GNUC__) && (__GNUC__ < 10) +// for old mingw +#include +#else +#ifndef Z7_OLD_WIN_SDK + #if !defined(_M_IA64) + #include + #endif +#else +typedef LONG NTSTATUS; +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; +#endif +#endif + #include "../../../Common/ComTry.h" #include "../../../Common/StringConvert.h" #include "../../../Common/Wildcard.h" +#include "../../../Windows/DLL.h" #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileIO.h" @@ -54,7 +76,7 @@ { if (IsNetworkShareRootPath(path)) return 0; - unsigned prefixSize = GetRootPrefixSize(path); + const unsigned prefixSize = GetRootPrefixSize(path); if (prefixSize == 0 || prefixSize >= path.Len()) return 0; FString parentPath = path; @@ -70,7 +92,7 @@ } if ((unsigned)pos + 1 < prefixSize) return 0; - return pos + 1; + return (unsigned)pos + 1; } HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFolder */) @@ -115,7 +137,7 @@ return S_OK; } -STDMETHODIMP CAltStreamsFolder::LoadItems() +Z7_COM7F_IMF(CAltStreamsFolder::LoadItems()) { Int32 dummy; WasChanged(&dummy); @@ -152,7 +174,7 @@ return S_OK; } -STDMETHODIMP CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems)) { *numItems = Streams.Size(); return S_OK; @@ -160,16 +182,16 @@ #ifdef USE_UNICODE_FSTRING -STDMETHODIMP CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len) +Z7_COM7F_IMF(CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len)) { - *name = 0; + *name = NULL; *len = 0; return S_OK; } -STDMETHODIMP CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len) +Z7_COM7F_IMF(CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) { - *name = 0; + *name = NULL; *len = 0; { const CAltStream &ss = Streams[index]; @@ -179,7 +201,7 @@ return S_OK; } -STDMETHODIMP_(UInt64) CAltStreamsFolder::GetItemSize(UInt32 index) +Z7_COM7F_IMF2(UInt64, CAltStreamsFolder::GetItemSize(UInt32 index)) { return Streams[index].Size; } @@ -187,7 +209,7 @@ #endif -STDMETHODIMP CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; { @@ -223,11 +245,11 @@ static inline const wchar_t *GetExtensionPtr(const UString &name) { - int dotPos = name.ReverseFind_Dot(); - return name.Ptr((dotPos < 0) ? name.Len() : dotPos); + const int dotPos = name.ReverseFind_Dot(); + return name.Ptr(dotPos < 0 ? name.Len() : (unsigned)dotPos); } -STDMETHODIMP_(Int32) CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */) +Z7_COM7F_IMF2(Int32, CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */)) { const CAltStream &ss1 = Streams[index1]; const CAltStream &ss2 = Streams[index2]; @@ -262,23 +284,23 @@ return 0; } -STDMETHODIMP CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder)) { - *resultFolder = 0; + *resultFolder = NULL; return E_INVALIDARG; } -STDMETHODIMP CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder)) { - *resultFolder = 0; + *resultFolder = NULL; return E_INVALIDARG; } // static CFSTR const kSuperPrefix = FTEXT("\\\\?\\"); -STDMETHODIMP CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder)) { - *resultFolder = 0; + *resultFolder = NULL; /* if (_parentFolder) { @@ -338,15 +360,9 @@ return S_OK; } -STDMETHODIMP CAltStreamsFolder::GetNumberOfProperties(UInt32 *numProperties) -{ - *numProperties = ARRAY_SIZE(kProps); - return S_OK; -} - -STDMETHODIMP CAltStreamsFolder::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps) +IMP_IFolderFolder_Props(CAltStreamsFolder) -STDMETHODIMP CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; @@ -360,7 +376,7 @@ COM_TRY_END } -STDMETHODIMP CAltStreamsFolder::WasChanged(Int32 *wasChanged) +Z7_COM7F_IMF(CAltStreamsFolder::WasChanged(Int32 *wasChanged)) { bool wasChangedMain = false; for (;;) @@ -371,8 +387,8 @@ return S_OK; } - DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); - bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); + const DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); + const bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); if (wasChangedLoc) { _findChangeNotification.FindNext(); @@ -385,7 +401,7 @@ return S_OK; } -STDMETHODIMP CAltStreamsFolder::Clone(IFolderFolder **resultFolder) +Z7_COM7F_IMF(CAltStreamsFolder::Clone(IFolderFolder **resultFolder)) { CAltStreamsFolder *folderSpec = new CAltStreamsFolder; CMyComPtr folderNew = folderSpec; @@ -436,39 +452,31 @@ } */ -STDMETHODIMP CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */) +Z7_COM7F_IMF(CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)) { return E_NOTIMPL; } -STDMETHODIMP CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */) +Z7_COM7F_IMF(CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)) { FString absPath; GetAbsPath(name, absPath); NIO::COutFile outFile; - if (!outFile.Create(absPath, false)) - return ::GetLastError(); + if (!outFile.Create_NEW(absPath)) + return GetLastError_noZero_HRESULT(); return S_OK; } -static DWORD Return_LastError_or_FAIL() -{ - DWORD errorCode = GetLastError(); - if (errorCode == 0) - errorCode = (DWORD)E_FAIL; - return errorCode; -} - static UString GetLastErrorMessage() { - return NError::MyFormatMessage(Return_LastError_or_FAIL()); + return NError::MyFormatMessage(GetLastError_noZero_HRESULT()); } static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR outPath, IFolderArchiveUpdateCallback *callback) { if (NFind::DoesFileOrDirExist(outPath)) { - RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath))); + RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath))) CFileInfo fi; if (fi.Find(inPath)) { @@ -480,8 +488,8 @@ { if (callback) - RINOK(callback->CompressOperation(fs2us(inPath))); - RINOK(state.MyCopyFile(inPath, outPath)); + RINOK(callback->CompressOperation(fs2us(inPath))) + RINOK(state.MyCopyFile(inPath, outPath)) if (state.ErrorFileIndex >= 0) { if (state.ErrorMessage.IsEmpty()) @@ -492,31 +500,136 @@ else errorName = outPath; if (callback) - RINOK(SendMessageError(callback, state.ErrorMessage, errorName)); + RINOK(SendMessageError(callback, state.ErrorMessage, errorName)) } if (callback) - RINOK(callback->OperationResult(0)); + RINOK(callback->OperationResult(0)) } return S_OK; } -STDMETHODIMP CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress) +EXTERN_C_BEGIN + +typedef enum +{ + Z7_WIN_FileRenameInformation = 10 +} +Z7_WIN_FILE_INFORMATION_CLASS; + + +typedef struct { - CMyComPtr callback; - if (progress) + // #if (_WIN32_WINNT >= _WIN32_WINNT_WIN10_RS1) + union { - RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback)); - } + BOOLEAN ReplaceIfExists; // FileRenameInformation + ULONG Flags; // FileRenameInformationEx + } DUMMYUNIONNAME; + // #else + // BOOLEAN ReplaceIfExists; + // #endif + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} Z7_WIN_FILE_RENAME_INFORMATION; + +#if (_WIN32_WINNT >= 0x0500) && !defined(_M_IA64) +#define Z7_WIN_NTSTATUS NTSTATUS +#define Z7_WIN_IO_STATUS_BLOCK IO_STATUS_BLOCK +#else +typedef LONG Z7_WIN_NTSTATUS; +typedef struct +{ + union + { + Z7_WIN_NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + ULONG_PTR Information; +} Z7_WIN_IO_STATUS_BLOCK; +#endif - FString destPath = _pathPrefix + us2fs(newName); +typedef Z7_WIN_NTSTATUS (WINAPI *Func_NtSetInformationFile)( + HANDLE FileHandle, + Z7_WIN_IO_STATUS_BLOCK *IoStatusBlock, + PVOID FileInformation, + ULONG Length, + Z7_WIN_FILE_INFORMATION_CLASS FileInformationClass); +// NTAPI +typedef ULONG (WINAPI *Func_RtlNtStatusToDosError)(Z7_WIN_NTSTATUS Status); + +#define MY_STATUS_SUCCESS 0 + +EXTERN_C_END + +// static Func_NtSetInformationFile f_NtSetInformationFile; +// static bool g_NtSetInformationFile_WasRequested = false; +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +Z7_COM7F_IMF(CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)) +{ const CAltStream &ss = Streams[index]; + const FString srcPath = _pathPrefix + us2fs(ss.Name); + + const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + // if (!g_NtSetInformationFile_WasRequested) { + // g_NtSetInformationFile_WasRequested = true; + const + Func_NtSetInformationFile + f_NtSetInformationFile = Z7_GET_PROC_ADDRESS( + Func_NtSetInformationFile, ntdll, + "NtSetInformationFile"); + if (f_NtSetInformationFile) + { + NIO::CInFile inFile; + if (inFile.Open_for_FileRenameInformation(srcPath)) + { + UString destPath (':'); + destPath += newName; + const ULONG len = (ULONG)sizeof(wchar_t) * destPath.Len(); + CByteBuffer buffer(sizeof(Z7_WIN_FILE_RENAME_INFORMATION) + len); + // buffer is 4 bytes larger than required. + Z7_WIN_FILE_RENAME_INFORMATION *fri = (Z7_WIN_FILE_RENAME_INFORMATION *)(void *)(Byte *)buffer; + memset(fri, 0, sizeof(Z7_WIN_FILE_RENAME_INFORMATION)); + /* DOCS: If ReplaceIfExists is set to TRUE, the rename operation will succeed only + if a stream with the same name does not exist or is a zero-length data stream. */ + fri->ReplaceIfExists = FALSE; + fri->RootDirectory = NULL; + fri->FileNameLength = len; + memcpy(fri->FileName, destPath.Ptr(), len); + Z7_WIN_IO_STATUS_BLOCK iosb; + const Z7_WIN_NTSTATUS status = f_NtSetInformationFile (inFile.GetHandle(), + &iosb, fri, (ULONG)buffer.Size(), Z7_WIN_FileRenameInformation); + if (status != MY_STATUS_SUCCESS) + { + const + Func_RtlNtStatusToDosError + f_RtlNtStatusToDosError = Z7_GET_PROC_ADDRESS( + Func_RtlNtStatusToDosError, ntdll, + "RtlNtStatusToDosError"); + if (f_RtlNtStatusToDosError) + { + const ULONG res = f_RtlNtStatusToDosError(status); + if (res != ERROR_MR_MID_NOT_FOUND) + return HRESULT_FROM_WIN32(res); + } + } + return status; + } + } + + CMyComPtr callback; + if (progress) + { + RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback)) + } if (callback) { - RINOK(callback->SetNumFiles(1)); - RINOK(callback->SetTotal(ss.Size)); + RINOK(callback->SetNumFiles(1)) + RINOK(callback->SetTotal(ss.Size)) } NFsFolder::CCopyStateIO state; @@ -524,67 +637,60 @@ state.TotalSize = 0; state.DeleteSrcFile = true; - return UpdateFile(state, _pathPrefix + us2fs(ss.Name), destPath, callback); + const FString destPath = _pathPrefix + us2fs(newName); + return UpdateFile(state, srcPath, destPath, callback); } -STDMETHODIMP CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress) +Z7_COM7F_IMF(CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)) { - RINOK(progress->SetTotal(numItems)); + RINOK(progress->SetTotal(numItems)) for (UInt32 i = 0; i < numItems; i++) { const CAltStream &ss = Streams[indices[i]]; const FString fullPath = _pathPrefix + us2fs(ss.Name); - bool result = DeleteFileAlways(fullPath); + const bool result = DeleteFileAlways(fullPath); if (!result) - return Return_LastError_or_FAIL(); - UInt64 completed = i; - RINOK(progress->SetCompleted(&completed)); + return GetLastError_noZero_HRESULT(); + const UInt64 completed = i; + RINOK(progress->SetCompleted(&completed)) } return S_OK; } -STDMETHODIMP CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */, - const PROPVARIANT * /* value */, IProgress * /* progress */) +Z7_COM7F_IMF(CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */)) { return E_NOTIMPL; } -STDMETHODIMP CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex) +Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) { const CAltStream &ss = Streams[index]; - *iconIndex = 0; - int iconIndexTemp; - if (GetRealIconIndex(_pathPrefix + us2fs(ss.Name), - 0 // fi.Attrib - , iconIndexTemp) != 0) - { - *iconIndex = iconIndexTemp; - return S_OK; - } - return Return_LastError_or_FAIL(); + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + _pathPrefix + us2fs(ss.Name), + FILE_ATTRIBUTE_ARCHIVE, + iconIndex); } /* -class CGetProp: - public IGetProp, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) public: // const CArc *Arc; // UInt32 IndexInArc; UString Name; // relative path UInt64 Size; - - MY_UNKNOWN_IMP1(IGetProp) - INTERFACE_IGetProp(;) }; -STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) { if (propID == kpidName) { COM_TRY_BEGIN - NCOM::CPropVariant prop = Name; + NCOM::CPropVariant prop; + prop = Name; prop.Detach(value); return S_OK; COM_TRY_END @@ -612,7 +718,7 @@ FString destPath = destPathSpec; if (CompareFileNames(destPath, srcPath) == 0) { - RINOK(SendMessageError(callback, "Cannot copy file onto itself", destPath)); + RINOK(SendMessageError(callback, "Cannot copy file onto itself", destPath)) return E_ABORT; } @@ -624,13 +730,13 @@ &srcFileInfo.MTime, &srcAltStream.Size, fs2us(destPath), &destPathResult, - &writeAskResult)); + &writeAskResult)) if (IntToBool(writeAskResult)) { - RINOK(callback->SetCurrentFilePath(fs2us(srcPath))); + RINOK(callback->SetCurrentFilePath(fs2us(srcPath))) FString destPathNew (us2fs((LPCOLESTR)destPathResult)); - RINOK(state.MyCopyFile(srcPath, destPathNew)); + RINOK(state.MyCopyFile(srcPath, destPathNew)) if (state.ErrorFileIndex >= 0) { if (state.ErrorMessage.IsEmpty()) @@ -640,7 +746,7 @@ errorName = srcPath; else errorName = destPathNew; - RINOK(SendMessageError(callback, state.ErrorMessage, errorName)); + RINOK(SendMessageError(callback, state.ErrorMessage, errorName)) return E_ABORT; } state.StartPos += state.CurrentSize; @@ -650,22 +756,23 @@ if (state.TotalSize >= srcAltStream.Size) { state.TotalSize -= srcAltStream.Size; - RINOK(state.Progress->SetTotal(state.TotalSize)); + RINOK(state.Progress->SetTotal(state.TotalSize)) } } return S_OK; } -STDMETHODIMP CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, +Z7_COM7F_IMF(CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, - const wchar_t *path, IFolderOperationsExtractCallback *callback) + const wchar_t *path, IFolderOperationsExtractCallback *callback)) { if (numItems == 0) return S_OK; /* - CMyComPtr ExtractToStreamCallback; - RINOK(callback->QueryInterface(IID_IFolderExtractToStreamCallback, (void **)&ExtractToStreamCallback)); + Z7_DECL_CMyComPtr_QI_FROM( + IFolderExtractToStreamCallback, + ExtractToStreamCallback, callback) if (ExtractToStreamCallback) { Int32 useStreams = 0; @@ -683,8 +790,8 @@ { totalSize += Streams[indices[i]].Size; } - RINOK(callback->SetTotal(totalSize)); - RINOK(callback->SetNumFiles(numItems)); + RINOK(callback->SetTotal(totalSize)) + RINOK(callback->SetNumFiles(numItems)) } /* @@ -716,8 +823,8 @@ if (destPath.IsEmpty() /* && !ExtractToStreamCallback */) return E_INVALIDARG; - bool isAltDest = NName::IsAltPathPrefix(destPath); - bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); + const bool isAltDest = NName::IsAltPathPrefix(destPath); + const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); if (isDirectPath) { @@ -727,7 +834,7 @@ CFileInfo fi; if (!fi.Find(_pathBaseFile)) - return GetLastError(); + return GetLastError_noZero_HRESULT(); NFsFolder::CCopyStateIO state; state.Progress = callback; @@ -736,21 +843,21 @@ for (UInt32 i = 0; i < numItems; i++) { - UInt32 index = indices[i]; + const UInt32 index = indices[i]; const CAltStream &ss = Streams[index]; FString destPath2 = destPath; if (!isDirectPath) destPath2 += us2fs(Get_Correct_FsFile_Name(ss.Name)); FString srcPath; GetFullPath(ss, srcPath); - RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback)); + RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback)) } return S_OK; } -STDMETHODIMP CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, - const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) +Z7_COM7F_IMF(CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, + const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)) { /* if (numItems == 0) @@ -831,7 +938,7 @@ return E_NOTIMPL; } -STDMETHODIMP CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */) +Z7_COM7F_IMF(CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)) { return E_NOTIMPL; } diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.h --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.h 2014-09-01 09:45:46.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AltStreamsFolder.h 2023-04-01 09:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // AltStreamsFolder.h -#ifndef __ALT_STREAMS_FOLDER_H -#define __ALT_STREAMS_FOLDER_H +#ifndef ZIP7_INC_ALT_STREAMS_FOLDER_H +#define ZIP7_INC_ALT_STREAMS_FOLDER_H #include "../../../Common/MyCom.h" @@ -24,12 +24,12 @@ }; -class CAltStreamsFolder: +class CAltStreamsFolder Z7_final: public IFolderFolder, public IFolderCompare, - #ifdef USE_UNICODE_FSTRING + #ifdef USE_UNICODE_FSTRING public IFolderGetItemName, - #endif + #endif public IFolderWasChanged, public IFolderOperations, // public IFolderOperationsDeleteToRecycleBin, @@ -37,35 +37,29 @@ public IFolderGetSystemIconIndex, public CMyUnknownImp { -public: - MY_QUERYINTERFACE_BEGIN2(IFolderFolder) - MY_QUERYINTERFACE_ENTRY(IFolderCompare) + Z7_COM_QI_BEGIN2(IFolderFolder) + Z7_COM_QI_ENTRY(IFolderCompare) #ifdef USE_UNICODE_FSTRING - MY_QUERYINTERFACE_ENTRY(IFolderGetItemName) + Z7_COM_QI_ENTRY(IFolderGetItemName) #endif - MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) - // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin) - MY_QUERYINTERFACE_ENTRY(IFolderOperations) - MY_QUERYINTERFACE_ENTRY(IFolderClone) - MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - INTERFACE_FolderFolder(;) - INTERFACE_FolderOperations(;) - - STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); + Z7_COM_QI_ENTRY(IFolderWasChanged) + // Z7_COM_QI_ENTRY(IFolderOperationsDeleteToRecycleBin) + Z7_COM_QI_ENTRY(IFolderOperations) + Z7_COM_QI_ENTRY(IFolderClone) + Z7_COM_QI_ENTRY(IFolderGetSystemIconIndex) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IFolderFolder) + Z7_IFACE_COM7_IMP(IFolderCompare) + #ifdef USE_UNICODE_FSTRING + Z7_IFACE_COM7_IMP(IFolderGetItemName) + #endif + Z7_IFACE_COM7_IMP(IFolderWasChanged) + Z7_IFACE_COM7_IMP(IFolderOperations) + Z7_IFACE_COM7_IMP(IFolderClone) + Z7_IFACE_COM7_IMP(IFolderGetSystemIconIndex) - #ifdef USE_UNICODE_FSTRING - INTERFACE_IFolderGetItemName(;) - #endif - STDMETHOD(WasChanged)(Int32 *wasChanged); - STDMETHOD(Clone)(IFolderFolder **resultFolder); - - STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex); - -private: FString _pathBaseFile; // folder FString _pathPrefix; // folder: @@ -81,8 +75,6 @@ // path must be with ':' at tail HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */); - CAltStreamsFolder() {} - void GetFullPath(const CAltStream &item, FString &path) const { path = _pathPrefix; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/App.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/App.cpp 2021-01-24 14:20:48.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.cpp 2024-10-04 16:00:00.000000000 +0000 @@ -35,7 +35,6 @@ using namespace NFind; using namespace NName; -extern DWORD g_ComCtl32Version; extern HINSTANCE g_hInstance; #define kTempDirPrefix FTEXT("7zE") @@ -49,7 +48,7 @@ void CPanelCallbackImp::SetFocusToPath(unsigned index) { - int newPanelIndex = index; + unsigned newPanelIndex = index; if (g_App.NumPanels == 1) newPanelIndex = g_App.LastFocusedPanel; _app->RefreshTitle(); @@ -66,7 +65,7 @@ void CPanelCallbackImp::DragEnd() { _app->DragEnd(); } void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitlePanel(_index, always); } -void CApp::ReloadLang() +void CApp::ReloadLangItems() { LangString(IDS_N_SELECTED_ITEMS, LangString_N_SELECTED_ITEMS); } @@ -101,11 +100,11 @@ panel._showRealFileIcons = st.ShowRealFileIcons; panel._exStyle = extendedStyle; - DWORD style = (DWORD)panel._listView.GetStyle(); + LONG_PTR style = panel._listView.GetStyle(); if (st.AlternativeSelection) style |= LVS_SINGLESEL; else - style &= ~LVS_SINGLESEL; + style &= ~(LONG_PTR)(DWORD)LVS_SINGLESEL; panel._listView.SetStyle(style); panel.SetExtendedStyle(); } @@ -115,7 +114,7 @@ #define ILC_COLOR32 0x0020 #endif -HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, +HRESULT CApp::CreateOnePanel(unsigned panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, COpenResult &openRes) { @@ -133,7 +132,7 @@ else path = mainPath; - int id = 1000 + 100 * panelIndex; + const unsigned id = 1000 + 100 * panelIndex; // check it return Panels[panelIndex].Create(_window, _window, id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, @@ -214,9 +213,9 @@ static void SetButtonText(int commandID, UString &s) { - if (SetButtonText(commandID, g_StandardButtons, ARRAY_SIZE(g_StandardButtons), s)) + if (SetButtonText(commandID, g_StandardButtons, Z7_ARRAY_SIZE(g_StandardButtons), s)) return; - SetButtonText(commandID, g_ArchiveButtons, ARRAY_SIZE(g_ArchiveButtons), s); + SetButtonText(commandID, g_ArchiveButtons, Z7_ARRAY_SIZE(g_ArchiveButtons), s); } static void AddButton( @@ -241,7 +240,7 @@ large ? MAKEINTRESOURCE(butInfo.BitmapResID): MAKEINTRESOURCE(butInfo.Bitmap2ResID)); - if (b != 0) + if (b) { imageList.AddMasked(b, RGB(255, 0, 255)); ::DeleteObject(b); @@ -264,10 +263,10 @@ CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons); unsigned i; if (ShowArchiveToolbar) - for (i = 0; i < ARRAY_SIZE(g_ArchiveButtons); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_ArchiveButtons); i++) AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons); if (ShowStandardToolbar) - for (i = 0; i < ARRAY_SIZE(g_StandardButtons); i++) + for (i = 0; i < Z7_ARRAY_SIZE(g_StandardButtons); i++) AddButton(_buttonsImageList, _toolBar, g_StandardButtons[i], ShowButtonsLables, LargeButtons); _toolBar.AutoSize(); @@ -290,7 +289,7 @@ _commandBar.Create(g_hInstance, hwnd, 1); #endif - MyLoadMenu(); + MyLoadMenu(false); // needResetMenu #ifdef UNDER_CE _commandBar.AutoSize(); @@ -317,7 +316,7 @@ for (i = 0; i < kNumPanelsMax; i++) { CPanel &panel = Panels[i]; - panel._ListViewMode = listMode.Panels[i]; + panel._listViewMode = listMode.Panels[i]; panel._xSize = xSizes[i]; panel._flatModeForArc = ReadFlatView(i); } @@ -342,7 +341,7 @@ RINOK(CreateOnePanel(panelIndex, path, arcFormat, isMainPanel && needOpenArc, - *(isMainPanel ? &openRes : &openRes2))); + *(isMainPanel ? &openRes : &openRes2))) if (isMainPanel) { @@ -366,7 +365,7 @@ COpenResult openRes; RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(), false, // needOpenArc - openRes)); + openRes)) Panels[1 - LastFocusedPanel].Enable(true); Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); } @@ -403,11 +402,17 @@ // Save_ShowDeleted(ShowDeletedFiles); } -void CApp::Release() +void CApp::ReleaseApp() { + // 24.09: ReleasePanel() will stop panel timer processing. + // but we want to stop timer processing for all panels + // before ReleasePanel() calling. + unsigned i; + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].Disable_Processing_Timer_Notify_StatusBar(); // It's for unloading COM dll's: don't change it. - for (unsigned i = 0; i < kNumPanelsMax; i++) - Panels[i].Release(); + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].ReleasePanel(); } // reduces path to part that exists on disk (or root prefix of path) @@ -479,7 +484,7 @@ s.Add_LF(); } -static void AddPropValueToSum(IFolderFolder *folder, int index, PROPID propID, UInt64 &sum) +static void AddPropValueToSum(IFolderFolder *folder, UInt32 index, PROPID propID, UInt64 &sum) { if (sum == (UInt64)(Int64)-1) return; @@ -501,7 +506,7 @@ unsigned i; for (i = 0; i < indices.Size(); i++) { - int index = indices[i]; + const UInt32 index = indices[i]; if (IsItem_Folder(index)) { AddPropValueToSum(_folder, index, kpidSize, foldersSize); @@ -528,7 +533,7 @@ { info.Add_LF(); info += " "; - int index = indices[i]; + const UInt32 index = indices[i]; info += GetItemRelPath(index); if (IsItem_Folder(index)) info.Add_PathSepar(); @@ -557,9 +562,9 @@ } */ -void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) +void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) { - unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + const unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &srcPanel = Panels[srcPanelIndex]; CPanel &destPanel = Panels[destPanelIndex]; @@ -584,10 +589,10 @@ { if (copyToSame) { - int focusedItem = srcPanel._listView.GetFocusedItem(); + const int focusedItem = srcPanel._listView.GetFocusedItem(); if (focusedItem < 0) return; - int realIndex = srcPanel.GetRealItemIndex(focusedItem); + const unsigned realIndex = srcPanel.GetRealItemIndex(focusedItem); if (realIndex == kParentIndex) return; indices.Add(realIndex); @@ -595,7 +600,7 @@ } else { - srcPanel.GetOperatedIndicesSmart(indices); + srcPanel.Get_ItemIndices_OperSmart(indices); if (indices.Size() == 0) return; destPath = destPanel.GetFsPath(); @@ -607,7 +612,7 @@ UStringVector copyFolders; ReadCopyHistory(copyFolders); - bool useFullItemPaths = srcPanel.Is_IO_FS_Folder(); // maybe we need flat also here ?? + const bool useFullItemPaths = srcPanel.Is_IO_FS_Folder(); // maybe we need flat also here ?? { CCopyDialog copyDialog; @@ -645,7 +650,7 @@ destPath += correctName; #if defined(_WIN32) && !defined(UNDER_CE) - if (destPath.Len() > 0 && destPath[0] == '\\') + if (destPath.Len() != 0 && destPath[0] == '\\') if (destPath.Len() == 1 || destPath[1] != '\\') { srcPanel.MessageBox_Error_UnsupportOperation(); @@ -722,7 +727,7 @@ UString prefix = destPath.Left(pos + 1); if (!CreateComplexDir(us2fs(prefix))) { - DWORD lastError = ::GetLastError(); + const HRESULT lastError = GetLastError_noZero_HRESULT(); srcPanel.MessageBox_Error_2Lines_Message_HRESULT(prefix, lastError); return; } @@ -734,7 +739,7 @@ NName::NormalizeDirPathPrefix(destPath); if (!CreateComplexDir(us2fs(destPath))) { - DWORD lastError = ::GetLastError(); + const HRESULT lastError = GetLastError_noZero_HRESULT(); srcPanel.MessageBox_Error_2Lines_Message_HRESULT(destPath, lastError); return; } @@ -783,6 +788,7 @@ if (useSrcPanel) { CCopyToOptions options; + // options.src_Is_IO_FS_Folder = useFullItemPaths; options.folder = useTemp ? fs2us(tempDirPrefix) : destPath; options.moveMode = move; options.includeAltStreams = true; @@ -815,7 +821,7 @@ filePaths.AddInReserved(s); } - result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0); + result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, NULL); } if (result != S_OK) @@ -849,7 +855,7 @@ srcPanel.SetFocusToList(); } -void CApp::OnSetSameFolder(int srcPanelIndex) +void CApp::OnSetSameFolder(unsigned srcPanelIndex) { if (NumPanels <= 1) return; @@ -858,17 +864,17 @@ destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix); } -void CApp::OnSetSubFolder(int srcPanelIndex) +void CApp::OnSetSubFolder(unsigned srcPanelIndex) { if (NumPanels <= 1) return; const CPanel &srcPanel = Panels[srcPanelIndex]; CPanel &destPanel = Panels[1 - srcPanelIndex]; - int focusedItem = srcPanel._listView.GetFocusedItem(); + const int focusedItem = srcPanel._listView.GetFocusedItem(); if (focusedItem < 0) return; - int realIndex = srcPanel.GetRealItemIndex(focusedItem); + const unsigned realIndex = srcPanel.GetRealItemIndex(focusedItem); if (!srcPanel.IsItem_Folder(realIndex)) return; @@ -933,7 +939,7 @@ if (pnmh->code == TTN_GETDISPINFO) { LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh; - info->hinst = 0; + info->hinst = NULL; g_ToolTipBuffer.Empty(); SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer); @@ -944,7 +950,7 @@ if (pnmh->code == TTN_GETDISPINFOW) { LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh; - info->hinst = 0; + info->hinst = NULL; g_ToolTipBuffer.Empty(); SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); info->lpszText = g_ToolTipBuffer.Ptr_non_const(); diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/App.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.h --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/App.h 2021-11-22 15:00:00.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/App.h 2024-10-12 07:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // App.h -#ifndef __APP_H -#define __APP_H +#ifndef ZIP7_INC_APP_H +#define ZIP7_INC_APP_H #include "../../../Windows/Control/CommandBar.h" #include "../../../Windows/Control/ImageList.h" @@ -30,7 +30,7 @@ kMenuCmdID_Toolbar_End }; -class CPanelCallbackImp: public CPanelCallback +class CPanelCallbackImp Z7_final: public CPanelCallback { CApp *_app; unsigned _index; @@ -40,79 +40,26 @@ _app = app; _index = index; } - virtual void OnTab(); - virtual void SetFocusToPath(unsigned index); - virtual void OnCopy(bool move, bool copyToSame); - virtual void OnSetSameFolder(); - virtual void OnSetSubFolder(); - virtual void PanelWasFocused(); - virtual void DragBegin(); - virtual void DragEnd(); - virtual void RefreshTitle(bool always); + virtual void OnTab() Z7_override; + virtual void SetFocusToPath(unsigned index) Z7_override; + virtual void OnCopy(bool move, bool copyToSame) Z7_override; + virtual void OnSetSameFolder() Z7_override; + virtual void OnSetSubFolder() Z7_override; + virtual void PanelWasFocused() Z7_override; + virtual void DragBegin() Z7_override; + virtual void DragEnd() Z7_override; + virtual void RefreshTitle(bool always) Z7_override; }; -class CApp; - -class CDropTarget: - public IDropTarget, - public CMyUnknownImp -{ - CMyComPtr m_DataObject; - UStringVector m_SourcePaths; - int m_SelectionIndex; - bool m_DropIsAllowed; // = true, if data contain fillist - bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel. - // check it only if m_DropIsAllowed == true - int m_SubFolderIndex; - UString m_SubFolderName; - - CPanel *m_Panel; - bool m_IsAppTarget; // true, if we want to drop to app window (not to panel). - - bool m_SetPathIsOK; - - bool IsItSameDrive() const; - - void QueryGetData(IDataObject *dataObject); - bool IsFsFolderPath() const; - DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect); - void RemoveSelection(); - void PositionCursor(POINTL ptl); - UString GetTargetPath() const; - bool SetPath(bool enablePath) const; - bool SetPath(); - -public: - MY_UNKNOWN_IMP1_MT(IDropTarget) - STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState, POINTL pt, DWORD *effect); - STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect); - STDMETHOD(DragLeave)(); - STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState, POINTL pt, DWORD *effect); - - CDropTarget(): - m_SelectionIndex(-1), - m_DropIsAllowed(false), - m_PanelDropIsAllowed(false), - m_SubFolderIndex(-1), - m_Panel(NULL), - m_IsAppTarget(false), - m_SetPathIsOK(false), - App(NULL), - SrcPanelIndex(-1), - TargetPanelIndex(-1) - {} - - CApp *App; - int SrcPanelIndex; // index of D&D source_panel - int TargetPanelIndex; // what panel to use as target_panel of Application -}; +class CDropTarget; class CApp { public: NWindows::CWindow _window; bool ShowSystemMenu; + bool AutoRefresh_Mode; // bool ShowDeletedFiles; unsigned NumPanels; unsigned LastFocusedPanel; @@ -138,49 +85,31 @@ UString LangString_N_SELECTED_ITEMS; - void ReloadLang(); + void ReloadLangItems(); - CApp(): _window(0), NumPanels(2), LastFocusedPanel(0), - AutoRefresh_Mode(true) + CApp(): + _window(NULL), + AutoRefresh_Mode(true), + NumPanels(2), + LastFocusedPanel(0) { SetPanels_AutoRefresh_Mode(); } - void CreateDragTarget() - { - _dropTargetSpec = new CDropTarget(); - _dropTarget = _dropTargetSpec; - _dropTargetSpec->App = (this); - } - - void SetFocusedPanel(unsigned index) - { - LastFocusedPanel = index; - _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; - } - - void DragBegin(unsigned panelIndex) - { - _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex; - _dropTargetSpec->SrcPanelIndex = panelIndex; - } + void CreateDragTarget(); + void SetFocusedPanel(unsigned index); + void DragBegin(unsigned panelIndex); + void DragEnd(); + + void OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex); + void OnSetSameFolder(unsigned srcPanelIndex); + void OnSetSubFolder(unsigned srcPanelIndex); - void DragEnd() - { - _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; - _dropTargetSpec->SrcPanelIndex = -1; - } - - - void OnCopy(bool move, bool copyToSame, int srcPanelIndex); - void OnSetSameFolder(int srcPanelIndex); - void OnSetSubFolder(int srcPanelIndex); - - HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, COpenResult &openRes); + HRESULT CreateOnePanel(unsigned panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, COpenResult &openRes); HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes); void Read(); void Save(); - void Release(); + void ReleaseApp(); // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } @@ -274,11 +203,19 @@ int GetTimestampLevel() const { return Panels[LastFocusedPanel]._timestampLevel; } void SetTimestampLevel(int level) { - unsigned i; - for (i = 0; i < kNumPanelsMax; i++) + for (unsigned i = 0; i < kNumPanelsMax; i++) { CPanel &panel = Panels[i]; panel._timestampLevel = level; + } + RedrawListItems_InPanels(); + } + + void RedrawListItems_InPanels() + { + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; if (panel.PanelCreated) panel.RedrawListItems(); } @@ -290,7 +227,6 @@ // void Change_ShowNtfsStrems_Mode() { Panels[LastFocusedPanel].Change_ShowNtfsStrems_Mode(); } // void Change_ShowDeleted() { ShowDeletedFiles = !ShowDeletedFiles; } - bool AutoRefresh_Mode; bool Get_AutoRefresh_Mode() { // return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); @@ -307,13 +243,13 @@ Panels[i].Set_AutoRefresh_Mode(AutoRefresh_Mode); } - void OpenBookmark(int index) { GetFocusedPanel().OpenBookmark(index); } - void SetBookmark(int index) { GetFocusedPanel().SetBookmark(index); } + void OpenBookmark(unsigned index) { GetFocusedPanel().OpenBookmark(index); } + void SetBookmark(unsigned index) { GetFocusedPanel().SetBookmark(index); } void ReloadToolbars(); void ReadToolbar() { - UInt32 mask = ReadToolbarsMask(); + const UInt32 mask = ReadToolbarsMask(); if (mask & ((UInt32)1 << 31)) { ShowButtonsLables = !g_IsSmallScreen; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AppState.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AppState.h --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/AppState.h 2013-02-10 17:59:18.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/AppState.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,7 +1,7 @@ // AppState.h -#ifndef __APP_STATE_H -#define __APP_STATE_H +#ifndef ZIP7_INC_APP_STATE_H +#define ZIP7_INC_APP_STATE_H #include "../../../Windows/Synchronization.h" diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.cpp 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.cpp --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.cpp 2021-02-11 08:53:59.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.cpp 2024-07-09 11:00:00.000000000 +0000 @@ -4,7 +4,7 @@ #include "../../../Common/MyWindows.h" -#include +#include "../../../Common/IntToString.h" #ifndef UNDER_CE #include "../../../Windows/CommonDialog.h" @@ -25,7 +25,6 @@ #ifdef USE_MY_BROWSE_DIALOG #include "../../../Common/Defs.h" -#include "../../../Common/IntToString.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/FileDir.h" @@ -40,11 +39,11 @@ #include "PropertyNameRes.h" #include "SysIconUtils.h" -#ifndef _SFX +#ifndef Z7_SFX #include "RegistryUtils.h" #endif -#endif +#endif // USE_MY_BROWSE_DIALOG #include "ComboDialog.h" #include "LangUtils.h" @@ -56,26 +55,23 @@ using namespace NName; using namespace NFind; +static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) +{ + ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); +} + #ifdef USE_MY_BROWSE_DIALOG +#if 0 +extern HINSTANCE g_hInstance; +#endif extern bool g_LVN_ITEMACTIVATE_Support; static const int kParentIndex = -1; static const UINT k_Message_RefreshPathEdit = WM_APP + 1; -static HRESULT GetNormalizedError() -{ - DWORD errorCode = GetLastError(); - return errorCode == 0 ? E_FAIL : errorCode; -} - extern UString HResultToMessage(HRESULT errorCode); -static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) -{ - ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); -} - static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name) { UString s = HResultToMessage(errorCode); @@ -98,17 +94,21 @@ CExtToIconMap _extToIconMap; int _sortIndex; bool _ascending; + #ifndef Z7_SFX bool _showDots; + #endif UString _topDirPrefix; // we don't open parent of that folder UString DirPrefix; - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - virtual bool OnNotify(UINT controlID, LPNMHDR header); - virtual bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - virtual void OnOK(); + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); } @@ -126,59 +126,37 @@ int GetRealItemIndex(int indexInListView) const { LPARAM param; - if (!_list.GetItemParam(indexInListView, param)) + if (!_list.GetItemParam((unsigned)indexInListView, param)) return (int)-1; return (int)param; } public: + + bool SaveMode; bool FolderMode; + int FilterIndex; // [in / out] + CObjectVector Filters; + + UString FilePath; // [in / out] UString Title; - UString FilePath; // input/ result path - bool ShowAllFiles; - UStringVector Filters; - UString FilterDescription; - - CBrowseDialog(): _showDots(false), FolderMode(false), ShowAllFiles(true) {} - void SetFilter(const UString &s); - INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_BROWSE, parent); } - int CompareItems(LPARAM lParam1, LPARAM lParam2); + + CBrowseDialog(): + #ifndef Z7_SFX + _showDots(false), + #endif + SaveMode(false) + , FolderMode(false) + , FilterIndex(-1) + {} + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE, parent); } + int CompareItems(LPARAM lParam1, LPARAM lParam2) const; }; -void CBrowseDialog::SetFilter(const UString &s) -{ - Filters.Clear(); - UString mask; - unsigned i; - for (i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if (c == ';') - { - if (!mask.IsEmpty()) - Filters.Add(mask); - mask.Empty(); - } - else - mask += c; - } - if (!mask.IsEmpty()) - Filters.Add(mask); - ShowAllFiles = Filters.IsEmpty(); - for (i = 0; i < Filters.Size(); i++) - { - const UString &f = Filters[i]; - if (f == L"*.*" || f == L"*") - { - ShowAllFiles = true; - break; - } - } -} bool CBrowseDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG LangSetDlgItems(*this, NULL, 0); #endif if (!Title.IsEmpty()) @@ -187,16 +165,11 @@ _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER)); _pathEdit.Attach(GetItem(IDE_BROWSE_PATH)); - if (FolderMode) - HideItem(IDC_BROWSE_FILTER); - else - EnableItem(IDC_BROWSE_FILTER, false); - #ifndef UNDER_CE _list.SetUnicodeFormat(); #endif - #ifndef _SFX + #ifndef Z7_SFX CFmSettings st; st.Load(); if (st.SingleClick) @@ -205,26 +178,38 @@ #endif { - UString s; - if (!FilterDescription.IsEmpty()) - s = FilterDescription; - else if (ShowAllFiles) - s = "*.*"; - else + /* + Filters.Clear(); // for debug + if (Filters.IsEmpty() && !FolderMode) { - FOR_VECTOR (i, Filters) - { - if (i != 0) - s.Add_Space(); - s += Filters[i]; - } + CBrowseFilterInfo &f = Filters.AddNew(); + const UString mask("*.*"); + f.Masks.Add(mask); + // f.Description = "("; + f.Description += mask; + // f.Description += ")"; } - _filterCombo.AddString(s); - _filterCombo.SetCurSel(0); + */ + + FOR_VECTOR (i, Filters) + { + _filterCombo.AddString(Filters[i].Description); + } + + if (Filters.Size() <= 1) + { + if (FolderMode) + HideItem(IDC_BROWSE_FILTER); + else + EnableItem(IDC_BROWSE_FILTER, false); + } + + if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size()) + _filterCombo.SetCurSel(FilterIndex); } - _list.SetImageList(GetSysImageList(true), LVSIL_SMALL); - _list.SetImageList(GetSysImageList(false), LVSIL_NORMAL); + _list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL); + _list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL); _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100); _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100); @@ -261,7 +246,7 @@ _topDirPrefix.Empty(); { - int rootSize = GetRootPrefixSize(FilePath); + unsigned rootSize = GetRootPrefixSize(FilePath); #if defined(_WIN32) && !defined(UNDER_CE) // We can go up from root folder to drives list if (IsDrivePath(FilePath)) @@ -301,9 +286,42 @@ #ifndef UNDER_CE /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible, even if we use mouse for pressing the button to open this dialog. */ - PostMsg(MY__WM_UPDATEUISTATE, MAKEWPARAM(MY__UIS_CLEAR, MY__UISF_HIDEFOCUS)); + PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS)); #endif +#if 0 + { + const HWND hwndTool = GetItem(IDB_BROWSE_CREATE_DIR); + if (hwndTool) + { + // Create the tooltip: + const HWND hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP + // | TTS_BALLOON + , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + *this, NULL, g_hInstance, NULL); + if (hwndTip) + { + // Associate the tooltip with the tool: + TOOLINFOW toolInfo; + memset(&toolInfo, 0, sizeof(toolInfo)); + toolInfo.cbSize = sizeof(toolInfo); + toolInfo.hwnd = *this; + toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + toolInfo.uId = (UINT_PTR)hwndTool; + UString s; +#ifdef Z7_LANG + LangString_OnlyFromLangFile(IDM_CREATE_FOLDER, s); + s.RemoveChar(L'&'); + if (s.IsEmpty()) +#endif + s = "Create Folder"; + toolInfo.lpszText = s.Ptr_non_const(); + SendMessage(hwndTip, TTM_ADDTOOLW, 0, (LPARAM)&toolInfo); + } + } + } +#endif return CModalDialog::OnInit(); } @@ -368,6 +386,24 @@ return CModalDialog::OnMessage(message, wParam, lParam); } + +bool CBrowseDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_BROWSE_FILTER: + { + Reload(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + + bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) { if (header->hwndFrom != _list) @@ -379,13 +415,13 @@ OnItemEnter(); break; case NM_DBLCLK: - case NM_RETURN: // probabably it's unused + case NM_RETURN: // probably it's unused if (!g_LVN_ITEMACTIVATE_Support) OnItemEnter(); break; case LVN_COLUMNCLICK: { - int index = LPNMLISTVIEW(header)->iSubItem; + const int index = LPNMLISTVIEW(header)->iSubItem; if (index == _sortIndex) _ascending = !_ascending; else @@ -413,7 +449,7 @@ bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) { - bool ctrl = IsKeyDown(VK_CONTROL); + const bool ctrl = IsKeyDown(VK_CONTROL); switch (keyDownInfo->wVKey) { @@ -434,7 +470,8 @@ return false; } -bool CBrowseDialog::OnButtonClicked(int buttonID, HWND buttonHWND) + +bool CBrowseDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { @@ -474,23 +511,27 @@ return false; if (IS_PATH_SEPAR(s.Back())) return false; - int pos = s.ReverseFind_PathSepar(); - parentPrefix.SetFrom(s, pos + 1); - name = s.Ptr((unsigned)(pos + 1)); + const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1); + parentPrefix.SetFrom(s, pos1); + name = s.Ptr(pos1); return true; } -int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) +int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) const { + if (lParam1 == lParam2) return 0; if (lParam1 == kParentIndex) return -1; if (lParam2 == kParentIndex) return 1; + const CFileInfo &f1 = _files[(int)lParam1]; const CFileInfo &f2 = _files[(int)lParam2]; - bool isDir1 = f1.IsDir(); - bool isDir2 = f2.IsDir(); - if (isDir1 && !isDir2) return -1; - if (isDir2 && !isDir1) return 1; + const bool isDir2 = f2.IsDir(); + if (f1.IsDir()) + { + if (!isDir2) return -1; + } + else if (isDir2) return 1; int res = 0; switch (_sortIndex) @@ -507,20 +548,22 @@ return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2); } -static void ConvertSizeToString(UInt64 v, wchar_t *s) +wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s); +wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s) { - Byte c = 0; + char c = 0; if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; } else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; } else if (v >= ((UInt64)10000 << 0)) { v >>= 10; c = 'K'; } - ConvertUInt64ToString(v, s); + s = ConvertUInt64ToString(v, s); if (c != 0) { - s += MyStringLen(s); *s++ = ' '; - *s++ = c; - *s++ = 0; + *s++ = (wchar_t)c; + *s++ = 'B'; + *s = 0; } + return s; } // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter @@ -536,42 +579,57 @@ isDrive = true; FStringVector drives; if (!MyGetLogicalDriveStrings(drives)) - return GetNormalizedError(); + return GetLastError_noZero_HRESULT(); FOR_VECTOR (i, drives) { - FString d = drives[i]; - if (d.Len() < 3 || d.Back() != '\\') + const FString &d = drives[i]; + if (d.Len() < 2 || d.Back() != '\\') return E_FAIL; - d.DeleteBack(); CFileInfo &fi = files.AddNew(); fi.SetAsDir(); fi.Name = d; + fi.Name.DeleteBack(); } } else #endif { + const UStringVector *masks = NULL; + if (!Filters.IsEmpty() && _filterCombo.GetCount() > 0) + { + const int selected = _filterCombo.GetCurSel(); + // GetItemData_of_CurSel(); // we don't use data field + if (/* selected >= 0 && */ (unsigned)selected < Filters.Size()) + { + const UStringVector &m = Filters[selected].Masks; + if (m.Size() > 1 || (m.Size() == 1 + && !m[0].IsEqualTo("*.*") + && !m[0].IsEqualTo("*"))) + masks = &m; + } + } CEnumerator enumerator; enumerator.SetDirPrefix(us2fs(pathPrefix)); + CFileInfo fi; for (;;) { bool found; - CFileInfo fi; if (!enumerator.Next(fi, found)) - return GetNormalizedError(); + return GetLastError_noZero_HRESULT(); if (!found) break; if (!fi.IsDir()) { if (FolderMode) continue; - if (!ShowAllFiles) + if (masks) { unsigned i; - for (i = 0; i < Filters.Size(); i++) - if (DoesWildcardMatchName(Filters[i], fs2us(fi.Name))) + const unsigned numMasks = masks->Size(); + for (i = 0; i < numMasks; i++) + if (DoesWildcardMatchName((*masks)[i], fs2us(fi.Name))) break; - if (i == Filters.Size()) + if (i == numMasks) continue; } } @@ -590,19 +648,19 @@ LVITEMW item; - int index = 0; + unsigned index = 0; int cursorIndex = -1; - #ifndef _SFX + #ifndef Z7_SFX if (_showDots && _topDirPrefix != DirPrefix) { - item.iItem = index; + item.iItem = (int)index; const UString itemName (".."); if (selectedName.IsEmpty()) - cursorIndex = index; + cursorIndex = (int)index; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - int subItem = 0; - item.iSubItem = subItem++; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); item.lParam = kParentIndex; item.pszText = itemName.Ptr_non_const(); item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix); @@ -617,34 +675,36 @@ for (unsigned i = 0; i < _files.Size(); i++, index++) { - item.iItem = index; + item.iItem = (int)index; const CFileInfo &fi = _files[i]; const UString name = fs2us(fi.Name); if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0) - cursorIndex = index; + cursorIndex = (int)index; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - int subItem = 0; - item.iSubItem = subItem++; - item.lParam = i; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = (LPARAM)i; item.pszText = name.Ptr_non_const(); const UString fullPath = DirPrefix + name; #ifndef UNDER_CE if (isDrive) { - if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0) - item.iImage = 0; + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path( + fi.Name + FCHAR_PATH_SEPARATOR, + FILE_ATTRIBUTE_DIRECTORY); } else #endif item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath); if (item.iImage < 0) - item.iImage = 0; + item.iImage = 0; _list.InsertItem(&item); - wchar_t s[32]; + wchar_t s[64]; { s[0] = 0; - ConvertUtcFileTimeToString(fi.MTime, s, + if (!FILETIME_IsZero(fi.MTime)) + ConvertUtcFileTimeToString(fi.MTime, s, #ifndef UNDER_CE kTimestampPrintLevel_MIN #else @@ -656,7 +716,7 @@ { s[0] = 0; if (!fi.IsDir()) - ConvertSizeToString(fi.Size, s); + Browse_ConvertSizeToString(fi.Size, s); _list.SetSubItem(index, subItem++, s); } } @@ -675,14 +735,14 @@ HRESULT CBrowseDialog::Reload() { UString selected; - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index >= 0) { - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex != kParentIndex) selected = fs2us(_files[fileIndex].Name); } - UString dirPathTemp = DirPrefix; + const UString dirPathTemp = DirPrefix; return Reload(dirPathTemp, selected); } @@ -698,14 +758,14 @@ void CBrowseDialog::SetPathEditText() { - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index < 0) { if (FolderMode) _pathEdit.SetText(DirPrefix); return; } - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex == kParentIndex) { if (FolderMode) @@ -745,7 +805,7 @@ { if (!NDir::CreateComplexDir(destPath)) { - MessageBox_HResError((HWND)*this, GetNormalizedError(), fs2us(destPath)); + MessageBox_HResError((HWND)*this, GetLastError_noZero_HRESULT(), fs2us(destPath)); } else { @@ -759,10 +819,10 @@ void CBrowseDialog::OnItemEnter() { - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index < 0) return; - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex == kParentIndex) OpenParentFolder(); else @@ -782,7 +842,7 @@ UString s = DirPrefix; s += fs2us(file.Name); s.Add_PathSepar(); - HRESULT res = Reload(s, UString()); + const HRESULT res = Reload(s, UString()); if (res != S_OK) MessageBox_HResError(*this, res, s); SetPathEditText(); @@ -802,10 +862,13 @@ FilePath = fs2us(destPath); if (FolderMode) NormalizeDirPathPrefix(FilePath); + FilterIndex = _filterCombo.GetCurSel(); End(IDOK); } -#endif +#endif // USE_MY_BROWSE_DIALOG + + bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath) { @@ -813,12 +876,13 @@ #ifndef UNDER_CE - #ifdef USE_MY_BROWSE_DIALOG +#ifdef USE_MY_BROWSE_DIALOG if (!IsSuperOrDevicePath(path)) - #endif + if (MyStringLen(path) < MAX_PATH) +#endif return NShell::BrowseForFolder(owner, title, path, resultPath); - #endif + #endif // UNDER_CE #ifdef USE_MY_BROWSE_DIALOG @@ -831,64 +895,107 @@ if (dialog.Create(owner) != IDOK) return false; resultPath = dialog.FilePath; - #endif - return true; + + #endif } -bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, - LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath) -{ - resultPath.Empty(); - #ifndef UNDER_CE +// LPCWSTR filterDescription, LPCWSTR filter, - #ifdef USE_MY_BROWSE_DIALOG - if (!IsSuperOrDevicePath(path)) - #endif +bool CBrowseInfo::BrowseForFile(const CObjectVector &filters) +{ +#ifndef UNDER_CE +#ifdef USE_MY_BROWSE_DIALOG + /* win10: + GetOpenFileName() for FilePath doesn't support super prefix "\\\\?\\" + GetOpenFileName() for FilePath doesn't support long path + */ + if (!IsSuperOrDevicePath(FilePath)) + // if (filters.Size() > 100) // for debug +#endif { - if (MyGetOpenFileName(owner, title, NULL, path, filterDescription, filter, resultPath)) + const UString filePath_Store = FilePath; + UString dirPrefix; + { + FString prefix, name; + if (NDir::GetFullPathAndSplit(us2fs(FilePath), prefix, name)) + { + dirPrefix = fs2us(prefix); + FilePath = fs2us(name); + } + } + UStringVector filters2; + FOR_VECTOR (i, filters) + { + const CBrowseFilterInfo &fi = filters[i]; + filters2.Add(fi.Description); + UString s; + FOR_VECTOR (k, fi.Masks) + { + if (k != 0) + s += ";"; + s += fi.Masks[k]; + } + filters2.Add(s); + } + if (CommonDlg_BrowseForFile(!dirPrefix.IsEmpty() ? dirPrefix.Ptr(): NULL, filters2)) return true; - #ifdef UNDER_CE + FilePath = filePath_Store; + + #ifdef UNDER_CE return false; - #else + #else // maybe we must use GetLastError in WinCE. - DWORD errorCode = CommDlgExtendedError(); - const char *errorMessage = NULL; - switch (errorCode) - { - case 0: return false; // cancel or close obn dialog - case FNERR_INVALIDFILENAME: errorMessage = "Invalid File Name"; break; - default: errorMessage = "Open Dialog Error"; - } - if (!errorMessage) - return false; + const DWORD errorCode = CommDlgExtendedError(); + #ifdef USE_MY_BROWSE_DIALOG + // FNERR_INVALIDFILENAME is expected error, if long path was used + if (errorCode != FNERR_INVALIDFILENAME + || FilePath.Len() < MAX_PATH) + #endif { - UString s (errorMessage); + if (errorCode == 0) // cancel or close on dialog + return false; + const char *message = NULL; + if (errorCode == FNERR_INVALIDFILENAME) + message = "Invalid file name"; + UString s ("Open Dialog Error:"); s.Add_LF(); - s += path; - MessageBox_Error_Global(owner, s); + if (message) + s += message; + else + { + char temp[16]; + ConvertUInt32ToHex8Digits(errorCode, temp); + s += "Error #"; + s += temp; + } + s.Add_LF(); + s += FilePath; + MessageBox_Error_Global(hwndOwner, s); } - #endif + #endif // UNDER_CE } - #endif +#endif // UNDER_CE - #ifdef USE_MY_BROWSE_DIALOG +#ifdef USE_MY_BROWSE_DIALOG + CBrowseDialog dialog; - if (title) - dialog.Title = title; - if (path) - dialog.FilePath = path; + dialog.FolderMode = false; - if (filter) - dialog.SetFilter(filter); - if (filterDescription) - dialog.FilterDescription = filterDescription; - if (dialog.Create(owner) != IDOK) + dialog.SaveMode = SaveMode; + dialog.FilterIndex = FilterIndex; + dialog.Filters = filters; + + if (lpstrTitle) + dialog.Title = lpstrTitle; + dialog.FilePath = FilePath; + if (dialog.Create(hwndOwner) != IDOK) return false; - resultPath = dialog.FilePath; - #endif + FilePath = dialog.FilePath; + FilterIndex = dialog.FilterIndex; +#endif return true; } @@ -913,7 +1020,9 @@ result.Empty(); UString path = path2; + #ifdef _WIN32 path.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif unsigned start = 0; UString base; @@ -926,9 +1035,7 @@ return true; } #endif - int pos = GetRootPrefixSize(path); - if (pos > 0) - start = pos; + start = GetRootPrefixSize(path); } else { @@ -973,8 +1080,8 @@ { if (start == path.Len()) break; - int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); - cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : slashPos) - start); + const int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); + cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : (unsigned)slashPos) - start); if (checkExist) { CFileInfo fi; @@ -994,8 +1101,8 @@ result += cur; if (slashPos < 0) break; + start = (unsigned)(slashPos + 1); result.Add_PathSepar(); - start = slashPos + 1; } return true; diff -Nru 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.h 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.h --- 7zip-22.01+dfsg/CPP/7zip/UI/FileManager/BrowseDialog.h 2014-07-23 13:45:15.000000000 +0000 +++ 7zip-22.01+really25.01+dfsg/CPP/7zip/UI/Fil