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
603 changes: 603 additions & 0 deletions src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.Async.cs

Large diffs are not rendered by default.

600 changes: 0 additions & 600 deletions src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.cs

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.Async.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Compressors.Rar.UnpackV1.Decode;

namespace SharpCompress.Compressors.Rar.UnpackV1;

internal partial class Unpack
{
private async Task unpack15Async(bool solid, CancellationToken cancellationToken = default)
{
if (suspended)
{
unpPtr = wrPtr;
}
else
{
UnpInitData(solid);
oldUnpInitData(solid);
await unpReadBufAsync(cancellationToken).ConfigureAwait(false);
if (!solid)
{
initHuff();
unpPtr = 0;
}
else
{
unpPtr = wrPtr;
}
--destUnpSize;
}
if (destUnpSize >= 0)
{
getFlagsBuf();
FlagsCnt = 8;
}

while (destUnpSize >= 0)
{
unpPtr &= PackDef.MAXWINMASK;

if (
inAddr > readTop - 30
&& !await unpReadBufAsync(cancellationToken).ConfigureAwait(false)
)
{
break;
}
if (((wrPtr - unpPtr) & PackDef.MAXWINMASK) < 270 && wrPtr != unpPtr)
{
oldUnpWriteBuf();
if (suspended)
{
return;
}
}
Comment on lines +49 to +56
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unpack15Async flushes using oldUnpWriteBuf() (sync Stream.Write) instead of the available async variant. This blocks the async extraction path and ignores the provided CancellationToken. Use await oldUnpWriteBufAsync(cancellationToken).ConfigureAwait(false) here.

Copilot uses AI. Check for mistakes.
if (StMode != 0)
{
huffDecode();
continue;
}

if (--FlagsCnt < 0)
{
getFlagsBuf();
FlagsCnt = 7;
}

if ((FlagBuf & 0x80) != 0)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
longLZ();
}
else
{
huffDecode();
}
}
else
{
FlagBuf <<= 1;
if (--FlagsCnt < 0)
{
getFlagsBuf();
FlagsCnt = 7;
}
if ((FlagBuf & 0x80) != 0)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
huffDecode();
}
else
{
longLZ();
}
}
else
{
FlagBuf <<= 1;
shortLZ();
}
}
}
oldUnpWriteBuf();
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unpack15Async ends with oldUnpWriteBuf() (sync write). This should be await oldUnpWriteBufAsync(cancellationToken).ConfigureAwait(false) so async extraction remains non-blocking and cancellable.

Suggested change
oldUnpWriteBuf();
await oldUnpWriteBufAsync(cancellationToken).ConfigureAwait(false);

Copilot uses AI. Check for mistakes.
}

private async Task<bool> unpReadBufAsync(CancellationToken cancellationToken = default)
{
var dataSize = readTop - inAddr;
if (dataSize < 0)
{
return false;
}
if (inAddr > MAX_SIZE / 2)
{
if (dataSize > 0)
{
Array.Copy(InBuf, inAddr, InBuf, 0, dataSize);
}
inAddr = 0;
readTop = dataSize;
}
else
{
dataSize = readTop;
}

var readCode = await readStream
.ReadAsync(InBuf, dataSize, (MAX_SIZE - dataSize) & ~0xf, cancellationToken)
.ConfigureAwait(false);
if (readCode > 0)
{
readTop += readCode;
}
readBorder = readTop - 30;
return readCode != -1;
}

private async Task oldUnpWriteBufAsync(CancellationToken cancellationToken = default)
{
if (unpPtr < wrPtr)
{
await writeStream
.WriteAsync(window, wrPtr, -wrPtr & PackDef.MAXWINMASK, cancellationToken)
.ConfigureAwait(false);
await writeStream
.WriteAsync(window, 0, unpPtr, cancellationToken)
.ConfigureAwait(false);
}
else
{
await writeStream
.WriteAsync(window, wrPtr, unpPtr - wrPtr, cancellationToken)
.ConfigureAwait(false);
}
wrPtr = unpPtr;
}
}
160 changes: 0 additions & 160 deletions src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,110 +316,6 @@ private void unpack15(bool solid)
oldUnpWriteBuf();
}

