Skip to content

Commit a389d9f

Browse files
authored
fix(zip): cleanup/fix of StringCodec (#778)
1 parent 23becfd commit a389d9f

File tree

10 files changed

+399
-118
lines changed

10 files changed

+399
-118
lines changed

src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,12 @@ public bool CanPatchEntries
205205
protected byte[] AESAuthCode;
206206

207207
/// <inheritdoc cref="StringCodec.ZipCryptoEncoding"/>
208-
public Encoding ZipCryptoEncoding { get; set; } = StringCodec.DefaultZipCryptoEncoding;
208+
public Encoding ZipCryptoEncoding {
209+
get => _stringCodec.ZipCryptoEncoding;
210+
set {
211+
_stringCodec = _stringCodec.WithZipCryptoEncoding(value);
212+
}
213+
}
209214

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

509514
private bool isClosed_;
510515

516+
/// <inheritdoc cref="StringCodec"/>
517+
protected StringCodec _stringCodec = ZipStrings.GetStringCodec();
518+
511519
#endregion Instance Fields
512520
}
513521
}

src/ICSharpCode.SharpZipLib/Zip/FastZip.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public bool UseUnicode
358358
public int LegacyCodePage
359359
{
360360
get => _stringCodec.CodePage;
361-
set => _stringCodec.CodePage = value;
361+
set => _stringCodec = StringCodec.FromCodePage(value);
362362
}
363363

