Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/SharpCompress/Compressors/ArcLzw/ArcLzwStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public List<byte> Decompress(byte[] input, bool useCrunched)

if (useCrunched)
{
if (input.Length == 0)
{
throw new InvalidFormatException("ArcLzwStream: compressed data is empty");
}
if (input[0] != BITS)
{
throw new InvalidFormatException($"File packed with {input[0]}, expected {BITS}.");
Expand Down Expand Up @@ -129,6 +133,10 @@ public List<byte> Decompress(byte[] input, bool useCrunched)

while (code >= 256)
{
if (code >= suffix.Length)
{
throw new InvalidFormatException("ArcLzwStream: code out of range");
}
stack.Push(suffix[code]);
code = prefix[code];
}
Expand Down
68 changes: 64 additions & 4 deletions src/SharpCompress/Compressors/BZip2/CBZip2InputStream.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,21 @@ private async ValueTask RecvDecodingTablesAsync(CancellationToken cancellationTo

/* Now the selectors */
nGroups = await BsRAsync(3, cancellationToken).ConfigureAwait(false);
if (nGroups < 2 || nGroups > BZip2Constants.N_GROUPS)
{
throw new InvalidFormatException("BZip2: invalid number of Huffman trees");
}
nSelectors = await BsRAsync(15, cancellationToken).ConfigureAwait(false);
for (i = 0; i < nSelectors; i++)
{
j = 0;
while (await BsRAsync(1, cancellationToken).ConfigureAwait(false) == 1)
{
j++;
if (j >= nGroups)
{
throw new InvalidFormatException("BZip2: invalid selector MTF value");
}
}
if (i < BZip2Constants.MAX_SELECTORS)
{
Expand All @@ -266,6 +274,10 @@ private async ValueTask RecvDecodingTablesAsync(CancellationToken cancellationTo
for (i = 0; i < nSelectors; i++)
{
v = selectorMtf[i];
if (v >= nGroups)
{
throw new InvalidFormatException("BZip2: selector MTF value out of range");
}
tmp = pos[v];
while (v > 0)
{
Expand Down Expand Up @@ -374,6 +386,10 @@ cache misses.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand Down Expand Up @@ -405,7 +421,14 @@ cache misses.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}

while (true)
Expand Down Expand Up @@ -448,6 +471,10 @@ cache misses.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand Down Expand Up @@ -479,7 +506,14 @@ cache misses.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}
} while (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB);

Expand Down Expand Up @@ -550,6 +584,10 @@ hence the unrolling.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand Down Expand Up @@ -581,7 +619,14 @@ hence the unrolling.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}
}
}
Expand All @@ -605,10 +650,18 @@ private async ValueTask SetupBlockAsync(CancellationToken cancellationToken)
for (i = 0; i <= last; i++)
{
ch = ll8[i];
if (cftab[ch] < 0 || cftab[ch] >= tt.Length)
{
throw new InvalidFormatException("BZip2: block data out of bounds");
}
tt[cftab[ch]] = i;
cftab[ch]++;
}

if (origPtr < 0 || origPtr >= tt.Length)
{
throw new InvalidFormatException("BZip2: origPtr out of bounds");
}
tPos = tt[origPtr];

count = 0;
Expand Down Expand Up @@ -806,6 +859,10 @@ private async ValueTask<int> BsRAsync(int n, CancellationToken cancellationToken
int v;
while (bsLive < n)
{
if (bsStream is null)
{
CompressedStreamEOF();
}
int zzi;
int thech = '\0';
var b = ArrayPool<byte>.Shared.Rent(1);
Expand Down Expand Up @@ -858,7 +915,10 @@ public static async ValueTask<CBZip2InputStream> CreateAsync(
cbZip2InputStream.ll8 = null;
cbZip2InputStream.tt = null;
cbZip2InputStream.BsSetStream(zStream);
await cbZip2InputStream.InitializeAsync(true, cancellationToken).ConfigureAwait(false);
if (!await cbZip2InputStream.InitializeAsync(true, cancellationToken).ConfigureAwait(false))
{
throw new InvalidFormatException("Not a valid BZip2 stream");
}
await cbZip2InputStream.InitBlockAsync(cancellationToken).ConfigureAwait(false);
await cbZip2InputStream.SetupBlockAsync(cancellationToken).ConfigureAwait(false);
return cbZip2InputStream;
Expand Down
72 changes: 68 additions & 4 deletions src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ bool leaveOpen
cbZip2InputStream.ll8 = null;
cbZip2InputStream.tt = null;
cbZip2InputStream.BsSetStream(zStream);
cbZip2InputStream.Initialize(true);
if (!cbZip2InputStream.Initialize(true))
{
throw new InvalidFormatException("Not a valid BZip2 stream");
}
cbZip2InputStream.InitBlock();
cbZip2InputStream.SetupBlock();
return cbZip2InputStream;
Expand Down Expand Up @@ -403,6 +406,10 @@ private int BsR(int n)
int v;
while (bsLive < n)
{
if (bsStream is null)
{
CompressedStreamEOF();
}
int zzi;
int thech = '\0';
try
Expand Down Expand Up @@ -477,6 +484,10 @@ int alphaSize
}
for (i = 0; i < alphaSize; i++)
{
if (length[i] >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: invalid Huffman code length");
}
basev[length[i] + 1]++;
}

Expand Down Expand Up @@ -553,13 +564,21 @@ private void RecvDecodingTables()

/* Now the selectors */
nGroups = BsR(3);
if (nGroups < 2 || nGroups > BZip2Constants.N_GROUPS)
{
throw new InvalidFormatException("BZip2: invalid number of Huffman trees");
}
nSelectors = BsR(15);
for (i = 0; i < nSelectors; i++)
{
j = 0;
while (BsR(1) == 1)
{
j++;
if (j >= nGroups)
{
throw new InvalidFormatException("BZip2: invalid selector MTF value");
}
}
if (i < BZip2Constants.MAX_SELECTORS)
{
Expand All @@ -582,6 +601,10 @@ private void RecvDecodingTables()
for (i = 0; i < nSelectors; i++)
{
v = selectorMtf[i];
if (v >= nGroups)
{
throw new InvalidFormatException("BZip2: selector MTF value out of range");
}
tmp = pos[v];
while (v > 0)
{
Expand Down Expand Up @@ -689,6 +712,10 @@ cache misses.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand Down Expand Up @@ -717,7 +744,14 @@ cache misses.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}

while (true)
Expand Down Expand Up @@ -760,6 +794,10 @@ cache misses.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand Down Expand Up @@ -788,7 +826,14 @@ cache misses.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}
} while (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB);

Expand Down Expand Up @@ -859,6 +904,10 @@ hence the unrolling.
while (zvec > limit[zt][zn])
{
zn++;
if (zn >= BZip2Constants.MAX_CODE_LEN)
{
throw new InvalidFormatException("BZip2: Huffman code too long");
}
{
{
while (bsLive < 1)
Expand All @@ -883,7 +932,14 @@ hence the unrolling.
}
zvec = (zvec << 1) | zj;
}
nextSym = perm[zt][zvec - basev[zt][zn]];
{
int permIdx = zvec - basev[zt][zn];
if (permIdx < 0 || permIdx >= perm[zt].Length)
{
throw new InvalidFormatException("BZip2: invalid Huffman symbol");
}
nextSym = perm[zt][permIdx];
}
}
}
}
Expand All @@ -907,10 +963,18 @@ private void SetupBlock()
for (i = 0; i <= last; i++)
{
ch = ll8[i];
if (cftab[ch] < 0 || cftab[ch] >= tt.Length)
{
throw new InvalidFormatException("BZip2: block data out of bounds");
}
tt[cftab[ch]] = i;
cftab[ch]++;
}

if (origPtr < 0 || origPtr >= tt.Length)
{
throw new InvalidFormatException("BZip2: origPtr out of bounds");
}
tPos = tt[origPtr];

count = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/SharpCompress/Compressors/Deflate64/HuffmanTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ private void CreateTable()

do
{
if (index < 0 || index >= array.Length)
{
throw new InvalidFormatException("Deflate64: invalid Huffman data");
}
var value = array[index];

if (value == 0)
Expand Down
5 changes: 4 additions & 1 deletion src/SharpCompress/Compressors/Explode/ExplodeStream.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ internal static async ValueTask<ExplodeStream> CreateAsync(
)
{
var ex = new ExplodeStream(inStr, compressedSize, uncompressedSize, generalPurposeBitFlag);
await ex.explode_SetTables_async(cancellationToken).ConfigureAwait(false);
if (await ex.explode_SetTables_async(cancellationToken).ConfigureAwait(false) != 0)
{
throw new InvalidFormatException("ExplodeStream: invalid Huffman table data");
}
ex.explode_var_init();
return ex;
}
Expand Down
5 changes: 4 additions & 1 deletion src/SharpCompress/Compressors/Explode/ExplodeStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ HeaderFlags generalPurposeBitFlag
)
{
var ex = new ExplodeStream(inStr, compressedSize, uncompressedSize, generalPurposeBitFlag);
ex.explode_SetTables();
if (ex.explode_SetTables() != 0)
{
throw new InvalidFormatException("ExplodeStream: invalid Huffman table data");
}
ex.explode_var_init();
return ex;
}
Expand Down
5 changes: 5 additions & 0 deletions src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;

namespace SharpCompress.Compressors.LZMA.LZ;

Expand All @@ -25,6 +26,10 @@ internal partial class OutWindow : IDisposable

public void Create(int windowSize)
{
if (windowSize <= 0)
{
throw new InvalidFormatException($"LZMA: invalid dictionary size {windowSize}");
}
if (_windowSize != windowSize)
{
if (_buffer is not null)
Expand Down
Loading