private async System.Threading.Tasks.Task unpack15Async(
bool solid,
System.Threading.CancellationToken cancellationToken = default
)
{
if (suspended)
{
unpPtr = wrPtr;
}
else
{
UnpInitData(solid);
oldUnpInitData(solid);
await unpReadBufAsync(cancellationToken).ConfigureAwait(false);
if (!solid)
{
initHuff();
unpPtr = 0;
}
else
{
unpPtr = wrPtr;
}
--destUnpSize;
}
if (destUnpSize >= 0)
{
getFlagsBuf();
FlagsCnt = 8;
}

while (destUnpSize >= 0)
{
unpPtr &= PackDef.MAXWINMASK;

if (
inAddr > readTop - 30
&& !await unpReadBufAsync(cancellationToken).ConfigureAwait(false)
)
{
break;
}
if (((wrPtr - unpPtr) & PackDef.MAXWINMASK) < 270 && wrPtr != unpPtr)
{
await oldUnpWriteBufAsync(cancellationToken).ConfigureAwait(false);
if (suspended)
{
return;
}
}
if (StMode != 0)
{
huffDecode();
continue;
}

if (--FlagsCnt < 0)
{
getFlagsBuf();
FlagsCnt = 7;
}

if ((FlagBuf & 0x80) != 0)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
longLZ();
}
else
{
huffDecode();
}
}
else
{
FlagBuf <<= 1;
if (--FlagsCnt < 0)
{
getFlagsBuf();
FlagsCnt = 7;
}
if ((FlagBuf & 0x80) != 0)
{
FlagBuf <<= 1;
if (Nlzb > Nhfb)
{
huffDecode();
}
else
{
longLZ();
}
}
else
{
FlagBuf <<= 1;
shortLZ();
}
}
}
await oldUnpWriteBufAsync(cancellationToken).ConfigureAwait(false);
}

private bool unpReadBuf()
{
var dataSize = readTop - inAddr;
Expand Down Expand Up @@ -455,40 +351,6 @@ private bool unpReadBuf()
return (readCode != -1);
}

private async System.Threading.Tasks.Task<bool> unpReadBufAsync(
System.Threading.CancellationToken cancellationToken = default
)
{
var dataSize = readTop - inAddr;
if (dataSize < 0)
{
return (false);
}
if (inAddr > MAX_SIZE / 2)
{
if (dataSize > 0)
{
Array.Copy(InBuf, inAddr, InBuf, 0, dataSize);
}
inAddr = 0;
readTop = dataSize;
}
else
{
dataSize = readTop;
}

var readCode = await readStream
.ReadAsync(InBuf, dataSize, (MAX_SIZE - dataSize) & ~0xf, cancellationToken)
.ConfigureAwait(false);
if (readCode > 0)
{
readTop += readCode;
}
readBorder = readTop - 30;
return (readCode != -1);
}

private int getShortLen1(int pos) => pos == 1 ? Buf60 + 3 : ShortLen1[pos];

private int getShortLen2(int pos) => pos == 3 ? Buf60 + 3 : ShortLen2[pos];
Expand Down Expand Up @@ -952,26 +814,4 @@ private void oldUnpWriteBuf()
}
wrPtr = unpPtr;
}

private async System.Threading.Tasks.Task oldUnpWriteBufAsync(
System.Threading.CancellationToken cancellationToken = default
)
{
if (unpPtr < wrPtr)
{
await writeStream
.WriteAsync(window, wrPtr, -wrPtr & PackDef.MAXWINMASK, cancellationToken)
.ConfigureAwait(false);
await writeStream
.WriteAsync(window, 0, unpPtr, cancellationToken)
.ConfigureAwait(false);
}
else
{
await writeStream
.WriteAsync(window, wrPtr, unpPtr - wrPtr, cancellationToken)
.ConfigureAwait(false);
}
wrPtr = unpPtr;
}
}
Loading
Loading