mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 07:25:11 +00:00
rar5: unpack work
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<BC;I++)
|
||||
@@ -766,7 +766,7 @@ void UnpInitData30(bool Solid)
|
||||
if (!Solid)
|
||||
{
|
||||
TablesRead3=false;
|
||||
memset(UnpOldTable,0,sizeof(UnpOldTable));
|
||||
Utility.Memset(UnpOldTable,0,(uint)UnpOldTable.Length);
|
||||
PPMEscChar=2;
|
||||
UnpBlockType=BLOCK_LZ;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,8 @@ void Init(size_t WinSize,bool Solid)
|
||||
{
|
||||
// Clean the window to generate the same output when unpacking corrupt
|
||||
// RAR files, which may access unused areas of sliding dictionary.
|
||||
memset(NewWindow,0,WinSize);
|
||||
// sharpcompress: don't need this, freshly allocated above
|
||||
//memset(NewWindow,0,WinSize);
|
||||
|
||||
|
||||
// If Window is not NULL, it means that window size has grown.
|
||||
@@ -139,8 +140,8 @@ void Init(size_t WinSize,bool Solid)
|
||||
for (size_t I=1;I<=MaxWinSize;I++)
|
||||
NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
|
||||
|
||||
if (Window!=null)
|
||||
free(Window);
|
||||
//if (Window!=null)
|
||||
// free(Window);
|
||||
Window=NewWindow;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,3 +34,17 @@ The size_t type is the unsigned integer type that is the result of the sizeof op
|
||||
so it is guaranteed to be big enough to contain the size of the biggest object your system can handle (e.g., a static array of 8Gb).
|
||||
[size_t] -> 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
|
||||
<gcAllowVeryLargeObjects enabled="true"/>
|
||||
https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element
|
||||
@@ -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.
|
||||
|
||||
@@ -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<IntPtr, byte, int> MemsetDelegate = CreateMemsetDelegate();
|
||||
private static readonly Action<IntPtr, byte, uint> MemsetDelegate = CreateMemsetDelegate();
|
||||
|
||||
private static Action<IntPtr, byte, int> CreateMemsetDelegate() {
|
||||
private static Action<IntPtr, byte, uint> 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<IntPtr, byte, int>)dynamicMethod.CreateDelegate(typeof(Action<IntPtr, byte, int>));
|
||||
return (Action<IntPtr, byte, uint>)dynamicMethod.CreateDelegate(typeof(Action<IntPtr, byte, uint>));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Fills the array with an specific value.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user