Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/libraries/System.IO.Compression/ref/System.IO.Compression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ public override void Flush() { }
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
public override void Write(System.ReadOnlySpan<byte> buffer) { }
public override void WriteByte(byte value) { }
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override void WriteByte(byte value) { }
}
public partial class GZipStream : System.IO.Stream
{
Expand Down Expand Up @@ -84,17 +84,17 @@ public override void Flush() { }
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
public override void Write(System.ReadOnlySpan<byte> buffer) { }
public override void WriteByte(byte value) { }
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override void WriteByte(byte value) { }
}
public partial class ZipArchive : System.IDisposable
{
public ZipArchive(System.IO.Stream stream) { }
public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode) { }
public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) { }
public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding? entryNameEncoding) { }
[System.Diagnostics.CodeAnalysis.AllowNull]
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
public string Comment { get { throw null; } set { } }
public System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry> Entries { get { throw null; } }
public System.IO.Compression.ZipArchiveMode Mode { get { throw null; } }
Expand All @@ -108,13 +108,14 @@ public partial class ZipArchiveEntry
{
internal ZipArchiveEntry() { }
public System.IO.Compression.ZipArchive Archive { get { throw null; } }
[System.Diagnostics.CodeAnalysis.AllowNull]
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
public string Comment { get { throw null; } set { } }
public long CompressedLength { get { throw null; } }
[System.CLSCompliantAttribute(false)]
public uint Crc32 { get { throw null; } }
public int ExternalAttributes { get { throw null; } set { } }
public string FullName { get { throw null; } }
public bool IsEncrypted { get { throw null; } }
public System.DateTimeOffset LastWriteTime { get { throw null; } set { } }
public long Length { get { throw null; } }
public string Name { get { throw null; } }
Expand Down Expand Up @@ -159,8 +160,8 @@ public override void Flush() { }
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
public override void Write(System.ReadOnlySpan<byte> buffer) { }
public override void WriteByte(byte value) { }
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override void WriteByte(byte value) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public partial class ZipArchiveEntry
private ZipVersionNeededValues _versionMadeBySpecification;
internal ZipVersionNeededValues _versionToExtract;
private BitFlagValues _generalPurposeBitFlag;
private bool _isEncrypted;
private CompressionMethodValues _storedCompressionMethod;
private DateTimeOffset _lastModified;
private long _compressedSize;
Expand Down Expand Up @@ -55,6 +56,7 @@ internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd)
_versionMadeBySpecification = (ZipVersionNeededValues)cd.VersionMadeBySpecification;
_versionToExtract = (ZipVersionNeededValues)cd.VersionNeededToExtract;
_generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag;
_isEncrypted = (_generalPurposeBitFlag & BitFlagValues.IsEncrypted) != 0;
CompressionMethod = (CompressionMethodValues)cd.CompressionMethod;
_lastModified = new DateTimeOffset(ZipHelper.DosTimeToDateTime(cd.LastModified));
_compressedSize = cd.CompressedSize;
Expand Down Expand Up @@ -151,6 +153,11 @@ internal ZipArchiveEntry(ZipArchive archive, string entryName)
[CLSCompliant(false)]
public uint Crc32 => _crc32;

/// <summary>
/// Gets a value that indicates whether the entry is encrypted.
/// </summary>
public bool IsEncrypted => _isEncrypted;

/// <summary>
/// The compressed size of the entry. If the archive that the entry belongs to is in Create mode, attempts to get this property will always throw an exception. If the archive that the entry belongs to is in update mode, this property will only be valid if the entry has not been opened.
/// </summary>
Expand Down Expand Up @@ -1305,7 +1312,7 @@ protected override void Dispose(bool disposing)
}

[Flags]
internal enum BitFlagValues : ushort { DataDescriptor = 0x8, UnicodeFileNameAndComment = 0x800 }
internal enum BitFlagValues : ushort { IsEncrypted = 0x1, DataDescriptor = 0x8, UnicodeFileNameAndComment = 0x800 }

internal enum CompressionMethodValues : ushort { Stored = 0x0, Deflate = 0x8, Deflate64 = 0x9, BZip2 = 0xC, LZMA = 0xE }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;

Expand Down Expand Up @@ -207,5 +208,46 @@ public static void TestEmptyLastModifiedEntryValueNotThrowingInternalException()
using var archive = new ZipArchive(memoryStream, ZipArchiveMode.Read, true);
Assert.Equal(archive.Entries[0].LastWriteTime, emptyDateIndicator);
}

[Theory]
[InlineData("normal.zip")]
[InlineData("small.zip")]
public static async Task EntriesNotEncryptedByDefault(string zipFile)
{
using (ZipArchive archive = new ZipArchive(await StreamHelpers.CreateTempCopyStream(zfile(zipFile)), ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Assert.False(entry.IsEncrypted);
}
}
}

[Theory]
[InlineData("encrypted_entries_weak.zip")]
[InlineData("encrypted_entries_aes256.zip")]
[InlineData("encrypted_entries_mixed.zip")]
public static async Task IdentifyEncryptedEntries(string zipFile)
{
var entriesEncrypted = new Dictionary<string, bool>();

using (ZipArchive archive = new ZipArchive(await StreamHelpers.CreateTempCopyStream(zfile(zipFile)), ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
entriesEncrypted.Add(entry.Name, entry.IsEncrypted);
}
}

var expectedEntries = new Dictionary<string, bool>()
{
{ "file1-encrypted.txt", true },
{ "file2-unencrypted.txt", false },
{ "file3-encrypted.txt", true },
{ "file4-unencrypted.txt", false },
};

Assert.Equal(expectedEntries, entriesEncrypted);
}
}
}