Fix sync methods called in async RAR unpacker paths (Unpack29Async, Unpack5Async)

Agent-Logs-Url: https://github.com/adamhathcock/sharpcompress/sessions/7f2fcb59-4a41-4b27-ab32-17afec510b5e

Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-28 06:45:49 +00:00
committed by GitHub
parent b8a075c368
commit 0e4cfef248
3 changed files with 205 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -112,7 +113,10 @@ internal sealed partial class Unpack
{
return;
}
if ((!solid || !tablesRead) && !ReadTables())
if (
(!solid || !tablesRead)
&& !await ReadTablesAsync(cancellationToken).ConfigureAwait(false)
)
{
return;
}
@@ -161,7 +165,7 @@ internal sealed partial class Unpack
var NextCh = ppm.DecodeChar();
if (NextCh == 0)
{
if (!ReadTables())
if (!await ReadTablesAsync(cancellationToken).ConfigureAwait(false))
{
break;
}
@@ -294,7 +298,7 @@ internal sealed partial class Unpack
}
if (Number == 256)
{
if (!ReadEndOfBlock())
if (!await ReadEndOfBlockAsync(cancellationToken).ConfigureAwait(false))
{
break;
}
@@ -302,7 +306,7 @@ internal sealed partial class Unpack
}
if (Number == 257)
{
if (!ReadVMCode())
if (!await ReadVMCodeAsync(cancellationToken).ConfigureAwait(false))
{
break;
}
@@ -600,4 +604,193 @@ internal sealed partial class Unpack
writtenFileSize += size;
destUnpSize -= size;
}
private async Task<bool> ReadTablesAsync(CancellationToken cancellationToken = default)
{
var bitLength = new byte[PackDef.BC];
var table = new byte[PackDef.HUFF_TABLE_SIZE];
if (inAddr > readTop - 25)
{
if (!await unpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
}
AddBits((8 - inBit) & 7);
long bitField = GetBits() & unchecked((int)0xffFFffFF);
if ((bitField & 0x8000) != 0)
{
unpBlockType = BlockTypes.BLOCK_PPM;
return ppm.DecodeInit(this, PpmEscChar);
}
unpBlockType = BlockTypes.BLOCK_LZ;
prevLowDist = 0;
lowDistRepCount = 0;
if ((bitField & 0x4000) == 0)
{
new Span<byte>(unpOldTable).Clear();
}
AddBits(2);
for (var i = 0; i < PackDef.BC; i++)
{
var length = (Utility.URShift(GetBits(), 12)) & 0xFF;
AddBits(4);
if (length == 15)
{
var zeroCount = (Utility.URShift(GetBits(), 12)) & 0xFF;
AddBits(4);
if (zeroCount == 0)
{
bitLength[i] = 15;
}
else
{
zeroCount += 2;
while (zeroCount-- > 0 && i < bitLength.Length)
{
bitLength[i++] = 0;
}
i--;
}
}
else
{
bitLength[i] = (byte)length;
}
}
UnpackUtility.makeDecodeTables(bitLength, 0, BD, PackDef.BC);
var TableSize = PackDef.HUFF_TABLE_SIZE;
for (var i = 0; i < TableSize; )
{
if (inAddr > readTop - 5)
{
if (!await unpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
}
var Number = this.decodeNumber(BD);
if (Number < 16)
{
table[i] = (byte)((Number + unpOldTable[i]) & 0xf);
i++;
}
else if (Number < 18)
{
int N;
if (Number == 16)
{
N = (Utility.URShift(GetBits(), 13)) + 3;
AddBits(3);
}
else
{
N = (Utility.URShift(GetBits(), 9)) + 11;
AddBits(7);
}
while (N-- > 0 && i < TableSize)
{
table[i] = table[i - 1];
i++;
}
}
else
{
int N;
if (Number == 18)
{
N = (Utility.URShift(GetBits(), 13)) + 3;
AddBits(3);
}
else
{
N = (Utility.URShift(GetBits(), 9)) + 11;
AddBits(7);
}
while (N-- > 0 && i < TableSize)
{
table[i++] = 0;
}
}
}
tablesRead = true;
if (inAddr > readTop)
{
return false;
}
UnpackUtility.makeDecodeTables(table, 0, LD, PackDef.NC);
UnpackUtility.makeDecodeTables(table, PackDef.NC, DD, PackDef.DC);
UnpackUtility.makeDecodeTables(table, PackDef.NC + PackDef.DC, LDD, PackDef.LDC);
UnpackUtility.makeDecodeTables(
table,
PackDef.NC + PackDef.DC + PackDef.LDC,
RD,
PackDef.RC
);
new Span<byte>(table).CopyTo(unpOldTable);
return true;
}
private async Task<bool> ReadEndOfBlockAsync(CancellationToken cancellationToken = default)
{
var BitField = GetBits();
bool NewTable,
NewFile = false;
if ((BitField & 0x8000) != 0)
{
NewTable = true;
AddBits(1);
}
else
{
NewFile = true;
NewTable = (BitField & 0x4000) != 0;
AddBits(2);
}
tablesRead = !NewTable;
return !(
NewFile || NewTable && !await ReadTablesAsync(cancellationToken).ConfigureAwait(false)
);
}
private async Task<bool> ReadVMCodeAsync(CancellationToken cancellationToken = default)
{
var FirstByte = GetBits() >> 8;
AddBits(8);
var Length = (FirstByte & 7) + 1;
if (Length == 7)
{
Length = (GetBits() >> 8) + 7;
AddBits(8);
}
else if (Length == 8)
{
Length = GetBits();
AddBits(16);
}
var vmCode = new List<byte>();
for (var I = 0; I < Length; I++)
{
if (
inAddr >= readTop - 1
&& !await unpReadBufAsync(cancellationToken).ConfigureAwait(false)
&& I < Length - 1
)
{
return false;
}
vmCode.Add((byte)(GetBits() >> 8));
AddBits(8);
}
return AddVMCode(FirstByte, vmCode);
}
}

View File

@@ -70,7 +70,7 @@ internal partial class Unpack
// So we can safefly use these tables below.
if (
!await ReadBlockHeaderAsync(cancellationToken).ConfigureAwait(false)
|| !ReadTables()
|| !await ReadTablesAsync(cancellationToken).ConfigureAwait(false)
|| !TablesRead5
)
{
@@ -101,7 +101,7 @@ internal partial class Unpack
}
if (
!await ReadBlockHeaderAsync(cancellationToken).ConfigureAwait(false)
|| !ReadTables()
|| !await ReadTablesAsync(cancellationToken).ConfigureAwait(false)
)
{
return;

View File

@@ -268,9 +268,9 @@
"net10.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[10.0.5, )",
"resolved": "10.0.5",
"contentHash": "A+5ZuQ0f449tM+MQrhf6R9ZX7lYpjk/ODEwLYKrnF6111rtARx8fVsm4YznUnQiKnnXfaXNBqgxmil6RW3L3SA=="
"requested": "[10.0.0, )",
"resolved": "10.0.0",
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
@@ -400,9 +400,9 @@
"net8.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.25, )",
"resolved": "8.0.25",
"contentHash": "sqX4nmBft05ivqKvUT4nxaN8rT3apCLt9SWFkfRrQPwra1zPwFknQAw1lleuMCKOCLvVmOWwrC2iPSm9RiXZUg=="
"requested": "[8.0.22, )",
"resolved": "8.0.22",
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",