364364
/// <inheritdoc cref="Zip.StringCodec"/>
@@ -579,7 +579,7 @@ public void ExtractZip(Stream inputStream, string targetDirectory,
579579
directoryFilter_ = new NameFilter(directoryFilter);
580580
restoreDateTimeOnExtract_ = restoreDateTime;
581581

582-
using (zipFile_ = new ZipFile(inputStream, !isStreamOwner))
582+
using (zipFile_ = new ZipFile(inputStream, !isStreamOwner, _stringCodec))
583583
{
584584
if (password_ != null)
585585
{
@@ -994,8 +994,7 @@ private static bool NameIsValid(string name)
994994
private INameTransform extractNameTransform_;
995995
private UseZip64 useZip64_ = UseZip64.Dynamic;
996996
private CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION;
997-
private StringCodec _stringCodec = new StringCodec();
998-
997+
private StringCodec _stringCodec = ZipStrings.GetStringCodec();
999998
private string password_;
1000999

10011000
#endregion Instance Fields

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections;
88
using System.Collections.Generic;
99
using System.IO;
10+
using System.Linq;
1011
using System.Security.Cryptography;
1112
using System.Text;
1213

@@ -504,6 +505,7 @@ public ZipFile(Stream stream) :
504505
/// </summary>
505506
/// <param name="stream">The <see cref="Stream"/> to read archive data from.</param>
506507
/// <param name="leaveOpen">true to leave the <see cref="Stream">stream</see> open when the ZipFile is disposed, false to dispose of it</param>
508+
/// <param name="stringCodec"></param>
507509
/// <exception cref="IOException">
508510
/// An i/o error occurs
509511
/// </exception>
@@ -516,7 +518,7 @@ public ZipFile(Stream stream) :
516518
/// <exception cref="ArgumentNullException">
517519
/// The <see cref="Stream">stream</see> argument is null.
518520
/// </exception>
519-
public ZipFile(Stream stream, bool leaveOpen)
521+
public ZipFile(Stream stream, bool leaveOpen, StringCodec stringCodec = null)
520522
{
521523
if (stream == null)
522524
{
@@ -531,6 +533,11 @@ public ZipFile(Stream stream, bool leaveOpen)
531533
baseStream_ = stream;
532534
isStreamOwner = !leaveOpen;
533535

536+
if (stringCodec != null)
537+
{
538+
_stringCodec = stringCodec;
539+
}
540+
534541
if (baseStream_.Length > 0)
535542
{
536543
try
@@ -736,14 +743,20 @@ public ZipEntry this[int index]
736743
public Encoding ZipCryptoEncoding
737744
{
738745
get => _stringCodec.ZipCryptoEncoding;
739-
set => _stringCodec.ZipCryptoEncoding = value;
746+
set => _stringCodec = _stringCodec.WithZipCryptoEncoding(value);
740747
}
741748

742749
/// <inheritdoc cref="Zip.StringCodec"/>
743750
public StringCodec StringCodec
744751
{
745-
get => _stringCodec;
746-
set => _stringCodec = value;
752+
set {
753+
_stringCodec = value;
754+
if (!isNewArchive_)
755+
{
756+
// Since the string codec was changed
757+
ReadEntries();
758+
}
759+
}
747760
}
748761

749762
#endregion Properties
@@ -1592,7 +1605,7 @@ public void CommitUpdate()
15921605
{
15931606
RunUpdates();
15941607
}
1595-
else if (commentEdited_)
1608+
else if (commentEdited_ && !isNewArchive_)
15961609
{
15971610
UpdateCommentOnly();
15981611
}

src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ internal static int WriteLocalHeader(Stream stream, ZipEntry entry, out EntryPat
9595
}
9696
}
9797

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

100100
if (name.Length > 0xFFFF)
101101
{

src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Diagnostics;
77
using System.IO;
8+
using System.Linq;
89

910
namespace ICSharpCode.SharpZipLib.Zip
1011
{
@@ -104,6 +105,21 @@ public ZipInputStream(Stream baseInputStream, int bufferSize)
104105
internalReader = new ReadDataHandler(ReadingNotAvailable);
105106
}
106107

108+
/// <summary>
109+
/// Creates a new Zip input stream, for reading a zip archive.
110+
/// </summary>
111+
/// <param name="baseInputStream">The underlying <see cref="Stream"/> providing data.</param>
112+
/// <param name="stringCodec"></param>
113+
public ZipInputStream(Stream baseInputStream, StringCodec stringCodec)
114+
: base(baseInputStream, new Inflater(true))
115+
{
116+
internalReader = new ReadDataHandler(ReadingNotAvailable);
117+
if (stringCodec != null)
118+
{
119+
_stringCodec = stringCodec;
120+
}
121+
}
122+
107123
#endregion Constructors
108124

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

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

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

src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.IO;
9+
using System.Linq;
910
using System.Security.Cryptography;
1011
using System.Threading;
1112
using System.Threading.Tasks;
@@ -80,7 +81,12 @@ public ZipOutputStream(Stream baseOutputStream, int bufferSize)
8081
{
8182
}
8283

83-
internal ZipOutputStream(Stream baseOutputStream, StringCodec stringCodec) : this(baseOutputStream)
84+
/// <summary>
85+
/// Creates a new Zip output stream, writing a zip archive.
86+
/// </summary>
87+
/// <param name="baseOutputStream">The output stream to which the archive contents are written.</param>
88+
/// <param name="stringCodec"></param>
89+
public ZipOutputStream(Stream baseOutputStream, StringCodec stringCodec) : this(baseOutputStream)
8490
{
8591
_stringCodec = stringCodec;
8692
}
@@ -160,7 +166,7 @@ public UseZip64 UseZip64
160166
/// Defaults to <see cref="PathTransformer"/>, set to null to disable transforms and use names as supplied.
161167
/// </summary>
162168
public INameTransform NameTransform { get; set; } = new PathTransformer();
163-
169+
164170
/// <summary>
165171
/// Get/set the password used for encryption.
166172
/// </summary>
@@ -742,7 +748,9 @@ private byte[] CreateZipCryptoHeader(long crcValue)
742748
private void InitializeZipCryptoPassword(string password)
743749
{
744750
var pkManaged = new PkzipClassicManaged();
751+
Console.WriteLine($"Output Encoding: {ZipCryptoEncoding.EncodingName}");
745752
byte[] key = PkzipClassic.GenerateKeys(ZipCryptoEncoding.GetBytes(password));
753+
Console.WriteLine($"Output Bytes: {string.Join(", ", key.Select(b => $"{b:x2}").ToArray())}");
746754
cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
747755
}
748756

@@ -970,8 +978,6 @@ public override void Flush()
970978
/// </summary>
971979
private string password;
972980

973-
private readonly StringCodec _stringCodec = ZipStrings.GetStringCodec();
974-
975981
#endregion Instance Fields
976982

977983
#region Static Fields

0 commit comments

Comments
 (0)