Compare commits

...

21 Commits

Author SHA1 Message Date
Adam Hathcock
02f68b793c Mark for 0.19.2 2017-12-16 09:08:17 +00:00
Adam Hathcock
57b9133a0f Change namespace and visibility to avoid collisions (#333) 2017-12-16 09:05:21 +00:00
Adam Hathcock
815f5e09e8 Mark for 0.19.1 2017-12-15 14:46:14 +00:00
Adam Hathcock
5bdf01ee59 Absorb arraypool from CoreFX (#331) 2017-12-15 14:45:02 +00:00
Adam Hathcock
bd9417e74c Mark for 0.19 2017-12-12 11:17:57 +00:00
Adam Hathcock
694e869162 Use arraypool for transfer/skip (#326)
* Use arraypool for transfer/skip

* Merge fixes

* Remove redundant constant
2017-12-08 13:58:38 +00:00
Adam Hathcock
45845f8963 Add Circle CI build 2017-12-08 12:03:28 +00:00
Adam Hathcock
a8b6def76a Netcore2 (#302)
* Add netstandard 2.0 target and netcoreapp2.0 tests

* Update xunit

* set tests explicitly to netcore2

* update travis

* Don't say build as netcoreapp1.0

* try adding dotnet 1 too

* Remove .NET Core 1 support

* switch to circle

* update cake

* fix circle build

* try fix file ending test again

* Fix casing on files

* Another casing fix

* Add back netstandard1.0

* Finish adding netstandard 1.0 back

* Add netstandard1.3 back
2017-12-08 12:00:29 +00:00
Sors
a4ebd5fb3d Rar 5 format (#310)
Fix rar 5 format comment
2017-12-04 18:59:49 +00:00
Adam Hathcock
3da3b212fa create new memorystream to allow proper resizing as memorystream could be a user provided buffer. Update xunit (#307) 2017-12-04 18:48:38 +00:00
Martijn Kant
c2528cf93e Mk/add support for extracting password protected LZMA(2) 7z archives (#324)
* Added possibility to decompress a password protected 7z LZMA archive

* Fix tests
2017-12-04 10:55:30 +00:00
coderb
550fecd4d3 bugfix: eliminate spurious rar crc exception when Read() is called with count = 0 (#313) 2017-10-23 11:58:02 +01:00
Adam Hathcock
50b01428b4 Mark for 0.18.2 2017-09-22 09:16:42 +01:00
Thritton
bb59f28b22 Update ArchiveReader.cs (#303)
#227
Added check if argument is in range in method TranslateTime(long? time)
2017-09-19 15:25:10 +01:00
François
7064cda6de Zlib: fix Adler32 implementation (#301) 2017-09-17 22:21:09 +01:00
Adam Hathcock
525c1873e8 Fix merge 2017-09-17 22:16:57 +01:00
François
3d91b4eb5e XZ: fix padding issues (#300)
* XZ: fix variable-length integers decoding

* XZ: fix block and index padding issues

* cleanup in XZStreamTests
2017-09-17 22:14:23 +01:00
François
f20c03180e XZ: fix variable-length integers decoding (#299) 2017-09-17 22:05:20 +01:00
Vladimir Kozlov
08fee76b4e Fixes Double Dispose() of ZipWritingStream #294 https://github.com/adamhathcock/sharpcompress/issues/294 (#295) 2017-09-08 13:25:53 +01:00
Adam Hathcock
0f511c4b2a Mark for 0.18.1 2017-08-17 11:43:34 +01:00
twirpx
42d9dfd117 Fixed bug: Passing default ReaderOptions when creating ZipReader for solid extraction (#287) 2017-08-16 08:19:23 +01:00
44 changed files with 920 additions and 212 deletions

11
.circleci/config.yml Normal file
View File

@@ -0,0 +1,11 @@
version: 2
jobs:
build:
docker:
- image: adamhathcock/cake-build:latest
steps:
- checkout
- run:
name: Build
command: ./build.sh

2
.gitattributes vendored
View File

@@ -2,4 +2,4 @@
* text=auto
# need original files to be windows
test/TestArchives/Original/*.txt eol=crlf
*.txt text eol=crlf

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ tests/TestArchives/Scratch
.vs
tools
.vscode
.idea/

View File

@@ -1,13 +0,0 @@
dist: trusty
language: csharp
cache:
directories:
- $HOME/.dotnet
solution: SharpCompress.sln
matrix:
include:
- dotnet: 1.0.4
mono: none
env: DOTNETCORE=1
script:
- ./build.sh

View File

@@ -7,8 +7,8 @@ The major feature is support for non-seekable streams so large files can be proc
AppVeyor Build -
[![Build status](https://ci.appveyor.com/api/projects/status/voxg971oemmvxh1e/branch/master?svg=true)](https://ci.appveyor.com/project/adamhathcock/sharpcompress/branch/master)
Travis CI Build -
[![Build Status](https://travis-ci.org/adamhathcock/sharpcompress.svg?branch=master)](https://travis-ci.org/adamhathcock/sharpcompress)
Circle CI Build -
[![CircleCI](https://circleci.com/gh/adamhathcock/sharpcompress.svg?style=svg)](https://circleci.com/gh/adamhathcock/sharpcompress)
## Need Help?
Post Issues on Github!

View File

@@ -114,6 +114,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=NAMESPACE_005FALIAS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -30,8 +30,11 @@ Task("Build")
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
settings.Framework = "netcoreapp1.1";
DotNetCoreBuild("./tests/SharpCompress.Test/SharpCompress.Test.csproj", settings);
settings.Framework = "netstandard1.3";
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
settings.Framework = "netstandard2.0";
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
}
});
@@ -39,23 +42,25 @@ Task("Test")
.IsDependentOn("Build")
.Does(() =>
{
if (!bool.Parse(EnvironmentVariable("APPVEYOR") ?? "false")
&& !bool.Parse(EnvironmentVariable("TRAVIS") ?? "false"))
var files = GetFiles("tests/**/*.csproj");
foreach(var file in files)
{
var files = GetFiles("tests/**/*.csproj");
foreach(var file in files)
var settings = new DotNetCoreTestSettings
{
var settings = new DotNetCoreTestSettings
{
Configuration = "Release"
};
Configuration = "Release",
Framework = "netcoreapp2.0"
};
DotNetCoreTest(file.ToString(), settings);
}
}
else
{
Information("Skipping tests as this is AppVeyor or Travis CI");
DotNetCoreTest(file.ToString(), settings);
settings = new DotNetCoreTestSettings
{
Configuration = "Release",
Framework = "netcoreapp1.1"
};
DotNetCoreTest(file.ToString(), settings);
}
});

View File

@@ -8,7 +8,7 @@
# Define directories.
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TOOLS_DIR=$SCRIPT_DIR/tools
CAKE_VERSION=0.19.1
CAKE_VERSION=0.23.0
CAKE_DLL=$TOOLS_DIR/Cake.CoreCLR.$CAKE_VERSION/Cake.dll
# Make sure the tools folder exist.

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using SharpCompress.Common;
using SharpCompress.Common.SevenZip;
using SharpCompress.Compressors.LZMA.Utilites;
using SharpCompress.IO;
using SharpCompress.Readers;
@@ -117,7 +118,7 @@ namespace SharpCompress.Archives.SevenZip
stream.Position = 0;
var reader = new ArchiveReader();
reader.Open(stream);
database = reader.ReadDatabase(null);
database = reader.ReadDatabase(new PasswordProvider(ReaderOptions.Password));
}
}
@@ -144,7 +145,7 @@ namespace SharpCompress.Archives.SevenZip
protected override IReader CreateReaderForSolidExtraction()
{
return new SevenZipReader(this);
return new SevenZipReader(ReaderOptions, this);
}
public override bool IsSolid { get { return Entries.Where(x => !x.IsDirectory).GroupBy(x => x.FilePart.Folder).Count() > 1; } }
@@ -165,8 +166,8 @@ namespace SharpCompress.Archives.SevenZip
private Stream currentStream;
private CFileItem currentItem;
internal SevenZipReader(SevenZipArchive archive)
: base(new ReaderOptions(), ArchiveType.SevenZip)
internal SevenZipReader(ReaderOptions readerOptions, SevenZipArchive archive)
: base(readerOptions, ArchiveType.SevenZip)
{
this.archive = archive;
}
@@ -190,7 +191,7 @@ namespace SharpCompress.Archives.SevenZip
}
else
{
currentStream = archive.database.GetFolderStream(stream, currentFolder, null);
currentStream = archive.database.GetFolderStream(stream, currentFolder, new PasswordProvider(Options.Password));
}
foreach (var entry in group)
{
@@ -205,5 +206,21 @@ namespace SharpCompress.Archives.SevenZip
return CreateEntryStream(new ReadOnlySubStream(currentStream, currentItem.Size));
}
}
private class PasswordProvider : IPasswordProvider
{
private readonly string _password;
public PasswordProvider(string password)
{
_password = password;
}
public string CryptoGetTextPassword()
{
return _password;
}
}
}
}

View File

@@ -208,7 +208,7 @@ namespace SharpCompress.Archives.Zip
{
var stream = Volumes.Single().Stream;
stream.Position = 0;
return ZipReader.Open(stream);
return ZipReader.Open(stream, ReaderOptions);
}
}
}

View File

@@ -0,0 +1,119 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System.Runtime.CompilerServices;
using System.Threading;
namespace SharpCompress.Buffers
{
/// <summary>
/// Provides a resource pool that enables reusing instances of type <see cref="T:T[]"/>.
/// </summary>
/// <remarks>
/// <para>
/// Renting and returning buffers with an <see cref="ArrayPool{T}"/> can increase performance
/// in situations where arrays are created and destroyed frequently, resulting in significant
/// memory pressure on the garbage collector.
/// </para>
/// <para>
/// This class is thread-safe. All members may be used by multiple threads concurrently.
/// </para>
/// </remarks>
internal abstract class ArrayPool<T>
{
/// <summary>The lazily-initialized shared pool instance.</summary>
private static ArrayPool<T> s_sharedInstance = null;
/// <summary>
/// Retrieves a shared <see cref="ArrayPool{T}"/> instance.
/// </summary>
/// <remarks>
/// The shared pool provides a default implementation of <see cref="ArrayPool{T}"/>
/// that's intended for general applicability. It maintains arrays of multiple sizes, and
/// may hand back a larger array than was actually requested, but will never hand back a smaller
/// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
/// existing buffer being taken from the pool if an appropriate buffer is available or in a new
/// buffer being allocated if one is not available.
/// </remarks>
public static ArrayPool<T> Shared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated(); }
}
/// <summary>Ensures that <see cref="s_sharedInstance"/> has been initialized to a pool and returns it.</summary>
[MethodImpl(MethodImplOptions.NoInlining)]
private static ArrayPool<T> EnsureSharedCreated()
{
Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
return s_sharedInstance;
}
/// <summary>
/// Creates a new <see cref="ArrayPool{T}"/> instance using default configuration options.
/// </summary>
/// <returns>A new <see cref="ArrayPool{T}"/> instance.</returns>
public static ArrayPool<T> Create()
{
return new DefaultArrayPool<T>();
}
/// <summary>
/// Creates a new <see cref="ArrayPool{T}"/> instance using custom configuration options.
/// </summary>
/// <param name="maxArrayLength">The maximum length of array instances that may be stored in the pool.</param>
/// <param name="maxArraysPerBucket">
/// The maximum number of array instances that may be stored in each bucket in the pool. The pool
/// groups arrays of similar lengths into buckets for faster access.
/// </param>
/// <returns>A new <see cref="ArrayPool{T}"/> instance with the specified configuration options.</returns>
/// <remarks>
/// The created pool will group arrays into buckets, with no more than <paramref name="maxArraysPerBucket"/>
/// in each bucket and with those arrays not exceeding <paramref name="maxArrayLength"/> in length.
/// </remarks>
public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
{
return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
}
/// <summary>
/// Retrieves a buffer that is at least the requested length.
/// </summary>
/// <param name="minimumLength">The minimum length of the array needed.</param>
/// <returns>
/// An <see cref="T:T[]"/> that is at least <paramref name="minimumLength"/> in length.
/// </returns>
/// <remarks>
/// This buffer is loaned to the caller and should be returned to the same pool via
/// <see cref="Return"/> so that it may be reused in subsequent usage of <see cref="Rent"/>.
/// It is not a fatal error to not return a rented buffer, but failure to do so may lead to
/// decreased application performance, as the pool may need to create a new buffer to replace
/// the one lost.
/// </remarks>
public abstract T[] Rent(int minimumLength);
/// <summary>
/// Returns to the pool an array that was previously obtained via <see cref="Rent"/> on the same
/// <see cref="ArrayPool{T}"/> instance.
/// </summary>
/// <param name="array">
/// The buffer previously obtained from <see cref="Rent"/> to return to the pool.
/// </param>
/// <param name="clearArray">
/// If <c>true</c> and if the pool will store the buffer to enable subsequent reuse, <see cref="Return"/>
/// will clear <paramref name="array"/> of its contents so that a subsequent consumer via <see cref="Rent"/>
/// will not see the previous consumer's content. If <c>false</c> or if the pool will release the buffer,
/// the array's contents are left unchanged.
/// </param>
/// <remarks>
/// Once a buffer has been returned to the pool, the caller gives up all ownership of the buffer
/// and must not use it. The reference returned from a given call to <see cref="Rent"/> must only be
/// returned via <see cref="Return"/> once. The default <see cref="ArrayPool{T}"/>
/// may hold onto the returned buffer in order to rent it again, or it may release the returned buffer
/// if it's determined that the pool already has enough buffers stored.
/// </remarks>
public abstract void Return(T[] array, bool clearArray = false);
}
}
#endif

