Skip to content

Add Async RAR and more#996

Merged
adamhathcock merged 27 commits intomasterfrom
adam/async-rar-ai
Oct 29, 2025
Merged

Add Async RAR and more#996
adamhathcock merged 27 commits intomasterfrom
adam/async-rar-ai

Conversation

@adamhathcock
Copy link
Owner

Part of #992

Copilot AI review requested due to automatic review settings October 29, 2025 10:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@adamhathcock adamhathcock requested a review from Copilot October 29, 2025 13:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 58 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
return;
}
_isDisposed = true;
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

Duplicate assignment of _isDisposed = true. The field is already set to true on line 103, making this second assignment redundant and potentially confusing.

Suggested change
_isDisposed = true;

Copilot uses AI. Check for mistakes.
}

var NewWindow = Fragmented ? null : new byte[WinSize];
var NewWindow = Fragmented ? null : ArrayPool<byte>.Shared.Rent((int)WinSize);
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

ArrayPool.Shared.Rent() may return an array larger than requested. The code should track the actual WinSize separately and ensure only the required portion is used, or clear the entire rented array to avoid using uninitialized memory from the pool.

Suggested change
var NewWindow = Fragmented ? null : ArrayPool<byte>.Shared.Rent((int)WinSize);
var NewWindow = Fragmented ? null : ArrayPool<byte>.Shared.Rent((int)WinSize);
if (NewWindow != null)
{
// Clear only the portion of the array that will be used.
Array.Clear(NewWindow, 0, (int)WinSize);
}

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +162
var array = System.Buffers.ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
var result = await base.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
if (result != 0)
{
currentCrc = RarCRC.CheckCrc(currentCrc, buffer.Span, 0, result);
}
else if (
!disableCRC
&& GetCrc() != BitConverter.ToUInt32(readStream.CurrentCrc, 0)
&& buffer.Length != 0
)
{
// NOTE: we use the last FileHeader in a multipart volume to check CRC
throw new InvalidFormatException("file crc mismatch");
}

return result;
}
finally
{
System.Buffers.ArrayPool<byte>.Shared.Return(array);
}
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

The rented array is not used. The code rents an array but then calls base.ReadAsync(buffer, ...) with the original buffer, making the array allocation wasteful. Either use the rented array for the read operation or remove the unnecessary allocation.

Suggested change
var array = System.Buffers.ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
var result = await base.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
if (result != 0)
{
currentCrc = RarCRC.CheckCrc(currentCrc, buffer.Span, 0, result);
}
else if (
!disableCRC
&& GetCrc() != BitConverter.ToUInt32(readStream.CurrentCrc, 0)
&& buffer.Length != 0
)
{
// NOTE: we use the last FileHeader in a multipart volume to check CRC
throw new InvalidFormatException("file crc mismatch");
}
return result;
}
finally
{
System.Buffers.ArrayPool<byte>.Shared.Return(array);
}
var result = await base.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
if (result != 0)
{
currentCrc = RarCRC.CheckCrc(currentCrc, buffer.Span, 0, result);
}
else if (
!disableCRC
&& GetCrc() != BitConverter.ToUInt32(readStream.CurrentCrc, 0)
&& buffer.Length != 0
)
{
// NOTE: we use the last FileHeader in a multipart volume to check CRC
throw new InvalidFormatException("file crc mismatch");
}
return result;

Copilot uses AI. Check for mistakes.
Comment on lines +693 to +698
if (Inp.InAddr > ReadTop - 25)
{
if (!await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

These 'if' statements can be combined.

Suggested change
if (Inp.InAddr > ReadTop - 25)
{
if (!await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
if (Inp.InAddr > ReadTop - 25 && !await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;

Copilot uses AI. Check for mistakes.
Comment on lines +736 to +741
if (Inp.InAddr > ReadTop - 5)
{
if (!await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

These 'if' statements can be combined.

Suggested change
if (Inp.InAddr > ReadTop - 5)
{
if (!await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;
}
if (Inp.InAddr > ReadTop - 5 && !await UnpReadBufAsync(cancellationToken).ConfigureAwait(false))
{
return false;

Copilot uses AI. Check for mistakes.
var fltj = Filters[J];
if (
fltj.Type != FILTER_NONE
&& fltj.NextWindow == false
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

The expression 'A == false' can be simplified to '!A'.

Suggested change
&& fltj.NextWindow == false
&& !fltj.NextWindow

Copilot uses AI. Check for mistakes.
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
var entryStream = await reader.OpenEntryStreamAsync();
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

This variable is manually disposed in a finally block - consider a C# using statement as a preferable resource management technique.

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +113
RarStream stream;
if (IsRarV3)
{
stream = new RarStream(
archive.UnpackV1.Value,
FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive)
);
}
else
{
stream = new RarStream(
archive.UnpackV2017.Value,
FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive)
);
}
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better.

Suggested change
RarStream stream;
if (IsRarV3)
{
stream = new RarStream(
archive.UnpackV1.Value,
FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive)
);
}
else
{
stream = new RarStream(
archive.UnpackV2017.Value,
FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive)
);
}
RarStream stream = new RarStream(
IsRarV3 ? archive.UnpackV1.Value : archive.UnpackV2017.Value,
FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive)
);

Copilot uses AI. Check for mistakes.
@adamhathcock
Copy link
Owner Author

@copilot figure out why the windows tests fail

Copy link
Contributor

Copilot AI commented Oct 29, 2025

@adamhathcock I've opened a new pull request, #1000, to work on those changes. Once the pull request is ready, I'll request review from you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants