Skip to content

Commit 67bd928

Browse files
authored
Merge pull request #1396 from adamhathcock/adam/fix-rar5-decompression-error
Fix RAR5 async decompression corruption in UnpWriteBufAsync
2 parents 246d968 + 2a2218b commit 67bd928

6 files changed

Lines changed: 55 additions & 57 deletions

File tree

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "10.0.301",
3+
"version": "10.0.302",
44
"rollForward": "disable"
55
}
6-
}
6+
}

src/SharpCompress/Compressors/Rar/RarCrcStream.Async.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.IO;
32
using System.Threading;
43
using System.Threading.Tasks;
54
using SharpCompress.Common;
@@ -31,16 +30,16 @@ CancellationToken cancellationToken
3130
.ConfigureAwait(false);
3231
if (result != 0)
3332
{
34-
currentCrc = RarCRC.CheckCrc(currentCrc, buffer, offset, result);
33+
_currentCrc = RarCRC.CheckCrc(_currentCrc, buffer, offset, result);
3534
}
3635
else if (
37-
!disableCRC
38-
&& GetCrc() != BitConverter.ToUInt32(readStream.NotNull().CurrentCrc.NotNull(), 0)
36+
!_disableCrc
37+
&& GetCrc() != BitConverter.ToUInt32(_readStream.NotNull().CurrentCrc.NotNull(), 0)
3938
&& count != 0
4039
)
4140
{
4241
// NOTE: we use the last FileHeader in a multipart volume to check CRC
43-
throw new InvalidFormatException("file crc mismatch");
42+
throw new InvalidFormatException("file crc mismatch: " + _key);
4443
}
4544

