Skip to content

Commit

Permalink
fix(zip): cleanup/fix of StringCodec (#778)
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel committed Oct 20, 2022
1 parent 23becfd commit a389d9f
Show file tree
Hide file tree
Showing 10 changed files with 399 additions and 118 deletions.
Expand Up @@ -205,7 +205,12 @@ public bool CanPatchEntries
protected byte[] AESAuthCode;

/// <inheritdoc cref="StringCodec.ZipCryptoEncoding"/>
public Encoding ZipCryptoEncoding { get; set; } = StringCodec.DefaultZipCryptoEncoding;
public Encoding ZipCryptoEncoding {
get => _stringCodec.ZipCryptoEncoding;
set {
_stringCodec = _stringCodec.WithZipCryptoEncoding(value);
}
}

/// <summary>
/// Encrypt a block of data
Expand Down Expand Up @@ -508,6 +513,9 @@ public override void Write(byte[] buffer, int offset, int count)

private bool isClosed_;

/// <inheritdoc cref="StringCodec"/>
protected StringCodec _stringCodec = ZipStrings.GetStringCodec();

#endregion Instance Fields
}
}
7 changes: 3 additions & 4 deletions src/ICSharpCode.SharpZipLib/Zip/FastZip.cs
Expand Up @@ -358,7 +358,7 @@ public bool UseUnicode
public int LegacyCodePage
{
get => _stringCodec.CodePage;
set => _stringCodec.CodePage = value;
set => _stringCodec = StringCodec.FromCodePage(value);
}