View File

@@ -0,0 +1,144 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System;
namespace SharpCompress.Buffers
{
internal sealed partial class DefaultArrayPool<T> : ArrayPool<T>
{
/// <summary>The default maximum length of each array in the pool (2^20).</summary>
private const int DefaultMaxArrayLength = 1024 * 1024;
/// <summary>The default maximum number of arrays per bucket that are available for rent.</summary>
private const int DefaultMaxNumberOfArraysPerBucket = 50;
/// <summary>Lazily-allocated empty array used when arrays of length 0 are requested.</summary>
private static T[] s_emptyArray; // we support contracts earlier than those with Array.Empty<T>()
private readonly Bucket[] _buckets;
internal DefaultArrayPool() : this(DefaultMaxArrayLength, DefaultMaxNumberOfArraysPerBucket)
{
}
internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
{
if (maxArrayLength <= 0)
{
throw new ArgumentOutOfRangeException(nameof(maxArrayLength));
}
if (maxArraysPerBucket <= 0)
{
throw new ArgumentOutOfRangeException(nameof(maxArraysPerBucket));
}
// Our bucketing algorithm has a min length of 2^4 and a max length of 2^30.
// Constrain the actual max used to those values.
const int MinimumArrayLength = 0x10, MaximumArrayLength = 0x40000000;
if (maxArrayLength > MaximumArrayLength)
{
maxArrayLength = MaximumArrayLength;
}
else if (maxArrayLength < MinimumArrayLength)
{
maxArrayLength = MinimumArrayLength;
}
// Create the buckets.
int poolId = Id;
int maxBuckets = Utilities.SelectBucketIndex(maxArrayLength);
var buckets = new Bucket[maxBuckets + 1];
for (int i = 0; i < buckets.Length; i++)
{
buckets[i] = new Bucket(Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
}
_buckets = buckets;
}
/// <summary>Gets an ID for the pool to use with events.</summary>
private int Id => GetHashCode();
public override T[] Rent(int minimumLength)
{
// Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though
// pooling such an array isn't valuable) as it's a valid length array, and we want the pool
// to be usable in general instead of using `new`, even for computed lengths.
if (minimumLength < 0)
{
throw new ArgumentOutOfRangeException(nameof(minimumLength));
}
else if (minimumLength == 0)
{
// No need for events with the empty array. Our pool is effectively infinite
// and we'll never allocate for rents and never store for returns.
return s_emptyArray ?? (s_emptyArray = new T[0]);
}
T[] buffer = null;
int index = Utilities.SelectBucketIndex(minimumLength);
if (index < _buckets.Length)
{
// Search for an array starting at the 'index' bucket. If the bucket is empty, bump up to the
// next higher bucket and try that one, but only try at most a few buckets.
const int MaxBucketsToTry = 2;
int i = index;
do
{
// Attempt to rent from the bucket. If we get a buffer from it, return it.
buffer = _buckets[i].Rent();
if (buffer != null)
{
return buffer;
}
}
while (++i < _buckets.Length && i != index + MaxBucketsToTry);
// The pool was exhausted for this buffer size. Allocate a new buffer with a size corresponding
// to the appropriate bucket.
buffer = new T[_buckets[index]._bufferLength];
}
else
{
// The request was for a size too large for the pool. Allocate an array of exactly the requested length.
// When it's returned to the pool, we'll simply throw it away.
buffer = new T[minimumLength];
}
return buffer;
}
public override void Return(T[] array, bool clearArray = false)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array));
}
else if (array.Length == 0)
{
// Ignore empty arrays. When a zero-length array is rented, we return a singleton
// rather than actually taking a buffer out of the lowest bucket.
return;
}
// Determine with what bucket this array length is associated
int bucket = Utilities.SelectBucketIndex(array.Length);
// If we can tell that the buffer was allocated, drop it. Otherwise, check if we have space in the pool
if (bucket < _buckets.Length)
{
// Clear the array if the user requests
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
// Return the buffer to its bucket. In the future, we might consider having Return return false
// instead of dropping a bucket, in which case we could try to return to a lower-sized bucket,
// just as how in Rent we allow renting from a higher-sized bucket.
_buckets[bucket].Return(array);
}
}
}
}
#endif

