using System.IO;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Common.Rar.Headers;
using SharpCompress.IO;
using SharpCompress.Readers;
using Xunit;
namespace SharpCompress.Test.Rar;
///
/// Summary description for RarFactoryReaderTest
///
public class RarHeaderFactoryTest : TestBase
{
private readonly RarHeaderFactory _rarHeaderFactory;
public RarHeaderFactoryTest() =>
_rarHeaderFactory = new RarHeaderFactory(
StreamingMode.Seekable,
ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = true,
}
);
[Fact]
public void Rar_ReadHeaders_RecognizeEncryptedFlag() =>
ReadEncryptedFlag("Rar.encrypted_filesAndHeader.rar", true);
[Fact]
public void Rar5_ReadHeaders_RecognizeEncryptedFlag() =>
ReadEncryptedFlag("Rar5.encrypted_filesAndHeader.rar", true);
[Fact]
public void Rar_ReadHeaders_RecognizeNoEncryptedFlag() => ReadEncryptedFlag("Rar.rar", false);
[Fact]
public void Rar5_ReadHeaders_RecognizeNoEncryptedFlag() => ReadEncryptedFlag("Rar5.rar", false);
private void ReadEncryptedFlag(string testArchive, bool isEncrypted)
{
using var stream = new FileStream(
Path.Combine(TEST_ARCHIVES_PATH, testArchive),
FileMode.Open,
FileAccess.Read
);
foreach (var header in _rarHeaderFactory.ReadHeaders(stream))
{
if (header.HeaderType == HeaderType.Archive || header.HeaderType == HeaderType.Crypt)
{
Assert.Equal(isEncrypted, _rarHeaderFactory.IsEncrypted);
break;
}
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task Rar5_ReadHeaders_WithCachedKey(bool useAsync)
{
var options = ReaderOptions.ForExternalStream.WithPassword("test");
Assert.Equal(6, await CountEncryptedFileHeaders(useAsync, options, false));
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task Rar5_ReadHeaders_RejectChangedPassword(bool useAsync)
{
var options = ReaderOptions.ForExternalStream.WithPassword("test");
await Assert.ThrowsAsync(async () =>
await CountEncryptedFileHeaders(useAsync, options, true)
);
}
private async Task CountEncryptedFileHeaders(
bool useAsync,
ReaderOptions options,
bool changePassword
)
{
using var stream = File.OpenRead(
Path.Combine(TEST_ARCHIVES_PATH, "Rar5.encrypted_filesAndHeader.rar")
);
var factory = new RarHeaderFactory(StreamingMode.Seekable, options);
var count = 0;
if (useAsync)
{
await foreach (var header in factory.ReadHeadersAsync(stream))
{
CountHeader(header);
}
}
else
{
foreach (var header in factory.ReadHeaders(stream))
{
CountHeader(header);
}
}
return count;
void CountHeader(IRarHeader header)
{
if (header.HeaderType == HeaderType.File)
{
count++;
if (changePassword)
{
options.Password = "failed";
}
}
}
}
}