4645
return result;
@@ -56,16 +55,16 @@ public override async ValueTask<int> ReadAsync(
5655
var result = await base.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
5756
if (result != 0)
5857
{
59-
currentCrc = RarCRC.CheckCrc(currentCrc, buffer.Span, 0, result);
58+
_currentCrc = RarCRC.CheckCrc(_currentCrc, buffer.Span, 0, result);
6059
}
6160
else if (
62-
!disableCRC
63-
&& GetCrc() != BitConverter.ToUInt32(readStream.NotNull().CurrentCrc.NotNull(), 0)
61+
!_disableCrc
62+
&& GetCrc() != BitConverter.ToUInt32(_readStream.NotNull().CurrentCrc.NotNull(), 0)
6463
&& buffer.Length != 0
6564
)
6665
{
6766
// NOTE: we use the last FileHeader in a multipart volume to check CRC
68-
throw new InvalidFormatException("file crc mismatch");
67+
throw new InvalidFormatException("file crc mismatch: " + _key);
6968
}
7069

7170
return result;

src/SharpCompress/Compressors/Rar/RarCrcStream.cs

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
using System;
2-
using System.IO;
3-
using System.Threading;
4-
using System.Threading.Tasks;
52
using SharpCompress.Common;
63
using SharpCompress.Common.Rar.Headers;
74

85
namespace SharpCompress.Compressors.Rar;
96

107
internal partial class RarCrcStream : RarStream
118
{
12-
private readonly MultiVolumeReadOnlyStreamBase readStream;
13-
private uint currentCrc;
14-
private readonly bool disableCRC;
9+
private readonly string? _key;
10+
private readonly MultiVolumeReadOnlyStreamBase _readStream;
11+
private uint _currentCrc;
12+
private readonly bool _disableCrc;
1513

1614
private RarCrcStream(
1715
IRarUnpack unpack,
@@ -20,8 +18,9 @@ MultiVolumeReadOnlyStreamBase readStream
2018
)
2119
: base(unpack, fileHeader, readStream)
2220
{
23-
this.readStream = readStream;
24-
disableCRC = fileHeader.IsEncrypted;
21+
this._readStream = readStream;
22+
_key = fileHeader.FileName;
23+
_disableCrc = fileHeader.IsEncrypted;
2524
ResetCrc();
2625
}
2726

@@ -36,31 +35,25 @@ MultiVolumeReadOnlyStream readStream
3635
}
3736

3837
// Async methods moved to RarCrcStream.Async.cs
38+
public uint GetCrc() => ~_currentCrc;
3939

40-
protected override void Dispose(bool disposing)
41-
{
42-
base.Dispose(disposing);
43-
}
44-
45-
public uint GetCrc() => ~currentCrc;
46-
47-
public void ResetCrc() => currentCrc = 0xffffffff;
40+
public void ResetCrc() => _currentCrc = 0xffffffff;
4841

4942
public override int Read(byte[] buffer, int offset, int count)
5043
{
5144
var result = base.Read(buffer, offset, count);
5245
if (result != 0)
5346
{
54-
currentCrc = RarCRC.CheckCrc(currentCrc, buffer, offset, result);
47+
_currentCrc = RarCRC.CheckCrc(_currentCrc, buffer, offset, result);
5548
}
5649
else if (
57-
!disableCRC
58-
&& GetCrc() != BitConverter.ToUInt32(readStream.NotNull().CurrentCrc.NotNull(), 0)
50+
!_disableCrc
51+
&& GetCrc() != BitConverter.ToUInt32(_readStream.NotNull().CurrentCrc.NotNull(), 0)
5952
&& count != 0
6053
)
6154
{
6255
// NOTE: we use the last FileHeader in a multipart volume to check CRC
63-
throw new InvalidFormatException("file crc mismatch");
56+
throw new InvalidFormatException("file crc mismatch: " + _key);
6457
}
6558

6659
return result;

src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack50_async.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,28 +394,34 @@ await UnpWriteAreaAsync(WrittenBorder, BlockStart, cancellationToken)
394394
{
395395
await UnpIO_UnpWriteAsync(OutMem, 0, BlockLength, cancellationToken)
396396
.ConfigureAwait(false);
397-
WrittenFileSize += BlockLength;
398397
}
399398

399+
UnpSomeRead = true;
400+
WrittenFileSize += BlockLength;
400401
WrittenBorder = BlockEnd;
401402
WriteSizeLeft = (UnpPtr - WrittenBorder) & MaxWinMask;
402403
}
403404
}
404405
else
405406
{
406-
NotAllFiltersProcessed = true;
407+
// Current filter intersects the window write border, so we adjust
408+
// the window border to process this filter next time, not now.
409+
WrPtr = WrittenBorder;
410+
411+
// Since Filter start position can only increase, we quit processing
412+
// all following filters for this data block and reset 'NextWindow'
413+
// flag for them.
407414
for (var J = I; J < Filters.Count; J++)
408415
{
409416
var fltj = Filters[J];
410-
if (
411-
fltj.Type != FILTER_NONE
412-
&& fltj.NextWindow == false
413-
&& ((fltj.BlockStart - WrPtr) & MaxWinMask) < FullWriteSize
414-
)
417+
if (fltj.Type != FILTER_NONE)
415418
{
416-
fltj.NextWindow = true;
419+
fltj.NextWindow = false;
417420
}
418421
}
422+
423+
// Do not write data left after current filter now.
424+
NotAllFiltersProcessed = true;
419425
break;
420426
}
421427
}