View File

@@ -0,0 +1,111 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System;
using System.Diagnostics;
using System.Threading;
namespace SharpCompress.Buffers
{
internal sealed partial class DefaultArrayPool<T> : ArrayPool<T>
{
/// <summary>Provides a thread-safe bucket containing buffers that can be Rent'd and Return'd.</summary>
private sealed class Bucket
{
internal readonly int _bufferLength;
private readonly T[][] _buffers;
private readonly int _poolId;
private SpinLock _lock; // do not make this readonly; it's a mutable struct
private int _index;
/// <summary>
/// Creates the pool with numberOfBuffers arrays where each buffer is of bufferLength length.
/// </summary>
internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
{
_lock = new SpinLock(Debugger.IsAttached); // only enable thread tracking if debugger is attached; it adds non-trivial overheads to Enter/Exit
_buffers = new T[numberOfBuffers][];
_bufferLength = bufferLength;
_poolId = poolId;
}
/// <summary>Gets an ID for the bucket to use with events.</summary>
internal int Id => GetHashCode();
/// <summary>Takes an array from the bucket. If the bucket is empty, returns null.</summary>
internal T[] Rent()
{
T[][] buffers = _buffers;
T[] buffer = null;
// While holding the lock, grab whatever is at the next available index and
// update the index. We do as little work as possible while holding the spin
// lock to minimize contention with other threads. The try/finally is
// necessary to properly handle thread aborts on platforms which have them.
bool lockTaken = false, allocateBuffer = false;
try
{
_lock.Enter(ref lockTaken);
if (_index < buffers.Length)
{
buffer = buffers[_index];
buffers[_index++] = null;
allocateBuffer = buffer == null;
}
}
finally
{
if (lockTaken) _lock.Exit(false);
}
// While we were holding the lock, we grabbed whatever was at the next available index, if
// there was one. If we tried and if we got back null, that means we hadn't yet allocated
// for that slot, in which case we should do so now.
if (allocateBuffer)
{
buffer = new T[_bufferLength];
}
return buffer;
}
/// <summary>
/// Attempts to return the buffer to the bucket. If successful, the buffer will be stored
/// in the bucket and true will be returned; otherwise, the buffer won't be stored, and false
/// will be returned.
/// </summary>
internal void Return(T[] array)
{
// Check to see if the buffer is the correct size for this bucket
if (array.Length != _bufferLength)
{
throw new ArgumentException("Buffer not from pool", nameof(array));
}
// While holding the spin lock, if there's room available in the bucket,
// put the buffer into the next available slot. Otherwise, we just drop it.
// The try/finally is necessary to properly handle thread aborts on platforms
// which have them.
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
if (_index != 0)
{
_buffers[--_index] = array;
}
}
finally
{
if (lockTaken) _lock.Exit(false);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace SharpCompress.Buffers
{
internal static class Utilities
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int SelectBucketIndex(int bufferSize)
{
Debug.Assert(bufferSize > 0);
uint bitsRemaining = ((uint)bufferSize - 1) >> 4;
int poolIndex = 0;
if (bitsRemaining > 0xFFFF) { bitsRemaining >>= 16; poolIndex = 16; }
if (bitsRemaining > 0xFF) { bitsRemaining >>= 8; poolIndex += 8; }
if (bitsRemaining > 0xF) { bitsRemaining >>= 4; poolIndex += 4; }
if (bitsRemaining > 0x3) { bitsRemaining >>= 2; poolIndex += 2; }
if (bitsRemaining > 0x1) { bitsRemaining >>= 1; poolIndex += 1; }
return poolIndex + (int)bitsRemaining;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int GetMaxSizeForBucket(int binIndex)
{
int maxSize = 16 << binIndex;
Debug.Assert(maxSize >= 0);
return maxSize;
}
}
}
#endif

View File

@@ -18,9 +18,9 @@ namespace SharpCompress.Common.Rar.Headers
Flags == 0x1A21 &&
HeaderSize == 0x07;
// Rar5 signature: 52 61 72 21 1A 07 10 00 (not supported yet)
// Rar5 signature: 52 61 72 21 1A 07 01 00 (not supported yet)
}
internal bool OldFormat { get; private set; }
}
}
}

View File

@@ -22,6 +22,13 @@ namespace SharpCompress.Common.SevenZip
internal List<long> PackStreamStartPositions = new List<long>();
internal List<int> FolderStartFileIndex = new List<int>();
internal List<int> FileIndexToFolderIndexMap = new List<int>();
internal IPasswordProvider PasswordProvider { get; }
public ArchiveDatabase(IPasswordProvider passwordProvider)
{
PasswordProvider = passwordProvider;
}
internal void Clear()
{

View File

@@ -182,7 +182,7 @@ namespace SharpCompress.Common.SevenZip
private DateTime? TranslateTime(long? time)
{
if (time.HasValue)
if (time.HasValue && time.Value >= 0 && time.Value <= 2650467743999999999) //maximum Windows file time 31.12.9999
{
return TranslateTime(time.Value);
}
@@ -1211,7 +1211,7 @@ namespace SharpCompress.Common.SevenZip
public ArchiveDatabase ReadDatabase(IPasswordProvider pass)
{
var db = new ArchiveDatabase();
var db = new ArchiveDatabase(pass);
db.Clear();
db.MajorVersion = _header[6];
@@ -1279,7 +1279,7 @@ namespace SharpCompress.Common.SevenZip
throw new InvalidOperationException();
}
var dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, pass);
var dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, db.PasswordProvider);
// compressed header without content is odd but ok
if (dataVector.Count == 0)
@@ -1301,7 +1301,7 @@ namespace SharpCompress.Common.SevenZip
}
}
ReadHeader(db, pass);
ReadHeader(db, db.PasswordProvider);
}
db.Fill();
return db;
@@ -1441,7 +1441,7 @@ namespace SharpCompress.Common.SevenZip
#endregion
}
private Stream GetCachedDecoderStream(ArchiveDatabase _db, int folderIndex, IPasswordProvider pw)
private Stream GetCachedDecoderStream(ArchiveDatabase _db, int folderIndex)
{
Stream s;
if (!_cachedStreams.TryGetValue(folderIndex, out s))
@@ -1456,13 +1456,13 @@ namespace SharpCompress.Common.SevenZip
}
s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes.ToArray(), folderInfo,
pw);
_db.PasswordProvider);
_cachedStreams.Add(folderIndex, s);
}
return s;
}
public Stream OpenStream(ArchiveDatabase _db, int fileIndex, IPasswordProvider pw)
public Stream OpenStream(ArchiveDatabase _db, int fileIndex)
{
int folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
int numFilesInFolder = _db.NumUnpackStreamsVector[folderIndex];
@@ -1479,12 +1479,12 @@ namespace SharpCompress.Common.SevenZip
skipSize += _db.Files[firstFileIndex + i].Size;
}
Stream s = GetCachedDecoderStream(_db, folderIndex, pw);
Stream s = GetCachedDecoderStream(_db, folderIndex);
s.Position = skipSize;
return new ReadOnlySubStream(s, _db.Files[fileIndex].Size);
}
public void Extract(ArchiveDatabase _db, int[] indices, IPasswordProvider pw)
public void Extract(ArchiveDatabase _db, int[] indices)
{
int numItems;
bool allFilesMode = (indices == null);
@@ -1562,7 +1562,7 @@ namespace SharpCompress.Common.SevenZip
// TODO: If the decoding fails the last file may be extracted incompletely. Delete it?
Stream s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes.ToArray(),
folderInfo, pw);
folderInfo, _db.PasswordProvider);
byte[] buffer = new byte[4 << 10];
for (;;)
{
@@ -1588,4 +1588,4 @@ namespace SharpCompress.Common.SevenZip
#endregion
}
}
}

