From b8a308012ff940f3d4638215918c7aee5c27f62a Mon Sep 17 00:00:00 2001 From: coderb Date: Mon, 18 Dec 2017 11:01:37 -0500 Subject: [PATCH] rar5: unpack work --- .../FragmentedWindow.unpack50frag_cpp.cs | 11 ++++++----- .../Compressors/Rar/UnpackV2017/Unpack.cs | 5 +++++ .../Rar/UnpackV2017/Unpack.unpack20_cpp.cs | 2 +- .../Rar/UnpackV2017/Unpack.unpack30_cpp.cs | 4 ++-- .../Rar/UnpackV2017/Unpack.unpack_cpp.cs | 7 ++++--- .../Compressors/Rar/UnpackV2017/notes.txt | 14 ++++++++++++++ .../Compressors/Rar/UnpackV2017/unpack_hpp.cs | 2 +- src/SharpCompress/Utility.cs | 11 ++++++----- 8 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/FragmentedWindow.unpack50frag_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/FragmentedWindow.unpack50frag_cpp.cs index 8c425713..6bff0202 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/FragmentedWindow.unpack50frag_cpp.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/FragmentedWindow.unpack50frag_cpp.cs @@ -20,10 +20,11 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017 { partial class FragmentedWindow { + public FragmentedWindow() { - memset(Mem,0,sizeof(Mem)); - memset(MemSize,0,sizeof(MemSize)); + //memset(Mem,0,sizeof(Mem)); + //memset(MemSize,0,sizeof(MemSize)); } @@ -60,10 +61,10 @@ public void Init(size_t WinSize) // smaller than some arbitrary constant. size_t MinSize=Math.Max(Size/(ASIZE(Mem)-BlockNum), 0x400000); - byte *NewMem=null; + byte[] NewMem=null; while (Size>=MinSize) { - NewMem=(byte *)malloc(Size); + NewMem=new byte[Size]; if (NewMem!=null) break; Size-=Size/32; @@ -73,7 +74,7 @@ public void Init(size_t WinSize) // Clean the window to generate the same output when unpacking corrupt // RAR files, which may access to unused areas of sliding dictionary. - memset(NewMem,0,Size); + Utility.Memset(NewMem,0,Size); Mem[BlockNum]=NewMem; TotalSize+=Size; diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.cs index 7079e0d9..e50efcfa 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.cs @@ -13,6 +13,11 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017 public void DoUnpack(FileHeader fileHeader, Stream readStream, Stream writeStream) { + // as of 12/2017 .NET limits array indexing to using a signed integer + // MaxWinSize causes unpack to use a fragmented window when the file + // window size exceeds MaxWinSize + MaxWinSize = ((uint)int.MaxValue) + 1; + // may be long.MaxValue which could indicate unknown size (not present in header) DestUnpSize = fileHeader.UncompressedSize; this.fileHeader = fileHeader; diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs index 8d389d70..6e54b90c 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs @@ -198,7 +198,7 @@ bool ReadTables20() UnpAudioBlock=(BitField & 0x8000)!=0; if (!(BitField & 0x4000)) - memset(UnpOldTable20,0,sizeof(UnpOldTable20)); + Utility.Memset(UnpOldTable20,0,UnpOldTable20.Length); Inp.addbits(2); uint TableSize; diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack30_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack30_cpp.cs index 6e915734..ff4252fb 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack30_cpp.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack30_cpp.cs @@ -671,7 +671,7 @@ bool ReadTables30() LowDistRepCount=0; if ((BitField & 0x4000) == 0) - memset(UnpOldTable,0,sizeof(UnpOldTable)); + Utility.Memset(UnpOldTable,0,UnpOldTable.Length); Inp.faddbits(2); for (uint I=0;I ulong (x64) [size_t] -> uint (x86) + +size_t is an unsigned data type defined by several C/C++ standards, e.g. the C99 ISO/IEC 9899 standard, that is defined +in stddef.h.1 It can be further imported by inclusion of stdlib.h as this file internally sub includes stddef.h. +This type is used to represent the size of an object. Library functions that take or return sizes expect them to be of type or +have the return type of size_t. Further, the most frequently used compiler-based operator sizeof should evaluate to a constant +value that is compatible with size_t. + + +20171218 +urggh, this allows things like new int[int.MaxValue] but NOT new byte[uint.MaxValue] +currently arrays are limited to being indexed by an int hence int.MaxValue entries. weak. +To get arrays > 2GB on x64 we need to configure + +https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/unpack_hpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/unpack_hpp.cs index 35a3de44..3873835a 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/unpack_hpp.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/unpack_hpp.cs @@ -366,7 +366,7 @@ internal partial class Unpack ModelPPM PPM; int PPMEscChar; - byte UnpOldTable[HUFF_TABLE_SIZE30]; + readonly byte [] UnpOldTable = new byte[HUFF_TABLE_SIZE30]; int UnpBlockType; // If we already read decoding tables for Unpack v2,v3,v5. diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 8700d4af..f24528c8 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -79,15 +79,15 @@ namespace SharpCompress #if NET45 // super fast memset, up to 40x faster than for loop on large arrays // see https://stackoverflow.com/questions/1897555/what-is-the-equivalent-of-memset-in-c - private static readonly Action MemsetDelegate = CreateMemsetDelegate(); + private static readonly Action MemsetDelegate = CreateMemsetDelegate(); - private static Action CreateMemsetDelegate() { + private static Action CreateMemsetDelegate() { var dynamicMethod = new DynamicMethod( "Memset", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null, - new[] { typeof(IntPtr), typeof(byte), typeof(int) }, + new[] { typeof(IntPtr), typeof(byte), typeof(uint) }, typeof(Utility), true); var generator = dynamicMethod.GetILGenerator(); @@ -96,13 +96,13 @@ namespace SharpCompress generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Initblk); generator.Emit(OpCodes.Ret); - return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + return (Action)dynamicMethod.CreateDelegate(typeof(Action)); } public static void Memset(byte[] array, byte what, int length) { var gcHandle = GCHandle.Alloc(array, GCHandleType.Pinned); - MemsetDelegate(gcHandle.AddrOfPinnedObject(), what, length); + MemsetDelegate(gcHandle.AddrOfPinnedObject(), what, (uint)length); gcHandle.Free(); } #else @@ -115,6 +115,7 @@ namespace SharpCompress } #endif + /// /// Fills the array with an specific value. ///