src/SharpCompress/packages.lock.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,9 @@
321321
"net10.0": {
322322
"Microsoft.NET.ILLink.Tasks": {
323323
"type": "Direct",
324-
"requested": "[10.0.9, )",
325-
"resolved": "10.0.9",
326-
"contentHash": "4Iw41e2h7I4t70SJcX2GCmbyKJIlA273Cfm9RJMM050/3VBejGAG1KcthP5Z2L6SQcbfbf6BhNWO26+ZG+GzMg=="
324+
"requested": "[10.0.10, )",
325+
"resolved": "10.0.10",
326+
"contentHash": "f5VCIE7AJpd5YvzNTeMGVzQIgyE9tX+AreTYwQF+REbu+DZo/2Ae+jNSwhPEYrVz6RRkd7y8ubXjk6Nn6Ka+Cg=="
327327
},
328328
"Microsoft.NETFramework.ReferenceAssemblies": {
329329
"type": "Direct",
@@ -441,9 +441,9 @@
441441
"net8.0": {
442442
"Microsoft.NET.ILLink.Tasks": {
443443
"type": "Direct",
444-
"requested": "[8.0.28, )",
445-
"resolved": "8.0.28",
446-
"contentHash": "XMqgVjlLxLqWmEh3c49haXLQwsMNtvo6YscUaqfvEGfg1iA8hnYgkUVq3i9Zu9gKeNKMWiiZKVwZExc/qyEAsQ=="
444+
"requested": "[8.0.29, )",
445+
"resolved": "8.0.29",
446+
"contentHash": "HSBTfrkIZijz8z3ybLRKB7E8rHk4QQufFwpHa9fc5CMIgRhRzdn4mBGmlyXZqaueiMPtuJcnjresGvSTfaW8Mg=="
447447
},
448448
"Microsoft.NETFramework.ReferenceAssemblies": {
449449
"type": "Direct",

tests/SharpCompress.AotSmoke/packages.lock.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
"net10.0": {
55
"Microsoft.DotNet.ILCompiler": {
66
"type": "Direct",
7-
"requested": "[10.0.9, )",
8-
"resolved": "10.0.9",
9-
"contentHash": "4y+VsQOcs4EiTSINdCpCWi/aLRbIbGTxSezQXd8uGVhzbDRm1FNVTZDyCUQixE0+g9UFusvfxVcF68YYz7RzxA=="
7+
"requested": "[10.0.10, )",
8+
"resolved": "10.0.10",
9+
"contentHash": "tnG8ntt/Bk6odvHREnGLMo3PEiihy5iSlIFVp0JbIo00GKtNRt2k73eKZbPqR5yaJNIa3z8R86YLwbxfqpb17g=="
1010
},
1111
"Microsoft.NET.ILLink.Tasks": {
1212
"type": "Direct",
13-
"requested": "[10.0.9, )",
14-
"resolved": "10.0.9",
15-
"contentHash": "4Iw41e2h7I4t70SJcX2GCmbyKJIlA273Cfm9RJMM050/3VBejGAG1KcthP5Z2L6SQcbfbf6BhNWO26+ZG+GzMg=="
13+
"requested": "[10.0.10, )",
14+
"resolved": "10.0.10",
15+
"contentHash": "f5VCIE7AJpd5YvzNTeMGVzQIgyE9tX+AreTYwQF+REbu+DZo/2Ae+jNSwhPEYrVz6RRkd7y8ubXjk6Nn6Ka+Cg=="
1616
},
1717
"Microsoft.NETFramework.ReferenceAssemblies": {
1818
"type": "Direct",
@@ -76,17 +76,17 @@
7676
"net10.0/linux-x64": {
7777
"Microsoft.DotNet.ILCompiler": {
7878
"type": "Direct",
79-
"requested": "[10.0.9, )",
80-
"resolved": "10.0.9",
81-
"contentHash": "4y+VsQOcs4EiTSINdCpCWi/aLRbIbGTxSezQXd8uGVhzbDRm1FNVTZDyCUQixE0+g9UFusvfxVcF68YYz7RzxA==",
79+
"requested": "[10.0.10, )",
80+
"resolved": "10.0.10",
81+
"contentHash": "tnG8ntt/Bk6odvHREnGLMo3PEiihy5iSlIFVp0JbIo00GKtNRt2k73eKZbPqR5yaJNIa3z8R86YLwbxfqpb17g==",
8282
"dependencies": {
83-
"runtime.linux-x64.Microsoft.DotNet.ILCompiler": "10.0.9"
83+
"runtime.linux-x64.Microsoft.DotNet.ILCompiler": "10.0.10"
8484
}
8585
},
8686
"runtime.linux-x64.Microsoft.DotNet.ILCompiler": {
8787
"type": "Transitive",
88-
"resolved": "10.0.9",
89-
"contentHash": "45CVefG8S0eUKUJ4LBWOi8FOAgMJOP6exW9l5M9OjvQaGR7jvkokBK50XaZCsO66uLxABcuzvncV8A3YiJLUgw=="
88+
"resolved": "10.0.10",
89+
"contentHash": "WRjSRBfv6A6UjgjO8EQuLe9xqdICpkQx1hACUziCw4B2uGL+2jVhkFLq/G7rxRr3MGvqLo9B+nNdfIJ/5CYN7A=="
9090
}
9191
}
9292
}

0 commit comments

Comments
 (0)