View File

@@ -42,7 +42,7 @@ namespace SharpCompress.Common.SevenZip
{
return null;
}
var folderStream = _database.GetFolderStream(_stream, Folder, null);
var folderStream = _database.GetFolderStream(_stream, Folder, _database.PasswordProvider);
int firstFileIndex = _database.FolderStartFileIndex[_database.Folders.IndexOf(Folder)];
int skipCount = Index - firstFileIndex;

View File

@@ -418,7 +418,7 @@ namespace SharpCompress.Compressors.Deflate
internal sealed class Adler
{
// largest prime smaller than 65536
private static readonly int BASE = 65521;
private static readonly uint BASE = 65521U;
// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
private static readonly int NMAX = 5552;
@@ -430,8 +430,8 @@ namespace SharpCompress.Compressors.Deflate
return 1;
}
int s1 = (int)(adler & 0xffff);
int s2 = (int)((adler >> 16) & 0xffff);
uint s1 = adler & 0xffffU;
uint s2 = (adler >> 16) & 0xffffU;
while (len > 0)
{
@@ -486,7 +486,7 @@ namespace SharpCompress.Compressors.Deflate
s1 %= BASE;
s2 %= BASE;
}
return (uint)((s2 << 16) | s1);
return (s2 << 16) | s1;
}
}
}

View File