/// <inheritdoc cref="Zip.StringCodec"/>
Expand Down Expand Up @@ -579,7 +579,7 @@ public void ExtractZip(string zipFileName, string targetDirectory, string fileFi
directoryFilter_ = new NameFilter(directoryFilter);
restoreDateTimeOnExtract_ = restoreDateTime;

using (zipFile_ = new ZipFile(inputStream, !isStreamOwner))
using (zipFile_ = new ZipFile(inputStream, !isStreamOwner, _stringCodec))
{
if (password_ != null)
{
Expand Down Expand Up @@ -994,8 +994,7 @@ private static bool NameIsValid(string name)
private INameTransform extractNameTransform_;
private UseZip64 useZip64_ = UseZip64.Dynamic;
private CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION;
private StringCodec _stringCodec = new StringCodec();

private StringCodec _stringCodec = ZipStrings.GetStringCodec();
private string password_;

#endregion Instance Fields
Expand Down
23 changes: 18 additions & 5 deletions src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
Expand Up @@ -7,6 +7,7 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

Expand Down Expand Up @@ -504,6 +505,7 @@ public ZipFile(FileStream file, bool leaveOpen)
/// </summary>
/// <param name="stream">The <see cref="Stream"/> to read archive data from.</param>
/// <param name="leaveOpen">true to leave the <see cref="Stream">stream</see> open when the ZipFile is disposed, false to dispose of it</param>
/// <param name="stringCodec"></param>
/// <exception cref="IOException">
/// An i/o error occurs
/// </exception>
Expand All @@ -516,7 +518,7 @@ public ZipFile(FileStream file, bool leaveOpen)
/// <exception cref="ArgumentNullException">
/// The <see cref="Stream">stream</see> argument is null.
/// </exception>
public ZipFile(Stream stream, bool leaveOpen)
public ZipFile(Stream stream, bool leaveOpen, StringCodec stringCodec = null)
{
if (stream == null)
{
Expand All @@ -531,6 +533,11 @@ public ZipFile(Stream stream, bool leaveOpen)
baseStream_ = stream;
isStreamOwner = !leaveOpen;

if (stringCodec != null)
{
_stringCodec = stringCodec;
}

if (baseStream_.Length > 0)
{
try
Expand Down Expand Up @@ -736,14 +743,20 @@ public long Count
public Encoding ZipCryptoEncoding
{
get => _stringCodec.ZipCryptoEncoding;
set => _stringCodec.ZipCryptoEncoding = value;
set => _stringCodec = _stringCodec.WithZipCryptoEncoding(value);
}

/// <inheritdoc cref="Zip.StringCodec"/>
public StringCodec StringCodec
{
get => _stringCodec;
set => _stringCodec = value;
set {
_stringCodec = value;
if (!isNewArchive_)
{
// Since the string codec was changed
ReadEntries();
}
}
}

#endregion Properties
Expand Down Expand Up @@ -1592,7 +1605,7 @@ public void CommitUpdate()
{
RunUpdates();
}
else if (commentEdited_)
else if (commentEdited_ && !isNewArchive_)
{
UpdateCommentOnly();
}
Expand Down
2 changes: 1 addition & 1 deletion src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs
Expand Up @@ -95,7 +95,7 @@ internal static class ZipFormat
}
}

byte[] name = stringCodec.ZipOutputEncoding.GetBytes(entry.Name);
byte[] name = stringCodec.ZipEncoding(entry.IsUnicodeText).GetBytes(entry.Name);

if (name.Length > 0xFFFF)
{
Expand Down
18 changes: 18 additions & 0 deletions src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace ICSharpCode.SharpZipLib.Zip
{
Expand Down Expand Up @@ -104,6 +105,21 @@ public ZipInputStream(Stream baseInputStream, int bufferSize)
internalReader = new ReadDataHandler(ReadingNotAvailable);
}

/// <summary>
/// Creates a new Zip input stream, for reading a zip archive.
/// </summary>
/// <param name="baseInputStream">The underlying <see cref="Stream"/> providing data.</param>
/// <param name="stringCodec"></param>
public ZipInputStream(Stream baseInputStream, StringCodec stringCodec)
: base(baseInputStream, new Inflater(true))
{
internalReader = new ReadDataHandler(ReadingNotAvailable);
if (stringCodec != null)
{
_stringCodec = stringCodec;
}
}

#endregion Constructors

/// <summary>
Expand Down Expand Up @@ -558,7 +574,9 @@ private int InitialRead(byte[] destination, int offset, int count)

// Generate and set crypto transform...
var managed = new PkzipClassicManaged();
Console.WriteLine($"Input Encoding: {_stringCodec.ZipCryptoEncoding.EncodingName}");
byte[] key = PkzipClassic.GenerateKeys(_stringCodec.ZipCryptoEncoding.GetBytes(password));
Console.WriteLine($"Input Bytes: {string.Join(", ", key.Select(b => $"{b:x2}").ToArray())}");

inputBuffer.CryptoTransform = managed.CreateDecryptor(key, null);

Expand Down
14 changes: 10 additions & 4 deletions src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -80,7 +81,12 @@ public ZipOutputStream(Stream baseOutputStream, int bufferSize)
{
}

internal ZipOutputStream(Stream baseOutputStream, StringCodec stringCodec) : this(baseOutputStream)
/// <summary>
/// Creates a new Zip output stream, writing a zip archive.
/// </summary>
/// <param name="baseOutputStream">The output stream to which the archive contents are written.</param>
/// <param name="stringCodec"></param>
public ZipOutputStream(Stream baseOutputStream, StringCodec stringCodec) : this(baseOutputStream)
{
_stringCodec = stringCodec;
}
Expand Down Expand Up @@ -160,7 +166,7 @@ public UseZip64 UseZip64
/// Defaults to <see cref="PathTransformer"/>, set to null to disable transforms and use names as supplied.
/// </summary>
public INameTransform NameTransform { get; set; } = new PathTransformer();

/// <summary>
/// Get/set the password used for encryption.
/// </summary>
Expand Down Expand Up @@ -742,7 +748,9 @@ private byte[] CreateZipCryptoHeader(long crcValue)
private void InitializeZipCryptoPassword(string password)
{
var pkManaged = new PkzipClassicManaged();
Console.WriteLine($"Output Encoding: {ZipCryptoEncoding.EncodingName}");
byte[] key = PkzipClassic.GenerateKeys(ZipCryptoEncoding.GetBytes(password));
Console.WriteLine($"Output Bytes: {string.Join(", ", key.Select(b => $"{b:x2}").ToArray())}");
cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
}

Expand Down Expand Up @@ -970,8 +978,6 @@ public override void Flush()
/// </summary>
private string password;

private readonly StringCodec _stringCodec = ZipStrings.GetStringCodec();

#endregion Instance Fields

#region Static Fields
Expand Down

0 comments on commit a389d9f

Please sign in to comment.