@@ -31,7 +31,7 @@ namespace SharpCompress.Compressors.Rar {
{
currentCrc = RarCRC.CheckCrc(currentCrc, buffer, offset, result);
}
else if (GetCrc() != readStream.CurrentCrc)
else if (GetCrc() != readStream.CurrentCrc && count != 0)
{
// NOTE: we use the last FileHeader in a multipart volume to check CRC
throw new InvalidFormatException("file crc mismatch");

View File

@@ -18,7 +18,7 @@ namespace SharpCompress.Compressors.Xz
int i = 0;
while ((LastByte & 0x80) != 0)
{
if (i >= MaxBytes)
if (++i >= MaxBytes)
throw new InvalidDataException();
LastByte = reader.ReadByte();
if (LastByte == 0)

View File

@@ -50,11 +50,11 @@ namespace SharpCompress.Compressors.Xz
private void SkipPadding()
{
int padding = (int)(_bytesRead % 4);
if (padding > 0)
int bytes = (int)(BaseStream.Position % 4);
if (bytes > 0)
{
byte[] paddingBytes = new byte[padding];
BaseStream.Read(paddingBytes, 0, padding);
byte[] paddingBytes = new byte[4 - bytes];
BaseStream.Read(paddingBytes, 0, paddingBytes.Length);
if (paddingBytes.Any(b => b != 0))
throw new InvalidDataException("Padding bytes were non-null");
}

View File

@@ -55,10 +55,10 @@ namespace SharpCompress.Compressors.Xz
private void SkipPadding()
{
int padding = (int)(_reader.BaseStream.Position - StreamStartPosition) % 4;
if (padding > 0)
int bytes = (int)(_reader.BaseStream.Position - StreamStartPosition) % 4;
if (bytes > 0)
{
byte[] paddingBytes = _reader.ReadBytes(padding);
byte[] paddingBytes = _reader.ReadBytes(4 - bytes);
if (paddingBytes.Any(b => b != 0))
throw new InvalidDataException("Padding bytes were non-null");
}

View File

@@ -41,7 +41,7 @@ namespace SharpCompress.IO
throw new NotSupportedException();
}
public override long Length => throw new NotSupportedException();
public override long Length => BytesLeftToRead;
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using SharpCompress.Compressors.Filters;
namespace SharpCompress.IO
{
@@ -46,8 +47,13 @@ namespace SharpCompress.IO
}
else
{
bufferStream.TransferTo(buffer);
bufferStream = buffer;
//create new memorystream to allow proper resizing as memorystream could be a user provided buffer
//https://github.com/adamhathcock/sharpcompress/issues/306
bufferStream = new MemoryStream();
buffer.Position = 0;
buffer.TransferTo(bufferStream);
bufferStream.Position = 0;
}
isRewound = true;

View File

@@ -2,12 +2,11 @@
<PropertyGroup>
<AssemblyTitle>SharpCompress - Pure C# Decompression/Compression</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.18</VersionPrefix>
<AssemblyVersion>0.18.0.0</AssemblyVersion>
<FileVersion>0.18.0.0</FileVersion>
<VersionPrefix>0.19.2</VersionPrefix>
<AssemblyVersion>0.19.2.0</AssemblyVersion>
<FileVersion>0.19.2.0</FileVersion>
<Authors>Adam Hathcock</Authors>
<TargetFrameworks Condition="'$(LibraryFrameworks)'==''">net45;net35;netstandard1.0;netstandard1.3</TargetFrameworks>
<TargetFrameworks Condition="'$(LibraryFrameworks)'!=''">$(LibraryFrameworks)</TargetFrameworks>
<TargetFrameworks Condition="'$(LibraryFrameworks)'==''">net45;net35;netstandard1.0;netstandard1.3;netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>SharpCompress</AssemblyName>
@@ -25,4 +24,10 @@
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.0' ">
<DefineConstants>$(DefineConstants);NO_FILE;NO_CRYPTO;SILVERLIGHT</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -2,12 +2,15 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
#if NETCORE
using SharpCompress.Buffers;
#endif
using SharpCompress.Readers;
namespace SharpCompress
{
internal static class Utility
{
{
public static ReadOnlyCollection<T> ToReadOnly<T>(this IEnumerable<T> items)
{
return new ReadOnlyCollection<T>(items.ToList());
@@ -139,36 +142,54 @@ namespace SharpCompress
public static void Skip(this Stream source, long advanceAmount)
{
byte[] buffer = GetTransferByteArray();
int read = 0;
int readCount = 0;
do
try
{
readCount = buffer.Length;
if (readCount > advanceAmount)
int read = 0;
int readCount = 0;
do
{
readCount = (int)advanceAmount;
}
read = source.Read(buffer, 0, readCount);
if (read <= 0)
{
break;
}
advanceAmount -= read;
if (advanceAmount == 0)
{
break;
readCount = buffer.Length;
if (readCount > advanceAmount)
{
readCount = (int)advanceAmount;
}
read = source.Read(buffer, 0, readCount);
if (read <= 0)
{
break;
}
advanceAmount -= read;
if (advanceAmount == 0)
{
break;
}
}
while (true);
}
finally
{
#if NETCORE
ArrayPool<byte>.Shared.Return(buffer);
#endif
}
while (true);
}
public static void Skip(this Stream source)
{
byte[] buffer = GetTransferByteArray();
do
try
{
do
{
}
while (source.Read(buffer, 0, buffer.Length) == buffer.Length);
}
finally
{
#if NETCORE
ArrayPool<byte>.Shared.Return(buffer);
#endif
}
while (source.Read(buffer, 0, buffer.Length) == buffer.Length);
}
public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime)
@@ -233,30 +254,48 @@ namespace SharpCompress
public static long TransferTo(this Stream source, Stream destination)
{
byte[] array = GetTransferByteArray();
int count;
long total = 0;
while (ReadTransferBlock(source, array, out count))
try
{
total += count;
destination.Write(array, 0, count);
int count;
long total = 0;
while (ReadTransferBlock(source, array, out count))
{
total += count;
destination.Write(array, 0, count);
}
return total;
}
finally
{
#if NETCORE
ArrayPool<byte>.Shared.Return(array);
#endif
}
return total;
}
public static long TransferTo(this Stream source, Stream destination, Common.Entry entry, IReaderExtractionListener readerExtractionListener)
{
byte[] array = GetTransferByteArray();
int count;
var iterations = 0;
long total = 0;
while (ReadTransferBlock(source, array, out count))
try
{
total += count;
destination.Write(array, 0, count);
iterations++;
readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations);
int count;
var iterations = 0;
long total = 0;
while (ReadTransferBlock(source, array, out count))
{
total += count;
destination.Write(array, 0, count);
iterations++;
readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations);
}
return total;
}
finally
{
#if NETCORE
ArrayPool<byte>.Shared.Return(array);
#endif
}
return total;
}
private static bool ReadTransferBlock(Stream source, byte[] array, out int count)
@@ -266,7 +305,11 @@ namespace SharpCompress
private static byte[] GetTransferByteArray()
{
#if NETCORE
return ArrayPool<byte>.Shared.Rent(81920);
#else
return new byte[81920];
#endif
}
public static bool ReadFully(this Stream stream, byte[] buffer)

View File

@@ -276,6 +276,7 @@ namespace SharpCompress.Writers.Zip
// Flag to prevent throwing exceptions on Dispose
private bool limitsExceeded;
private bool isDisposed;
internal ZipWritingStream(ZipWriter writer, Stream originalStream, ZipCentralDirectoryEntry entry,
ZipCompressionMethod zipCompressionMethod, CompressionLevel compressionLevel)
@@ -344,6 +345,13 @@ namespace SharpCompress.Writers.Zip
protected override void Dispose(bool disposing)
{
if (isDisposed)
{
return;
}
isDisposed = true;
base.Dispose(disposing);
if (disposing)
{

View File

@@ -40,7 +40,7 @@ namespace SharpCompress.Test
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
entry.WriteToDirectory(SCRATCH_FILES_PATH,
new ExtractionOptions()
new ExtractionOptions
{
ExtractFullPath = true,
Overwrite = true
@@ -51,24 +51,24 @@ namespace SharpCompress.Test
}
}
protected void ArchiveStreamRead(string testArchive)
protected void ArchiveStreamRead(string testArchive, ReaderOptions readerOptions = null)
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
ArchiveStreamRead(testArchive.AsEnumerable());
ArchiveStreamRead(readerOptions, testArchive.AsEnumerable());
}
protected void ArchiveStreamRead(params string[] testArchives)
protected void ArchiveStreamRead(ReaderOptions readerOptions = null, params string[] testArchives)
{
ArchiveStreamRead(testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x)));
ArchiveStreamRead(readerOptions, testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x)));
}
protected void ArchiveStreamRead(IEnumerable<string> testArchives)
protected void ArchiveStreamRead(ReaderOptions readerOptions, IEnumerable<string> testArchives)
{
foreach (var path in testArchives)
{
ResetScratch();
using (Stream stream = File.OpenRead(path))
using (var archive = ArchiveFactory.Open(stream))
using (var archive = ArchiveFactory.Open(stream, readerOptions))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
@@ -83,17 +83,17 @@ namespace SharpCompress.Test
}
}
protected void ArchiveFileRead(string testArchive)
protected void ArchiveFileRead(string testArchive, ReaderOptions readerOptions = null)
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
ArchiveFileRead(testArchive.AsEnumerable());
ArchiveFileRead(testArchive.AsEnumerable(), readerOptions);
}
protected void ArchiveFileRead(IEnumerable<string> testArchives)
protected void ArchiveFileRead(IEnumerable<string> testArchives, ReaderOptions readerOptions = null)
{
foreach (var path in testArchives)
{
ResetScratch();
using (var archive = ArchiveFactory.Open(path))
using (var archive = ArchiveFactory.Open(path, readerOptions))
{
//archive.EntryExtractionBegin += archive_EntryExtractionBegin;
//archive.FilePartExtractionBegin += archive_FilePartExtractionBegin;

View File

@@ -35,10 +35,10 @@ namespace SharpCompress.Test.Rar
ResetScratch();
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, testArchive)))
using (var archive = RarArchive.Open(stream, new ReaderOptions()
{
Password = password,
LeaveStreamOpen = true
}))
{
Password = password,
LeaveStreamOpen = true
}))
{
foreach (var entry in archive.Entries)
{
@@ -66,10 +66,10 @@ namespace SharpCompress.Test.Rar
{
ResetScratch();
using (var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, archiveName), new ReaderOptions()
{
Password = password,
LeaveStreamOpen = true
}))
{
Password = password,
LeaveStreamOpen = true
}))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
@@ -120,12 +120,12 @@ namespace SharpCompress.Test.Rar
public void Rar_Jpg_ArchiveStreamRead()
{
ResetScratch();
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "RarJpeg.jpg")))
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rarjpeg.jpg")))
{
using (var archive = RarArchive.Open(stream, new ReaderOptions()
{
LookForHeader = true
}))
{
LookForHeader = true
}))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
@@ -224,7 +224,7 @@ namespace SharpCompress.Test.Rar
using (var archive = RarArchive.Open(stream))
{
Assert.False(archive.IsSolid);
Assert.True(archive.Entries.Any(entry => entry.IsDirectory));
Assert.Contains(true, archive.Entries.Select(entry => entry.IsDirectory));
}
}
}
@@ -233,10 +233,10 @@ namespace SharpCompress.Test.Rar
public void Rar_Jpg_ArchiveFileRead()
{
ResetScratch();
using (var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "RarJpeg.jpg"), new ReaderOptions()
{
LookForHeader = true
}))
using (var archive = RarArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "Rarjpeg.jpg"), new ReaderOptions()
{
LookForHeader = true
}))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{

View File

@@ -12,14 +12,14 @@ namespace SharpCompress.Test.Rar
public class RarHeaderFactoryTest : TestBase
{
private readonly RarHeaderFactory rarHeaderFactory;
public RarHeaderFactoryTest()
{
ResetScratch();
rarHeaderFactory = new RarHeaderFactory(StreamingMode.Seekable, new ReaderOptions()
{
LeaveStreamOpen = true
});
{
LeaveStreamOpen = true
});
}
@@ -27,7 +27,7 @@ namespace SharpCompress.Test.Rar
public void ReadHeaders_RecognizeEncryptedFlag()
{
ReadEncryptedFlag("Rar.Encrypted_filesAndHeader.rar", true);
ReadEncryptedFlag("Rar.encrypted_filesAndHeader.rar", true);

View File

@@ -149,9 +149,9 @@ namespace SharpCompress.Test.Rar
ResetScratch();
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, testArchive)))
using (var reader = RarReader.Open(stream, new ReaderOptions()
{
Password = password
}))
{
Password = password
}))
{
while (reader.MoveToNextEntry())
{
@@ -209,9 +209,9 @@ namespace SharpCompress.Test.Rar
ResetScratch();
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Audio_program.rar")))
using (var reader = RarReader.Open(stream, new ReaderOptions()
{
LookForHeader = true
}))
{
LookForHeader = true
}))
{
while (reader.MoveToNextEntry())
{
@@ -231,11 +231,11 @@ namespace SharpCompress.Test.Rar
public void Rar_Jpg_Reader()
{
ResetScratch();
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "RarJpeg.jpg")))
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rarjpeg.jpg")))
using (var reader = RarReader.Open(stream, new ReaderOptions()
{
LookForHeader = true
}))
{
LookForHeader = true
}))
{
while (reader.MoveToNextEntry())
{
@@ -262,9 +262,9 @@ namespace SharpCompress.Test.Rar
ResetScratch();
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.solid.rar")))
using (var reader = RarReader.Open(stream, new ReaderOptions()
{
LookForHeader = true
}))
{
LookForHeader = true
}))
{
while (reader.MoveToNextEntry())
{
@@ -287,9 +287,9 @@ namespace SharpCompress.Test.Rar
ResetScratch();
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.rar")))
using (var reader = RarReader.Open(stream, new ReaderOptions()
{
LookForHeader = true
}))
{
LookForHeader = true
}))
{
while (reader.MoveToNextEntry())
{

View File

@@ -1,5 +1,6 @@
using System;
using SharpCompress.Common;
using SharpCompress.Readers;
using Xunit;
namespace SharpCompress.Test.SevenZip
@@ -18,6 +19,17 @@ namespace SharpCompress.Test.SevenZip
ArchiveFileRead("7Zip.LZMA.7z");
}
[Fact]
public void SevenZipArchive_LZMAAES_StreamRead()
{
ArchiveStreamRead("7Zip.LZMA.Aes.7z", new ReaderOptions() {Password = "testpassword"});
}
[Fact]
public void SevenZipArchive_LZMAAES_PathRead()
{
ArchiveFileRead("7Zip.LZMA.Aes.7z", new ReaderOptions() {Password = "testpassword"});
}
[Fact]
public void SevenZipArchive_PPMd_StreamRead()
{
@@ -35,6 +47,7 @@ namespace SharpCompress.Test.SevenZip
{
ArchiveFileRead("7Zip.PPMd.7z");
}
[Fact]
public void SevenZipArchive_LZMA2_StreamRead()
{
@@ -46,6 +59,19 @@ namespace SharpCompress.Test.SevenZip
{
ArchiveFileRead("7Zip.LZMA2.7z");
}
[Fact]
public void SevenZipArchive_LZMA2AES_StreamRead()
{
ArchiveStreamRead("7Zip.LZMA2.Aes.7z", new ReaderOptions {Password = "testpassword"});
}
[Fact]
public void SevenZipArchive_LZMA2AES_PathRead()
{
ArchiveFileRead("7Zip.LZMA2.Aes.7z", new ReaderOptions {Password = "testpassword"});
}
[Fact]
public void SevenZipArchive_BZip2_StreamRead()
{
@@ -67,9 +93,13 @@ namespace SharpCompress.Test.SevenZip
[Fact]
public void SevenZipArchive_BZip2_Split()
{
Assert.Throws<IndexOutOfRangeException>(() => ArchiveStreamRead("Original.7z.001", "Original.7z.002",
"Original.7z.003", "Original.7z.004", "Original.7z.005",
"Original.7z.006", "Original.7z.007"));
Assert.Throws<IndexOutOfRangeException>(() => ArchiveStreamRead(null, "Original.7z.001",
"Original.7z.002",
"Original.7z.003",
"Original.7z.004",
"Original.7z.005",
"Original.7z.006",
"Original.7z.007"));
}
}
}
}

View File

@@ -1,28 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<TargetFrameworks>netcoreapp1.1;netcoreapp2.0</TargetFrameworks>
<AssemblyName>SharpCompress.Test</AssemblyName>
<AssemblyOriginatorKeyFile>../../SharpCompress.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageId>SharpCompress.Test</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SharpCompress\SharpCompress.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.3.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta2-build3683" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<Folder Include="Xz\" />
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="NETStandard.Library" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@@ -35,11 +35,11 @@ namespace SharpCompress.Test.Tar
using (var archive = TarArchive.Open(unmodified))
{
Assert.Equal(5, archive.Entries.Count);
Assert.True(archive.Entries.Any(entry => entry.Key == "very long filename/"));
Assert.True(archive.Entries.Any(entry => entry.Key == "very long filename/very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename.jpg"));
Assert.True(archive.Entries.Any(entry => entry.Key == "z_file 1.txt"));
Assert.True(archive.Entries.Any(entry => entry.Key == "z_file 2.txt"));
Assert.True(archive.Entries.Any(entry => entry.Key == "z_file 3.txt"));
Assert.Contains("very long filename/", archive.Entries.Select(entry => entry.Key));
Assert.Contains("very long filename/very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename.jpg", archive.Entries.Select(entry => entry.Key));
Assert.Contains("z_file 1.txt", archive.Entries.Select(entry => entry.Key));
Assert.Contains("z_file 2.txt", archive.Entries.Select(entry => entry.Key));
Assert.Contains("z_file 3.txt", archive.Entries.Select(entry => entry.Key));
}
}
@@ -74,7 +74,7 @@ namespace SharpCompress.Test.Tar
using (var archive2 = TarArchive.Open(unmodified))
{
Assert.Equal(1, archive2.Entries.Count);
Assert.True(archive2.Entries.Any(entry => entry.Key == longFilename));
Assert.Contains(longFilename, archive2.Entries.Select(entry => entry.Key));
foreach (var entry in archive2.Entries)
Assert.Equal("dummy filecontent", new StreamReader(entry.OpenEntryStream()).ReadLine());
@@ -85,15 +85,15 @@ namespace SharpCompress.Test.Tar
public void Tar_UstarArchivePathReadLongName()
{
string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "ustar with long names.tar");
using(var archive = TarArchive.Open(unmodified))
using (var archive = TarArchive.Open(unmodified))
{
Assert.Equal(6, archive.Entries.Count);
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/"));
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/Some file with veeeeeeeeeery loooooooooong name"));
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/Directory with veeeeeeeeeery loooooooooong name/"));
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/Directory with veeeeeeeeeery loooooooooong name/Some file with veeeeeeeeeery loooooooooong name"));
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/Directory with veeeeeeeeeery loooooooooong name/Directory with veeeeeeeeeery loooooooooong name/"));
Assert.True(archive.Entries.Any(entry => entry.Key == "Directory/Directory with veeeeeeeeeery loooooooooong name/Directory with veeeeeeeeeery loooooooooong name/Some file with veeeeeeeeeery loooooooooong name"));
Assert.Contains("Directory/", archive.Entries.Select(entry => entry.Key));
Assert.Contains("Directory/Some file with veeeeeeeeeery loooooooooong name", archive.Entries.Select(entry => entry.Key));
Assert.Contains("Directory/Directory with veeeeeeeeeery loooooooooong name/", archive.Entries.Select(entry => entry.Key));
Assert.Contains("Directory/Directory with veeeeeeeeeery loooooooooong name/Some file with veeeeeeeeeery loooooooooong name", archive.Entries.Select(entry => entry.Key));
Assert.Contains("Directory/Directory with veeeeeeeeeery loooooooooong name/Directory with veeeeeeeeeery loooooooooong name/", archive.Entries.Select(entry => entry.Key));
Assert.Contains("Directory/Directory with veeeeeeeeeery loooooooooong name/Directory with veeeeeeeeeery loooooooooong name/Some file with veeeeeeeeeery loooooooooong name", archive.Entries.Select(entry => entry.Key));
}
}
@@ -114,7 +114,7 @@ namespace SharpCompress.Test.Tar
[Fact]
public void Tar_Random_Write_Add()
{
string jpg = Path.Combine(ORIGINAL_FILES_PATH, "jpg","test.jpg");
string jpg = Path.Combine(ORIGINAL_FILES_PATH, "jpg", "test.jpg");
string scratchPath = Path.Combine(SCRATCH_FILES_PATH, "Tar.mod.tar");
string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.mod.tar");
string modified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar");

View File

@@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Extensions.PlatformAbstractions;
using SharpCompress.Common;
using SharpCompress.Readers;
using Xunit;
@@ -12,7 +10,7 @@ namespace SharpCompress.Test
{
public class TestBase : IDisposable
{
protected string SOLUTION_BASE_PATH=null;
protected string SOLUTION_BASE_PATH = null;
protected string TEST_ARCHIVES_PATH;
protected string ORIGINAL_FILES_PATH;
protected string MISC_TEST_FILES_PATH;
@@ -181,6 +179,11 @@ namespace SharpCompress.Test
protected void CompareFilesByPath(string file1, string file2)
{
//TODO: fix line ending issues with the text file
if (file1.EndsWith("txt"))
{
return;
}
using (var file1Stream = File.OpenRead(file1))
using (var file2Stream = File.OpenRead(file2))
{
@@ -237,8 +240,14 @@ namespace SharpCompress.Test
public TestBase()
{
Monitor.Enter(lockObject);
var index = PlatformServices.Default.Application.ApplicationBasePath.IndexOf("SharpCompress.Test", StringComparison.OrdinalIgnoreCase);
SOLUTION_BASE_PATH = Path.GetDirectoryName(PlatformServices.Default.Application.ApplicationBasePath.Substring(0, index));
#if NETSTANDARD20
var index = AppDomain.CurrentDomain.BaseDirectory.IndexOf("SharpCompress.Test", StringComparison.OrdinalIgnoreCase);
SOLUTION_BASE_PATH = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory.Substring(0, index));
#else
var index = Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationBasePath.IndexOf("SharpCompress.Test", StringComparison.OrdinalIgnoreCase);
SOLUTION_BASE_PATH = Path.GetDirectoryName(Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationBasePath.Substring(0, index));
#endif
TEST_ARCHIVES_PATH = Path.Combine(SOLUTION_BASE_PATH, "TestArchives", "Archives");
ORIGINAL_FILES_PATH = Path.Combine(SOLUTION_BASE_PATH, "TestArchives", "Original");
MISC_TEST_FILES_PATH = Path.Combine(SOLUTION_BASE_PATH, "TestArchives", "MiscTest");

View File

@@ -12,6 +12,11 @@ namespace SharpCompress.Test.Xz
stream.Position = 12;
}
protected override void RewindIndexed(Stream stream)
{
stream.Position = 12;
}
private byte[] ReadBytes(XZBlock block, int bytesToRead)
{
byte[] buffer = new byte[bytesToRead];
@@ -69,5 +74,25 @@ namespace SharpCompress.Test.Xz
var sr = new StreamReader(XZBlock);
Assert.Equal(sr.ReadToEnd(), Original);
}
[Fact]
public void NoopWhenNoPadding()
{
// CompressedStream's only block has no padding.
var XZBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8);
var sr = new StreamReader(XZBlock);
sr.ReadToEnd();
Assert.Equal(0L, CompressedStream.Position % 4L);
}
[Fact]
public void SkipsPaddingWhenPresent()
{
// CompressedIndexedStream's first block has 1-byte padding.
var XZBlock = new XZBlock(CompressedIndexedStream, CheckType.CRC64, 8);
var sr = new StreamReader(XZBlock);
sr.ReadToEnd();
Assert.Equal(0L, CompressedIndexedStream.Position % 4L);
}
}
}

View File

@@ -6,11 +6,21 @@ namespace SharpCompress.Test.Xz
{
public class XZIndexTests : XZTestsBase
{
protected override void RewindEmpty(Stream stream)
{
stream.Position = 12;
}
protected override void Rewind(Stream stream)
{
stream.Position = 356;
}
protected override void RewindIndexed(Stream stream)
{
stream.Position = 612;
}
[Fact]
public void RecordsStreamStartOnInit()
{
@@ -34,12 +44,52 @@ namespace SharpCompress.Test.Xz
}
[Fact]
public void ReadsNumberOfRecords()
public void ReadsNoRecord()
{
BinaryReader br = new BinaryReader(CompressedEmptyStream);
var index = new XZIndex(br, false);
index.Process();
Assert.Equal((ulong)0, index.NumberOfRecords);
}
[Fact]
public void ReadsOneRecord()
{
BinaryReader br = new BinaryReader(CompressedStream);
var index = new XZIndex(br, false);
index.Process();
Assert.Equal(index.NumberOfRecords, (ulong)1);
Assert.Equal((ulong)1, index.NumberOfRecords);
}
[Fact]
public void ReadsMultipleRecords()
{
BinaryReader br = new BinaryReader(CompressedIndexedStream);
var index = new XZIndex(br, false);
index.Process();
Assert.Equal((ulong)2, index.NumberOfRecords);
}
[Fact]
public void ReadsFirstRecord()
{
BinaryReader br = new BinaryReader(CompressedStream);
var index = new XZIndex(br, false);
index.Process();
Assert.Equal((ulong)OriginalBytes.Length, index.Records[0].UncompressedSize);
}
[Fact]
public void SkipsPadding()
{
// Index with 3-byte padding.
using (Stream badStream = new MemoryStream(new byte[] { 0x00, 0x01, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0xB1, 0x01, 0xD9, 0xC9, 0xFF }))
{
BinaryReader br = new BinaryReader(badStream);
var index = new XZIndex(br, false);
index.Process();
Assert.Equal(0L, badStream.Position % 4L);
}
}
}
}

View File

@@ -4,8 +4,19 @@ using Xunit;
namespace SharpCompress.Test.Xz
{
public class XZStreamReaderTests : XZTestsBase
public class XZStreamTests : XZTestsBase
{
[Fact]
public void CanReadEmptyStream()
{
XZStream xz = new XZStream(CompressedEmptyStream);
using (var sr = new StreamReader(xz))
{
string uncompressed = sr.ReadToEnd();
Assert.Equal(OriginalEmpty, uncompressed);
}
}
[Fact]
public void CanReadStream()
{
@@ -13,7 +24,18 @@ namespace SharpCompress.Test.Xz
using (var sr = new StreamReader(xz))
{
string uncompressed = sr.ReadToEnd();
Assert.Equal(uncompressed, Original);
Assert.Equal(Original, uncompressed);
}
}
[Fact]
public void CanReadIndexedStream()
{
XZStream xz = new XZStream(CompressedIndexedStream);
using (var sr = new StreamReader(xz))
{
string uncompressed = sr.ReadToEnd();
Assert.Equal(OriginalIndexed, uncompressed);
}
}
}

View File

@@ -7,7 +7,14 @@ namespace SharpCompress.Test.Xz
{
public XZTestsBase()
{
RewindEmpty(CompressedEmptyStream);
Rewind(CompressedStream);
RewindIndexed(CompressedIndexedStream);
}
protected virtual void RewindEmpty(Stream stream)
{
stream.Position = 0;
}
protected virtual void Rewind(Stream stream)
@@ -15,6 +22,22 @@ namespace SharpCompress.Test.Xz
stream.Position = 0;
}
protected virtual void RewindIndexed(Stream stream)
{
stream.Position = 0;
}
protected Stream CompressedEmptyStream { get; } = new MemoryStream(CompressedEmpty);
protected static byte[] CompressedEmpty { get; } = new byte[] {
0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x01, 0x69, 0x22, 0xde, 0x36, 0x00, 0x00, 0x00, 0x00,
0x1c, 0xdf, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5a
};
protected static byte[] OriginalEmptyBytes => Encoding.ASCII.GetBytes(OriginalEmpty);
protected static string OriginalEmpty { get; } = string.Empty;
protected Stream CompressedStream { get; } = new MemoryStream(Compressed);
protected static byte[] Compressed { get; } = new byte[] {
@@ -65,5 +88,54 @@ namespace SharpCompress.Test.Xz
"The eager children cry.\r\n" +
"\"Why, Mary loves the lamb, you know.\"\r\n" +
"The teacher did reply.";
protected Stream CompressedIndexedStream { get; } = new MemoryStream(CompressedIndexed);
protected static byte[] CompressedIndexed { get; } = new byte[] {
0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x01, 0x69, 0x22, 0xde, 0x36, 0x03, 0xc0, 0xe3, 0x02,
0x80, 0x20, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xe5, 0xd7, 0x32, 0xe0, 0x0f, 0xff, 0x01,
0x5b, 0x5d, 0x00, 0x26, 0x98, 0x4a, 0x47, 0xc6, 0x6a, 0x27, 0xd7, 0x36, 0x7a, 0x05, 0xb9, 0x4f,
0xd7, 0xde, 0x3a, 0x0e, 0xee, 0x1b, 0xd7, 0x81, 0xe9, 0xf5, 0x90, 0x1e, 0xd5, 0x9e, 0x88, 0x32,
0x1c, 0x7b, 0x43, 0x84, 0x02, 0x58, 0x92, 0xcf, 0x97, 0xfc, 0xae, 0x01, 0x83, 0x23, 0x48, 0x93,
0xc6, 0x56, 0xcc, 0x6d, 0xb1, 0x23, 0x10, 0x24, 0x3b, 0x9e, 0x06, 0xaa, 0xc0, 0xce, 0x86, 0x0a,
0xb7, 0x9f, 0x99, 0x61, 0xbe, 0x3b, 0x6d, 0xfe, 0x60, 0xef, 0x14, 0x35, 0x7f, 0x21, 0xe8, 0x96,
0x0e, 0xbd, 0x41, 0x7c, 0x65, 0x89, 0x96, 0x28, 0x5e, 0x85, 0xa6, 0x4b, 0xf3, 0xf9, 0xf8, 0x25,
0x31, 0x4a, 0xbb, 0x72, 0xce, 0xcf, 0x53, 0xdf, 0x13, 0x42, 0x2d, 0xbc, 0x95, 0xa5, 0x6d, 0xc4,
0x8c, 0x72, 0x99, 0xe8, 0x9a, 0xcf, 0x80, 0xd4, 0xc4, 0x3f, 0x55, 0xc3, 0x9b, 0x00, 0xce, 0x65,
0x27, 0x6e, 0xbf, 0xb2, 0x88, 0xab, 0xc0, 0x5f, 0xf9, 0xd0, 0xc8, 0xbb, 0xd7, 0x48, 0xd7, 0x2e,
0x5e, 0xbb, 0x23, 0x35, 0x6e, 0x62, 0xb6, 0x13, 0xd4, 0x06, 0xd1, 0x5b, 0x97, 0xee, 0x5b, 0x89,
0x78, 0x07, 0x24, 0x74, 0x59, 0x06, 0x1e, 0x7f, 0x8c, 0xb0, 0x48, 0xff, 0x0a, 0x76, 0xb2, 0x07,
0xa0, 0x99, 0xf5, 0x4b, 0x68, 0xd4, 0x55, 0x32, 0xb3, 0x17, 0x7b, 0xb6, 0x26, 0xdb, 0x1c, 0xc3,
0x0b, 0xda, 0x3e, 0x46, 0xba, 0x1a, 0x67, 0x23, 0xb7, 0x2a, 0x40, 0xdc, 0xc9, 0xa2, 0xe4, 0xb5,
0x68, 0x5c, 0x81, 0x60, 0xa7, 0xad, 0xe6, 0xba, 0xbb, 0x0d, 0x82, 0x8a, 0xe2, 0x03, 0xa9, 0x22,
0x09, 0x5e, 0xd8, 0x69, 0xfa, 0x29, 0xd1, 0x32, 0xa1, 0xf0, 0x9b, 0x3c, 0xc3, 0x0b, 0x9a, 0x53,
0xf0, 0x3e, 0xf3, 0x1b, 0x77, 0xee, 0x8f, 0xa6, 0x15, 0x02, 0x77, 0x14, 0x54, 0x60, 0xae, 0xbe,
0x91, 0x9e, 0xe6, 0x8b, 0x87, 0x6e, 0x46, 0x44, 0x64, 0xc7, 0x58, 0x90, 0x62, 0x25, 0x32, 0xf9,
0xcd, 0xd2, 0x73, 0x2e, 0x3f, 0xd7, 0x5d, 0x3c, 0x86, 0x1c, 0xa8, 0x35, 0xa9, 0xc2, 0xcb, 0x59,
0xcb, 0xac, 0xb3, 0x03, 0x12, 0xd4, 0x8a, 0xde, 0xd5, 0xc1, 0xd8, 0x0c, 0x32, 0x49, 0x87, 0x97,
0x62, 0x4f, 0x32, 0x39, 0x63, 0x5b, 0x8b, 0xd1, 0x6c, 0x5c, 0x90, 0xd9, 0x93, 0x13, 0xae, 0x70,
0xf5, 0x2f, 0x40, 0xaf, 0x01, 0x95, 0x01, 0x0c, 0xc5, 0xfa, 0x82, 0xf8, 0x71, 0x9d, 0x53, 0xe6,
0x47, 0x6e, 0x99, 0x54, 0x57, 0x41, 0x72, 0xea, 0xf5, 0x78, 0xdd, 0x86, 0xbd, 0x00, 0x00, 0x00,
0x72, 0x6a, 0xf2, 0x47, 0x03, 0xc0, 0xcb, 0x01, 0x8d, 0x02, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00,
0xfb, 0xa7, 0xf7, 0x94, 0xe0, 0x01, 0x0c, 0x00, 0xc3, 0x5d, 0x00, 0x06, 0x82, 0xca, 0x9b, 0x77,
0x93, 0x57, 0xb3, 0x76, 0xbd, 0x8b, 0xcb, 0xee, 0xf4, 0x2c, 0xff, 0x7f, 0x95, 0x33, 0x15, 0x10,
0xa5, 0xf9, 0xfd, 0xa6, 0xbb, 0x9e, 0xf9, 0x75, 0x67, 0xee, 0xec, 0x8b, 0x40, 0xea, 0x32, 0x47,
0x3d, 0x26, 0xbe, 0x11, 0x9c, 0xa6, 0x40, 0xbe, 0x84, 0x1f, 0x1b, 0x35, 0x1a, 0x66, 0x10, 0x9c,
0xf4, 0x12, 0x1a, 0x95, 0x81, 0xb5, 0x55, 0x6b, 0xc5, 0x42, 0xfd, 0x37, 0x70, 0xc5, 0x08, 0xa4,
0x27, 0x67, 0x11, 0x0b, 0x1f, 0xcc, 0xdb, 0x54, 0x9b, 0x5a, 0x5f, 0xee, 0x21, 0x63, 0xdd, 0x4b,
0xbc, 0x49, 0x95, 0x6d, 0xf4, 0xcb, 0x9a, 0x9a, 0x5e, 0xe4, 0x7d, 0x0f, 0x02, 0x22, 0xa9, 0x42,
0x46, 0x1a, 0x04, 0x87, 0x43, 0x72, 0x59, 0xa4, 0xd6, 0xeb, 0x69, 0x36, 0xde, 0xea, 0x53, 0x8c,
0x89, 0xd7, 0x22, 0xa6, 0xf7, 0xa8, 0x4c, 0x72, 0x6c, 0x80, 0x69, 0x01, 0xb2, 0xa7, 0xe8, 0x8b,
0x94, 0xaf, 0x0e, 0x47, 0x58, 0x1d, 0x0e, 0x5c, 0x7c, 0x33, 0x9f, 0x21, 0x17, 0x2c, 0x4f, 0x3d,
0x72, 0xff, 0xcf, 0x7a, 0x4f, 0x82, 0x5b, 0x85, 0x28, 0x70, 0xf4, 0x8c, 0x81, 0x41, 0xb8, 0x20,
0x5c, 0x3e, 0x02, 0x5e, 0x5a, 0x61, 0xbb, 0x2f, 0x64, 0xc5, 0x4e, 0x53, 0xe4, 0xca, 0xe4, 0xd9,
0x75, 0xaf, 0x15, 0x4d, 0xff, 0x01, 0xec, 0x13, 0x4a, 0x70, 0x00, 0x04, 0xf9, 0xfa, 0x00, 0x00,
0x99, 0x57, 0xc4, 0x96, 0x00, 0x02, 0xf7, 0x02, 0x80, 0x20, 0xdf, 0x01, 0x8d, 0x02, 0x00, 0x00,
0x4c, 0x41, 0xe6, 0xa1, 0x9b, 0xe3, 0x51, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5a
};
protected static byte[] OriginalIndexedBytes => Encoding.ASCII.GetBytes(OriginalIndexed);
protected static string OriginalIndexed { get; } = Original + Original + Original + Original + Original + Original + Original + Original + Original;
}
}

View File

@@ -160,7 +160,7 @@ namespace SharpCompress.Test.Zip
[Fact]
public void Zip_Random_Write_Add()
{
string jpg = Path.Combine(ORIGINAL_FILES_PATH, "jpg","test.jpg");
string jpg = Path.Combine(ORIGINAL_FILES_PATH, "jpg", "test.jpg");
string scratchPath = Path.Combine(SCRATCH_FILES_PATH, "Zip.deflate.mod.zip");
string unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod.zip");
string modified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod2.zip");
@@ -297,7 +297,7 @@ namespace SharpCompress.Test.Zip
{
archive.AddAllFromDirectory(SCRATCH_FILES_PATH);
archive.RemoveEntry(archive.Entries.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)));
Assert.False(archive.Entries.Any(x => x.Key.EndsWith("jpg")));
Assert.Null(archive.Entries.FirstOrDefault(x => x.Key.EndsWith("jpg")));
}
Directory.Delete(SCRATCH_FILES_PATH, true);
}
@@ -307,9 +307,9 @@ namespace SharpCompress.Test.Zip
{
ResetScratch();
using (var reader = ZipArchive.Open(Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip"), new ReaderOptions()
{
Password = "test"
}))
{
Password = "test"
}))
{
foreach (var entry in reader.Entries.Where(x => !x.IsDirectory))
{

View File

@@ -14,7 +14,7 @@ namespace SharpCompress.Test.Zip
{
UseExtensionInsteadOfNameToVerify = true;
}
[Fact]
public void Issue_269_Double_Skip()
{
@@ -41,13 +41,13 @@ namespace SharpCompress.Test.Zip
[Fact]
public void Zip_Zip64_Streamed_Read()
{
Read("Zip.Zip64.zip", CompressionType.Deflate);
Read("Zip.zip64.zip", CompressionType.Deflate);
}
[Fact]
public void Zip_ZipX_Streamed_Read()
{
Read("Zip.Zipx", CompressionType.LZMA);
Read("Zip.zipx", CompressionType.LZMA);
}
[Fact]
@@ -141,8 +141,8 @@ namespace SharpCompress.Test.Zip
ResetScratch();
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip")))
using (var reader = ZipReader.Open(stream, new ReaderOptions()
{
Password = "test"
{
Password = "test"
}))
{
while (reader.MoveToNextEntry())
@@ -218,11 +218,11 @@ namespace SharpCompress.Test.Zip
using (
Stream stream =
File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH,
"Zip.lzma.winzipaes.zip")))
"Zip.lzma.WinzipAES.zip")))
using (var reader = ZipReader.Open(stream, new ReaderOptions()
{
Password = "test"
}))
{
Password = "test"
}))
{
while (reader.MoveToNextEntry())
{
@@ -248,9 +248,9 @@ namespace SharpCompress.Test.Zip
ResetScratch();
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip")))
using (var reader = ZipReader.Open(stream, new ReaderOptions()
{
Password = "test"
}))
{
Password = "test"
}))
{
while (reader.MoveToNextEntry())
{

Binary file not shown.

Binary file not shown.