Skip to content

Commit 3b126e9

Browse files
committed
Replace static ZipStrings with instances of StringCodec
1 parent a4e4502 commit 3b126e9

File tree

12 files changed

+195
-277
lines changed

12 files changed

+195
-277
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.IO;
44
using System.Security.Cryptography;
5+
using System.Text;
56

67
namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams
78
{
@@ -185,6 +186,9 @@ public string Password
185186
}
186187
}
187188

189+
/// <inheritdoc cref="StringCodec.ZipCryptoEncoding"/>
190+
public Encoding ZipCryptoEncoding { get; set; } = StringCodec.DefaultZipCryptoEncoding;
191+
188192
/// <summary>
189193
/// Encrypt a block of data
190194
/// </summary>
@@ -209,7 +213,7 @@ protected void EncryptBlock(byte[] buffer, int offset, int length)
209213
protected void InitializePassword(string password)
210214
{
211215
var pkManaged = new PkzipClassicManaged();
212-
byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password));
216+
byte[] key = PkzipClassic.GenerateKeys(ZipCryptoEncoding.GetBytes(password));
213217
cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
214218
}
215219

src/ICSharpCode.SharpZipLib/Zip/FastZip.cs

+17
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,22 @@ public Deflater.CompressionLevel CompressionLevel
345345
set { compressionLevel_ = value; }
346346
}
347347

348+
/// <summary>
349+
/// Reflects the opposite of the internal <see cref="StringCodec.ForceZipLegacyEncoding"/>, setting it to <c>false</c> overrides the encoding used for reading and writing zip entries
350+
/// </summary>
351+
public bool UseUnicode
352+
{
353+
get => !_stringCodec.ForceZipLegacyEncoding;
354+
set => _stringCodec.ForceZipLegacyEncoding = !value;
355+
}
356+
357+
/// <summary> Gets or sets the code page used for reading/writing zip file entries when unicode is disabled </summary>
358+
public int LegacyCodePage
359+
{
360+
get => _stringCodec.CodePage;
361+
set => _stringCodec.CodePage = value;
362+
}
363+
348364
#endregion Properties
349365

350366
#region Delegates
@@ -967,6 +983,7 @@ private static bool NameIsValid(string name)
967983
private INameTransform extractNameTransform_;
968984
private UseZip64 useZip64_ = UseZip64.Dynamic;
969985
private CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION;
986+
private readonly StringCodec _stringCodec = new StringCodec();
970987

971988
private string password_;
972989

src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs

-43
Original file line numberDiff line numberDiff line change
@@ -470,48 +470,5 @@ public static class ZipConstants
470470
public const int ENDSIG = 'P' | ('K' << 8) | (5 << 16) | (6 << 24);
471471

472472
#endregion Header Signatures
473-
474-
/// <summary>
475-
/// Default encoding used for string conversion. 0 gives the default system OEM code page.
476-
/// Using the default code page isnt the full solution necessarily
477-
/// there are many variable factors, codepage 850 is often a good choice for
478-
/// European users, however be careful about compatability.
479-
/// </summary>
480-
[Obsolete("Use ZipStrings instead")]
481-
public static int DefaultCodePage
482-
{
483-
get => ZipStrings.CodePage;
484-
set => ZipStrings.CodePage = value;
485-
}
486-
487-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToString(byte[], int)"/></summary>
488-
[Obsolete("Use ZipStrings.ConvertToString instead")]
489-
public static string ConvertToString(byte[] data, int count)
490-
=> ZipStrings.ConvertToString(data, count);
491-
492-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToString(byte[])"/></summary>
493-
[Obsolete("Use ZipStrings.ConvertToString instead")]
494-
public static string ConvertToString(byte[] data)
495-
=> ZipStrings.ConvertToString(data);
496-
497-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToStringExt(int, byte[], int)"/></summary>
498-
[Obsolete("Use ZipStrings.ConvertToStringExt instead")]
499-
public static string ConvertToStringExt(int flags, byte[] data, int count)
500-
=> ZipStrings.ConvertToStringExt(flags, data, count);
501-
502-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToStringExt(int, byte[])"/></summary>
503-
[Obsolete("Use ZipStrings.ConvertToStringExt instead")]
504-
public static string ConvertToStringExt(int flags, byte[] data)
505-
=> ZipStrings.ConvertToStringExt(flags, data);
506-
507-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToArray(string)"/></summary>
508-
[Obsolete("Use ZipStrings.ConvertToArray instead")]
509-
public static byte[] ConvertToArray(string str)
510-
=> ZipStrings.ConvertToArray(str);
511-
512-
/// <summary> Deprecated wrapper for <see cref="ZipStrings.ConvertToArray(int, string)"/></summary>
513-
[Obsolete("Use ZipStrings.ConvertToArray instead")]
514-
public static byte[] ConvertToArray(int flags, string str)
515-
=> ZipStrings.ConvertToArray(flags, str);
516473
}
517474
}

src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.IO;
3+
using System.Text;
34

45
namespace ICSharpCode.SharpZipLib.Zip
56
{
@@ -150,7 +151,7 @@ private enum Known : byte
150151
/// The name passed is null
151152
/// </exception>
152153
public ZipEntry(string name)
153-
: this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated)
154+
: this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated, true)
154155
{
155156
}
156157

@@ -171,7 +172,7 @@ public ZipEntry(string name)
171172
/// </exception>
172173
internal ZipEntry(string name, int versionRequiredToExtract)
173174
: this(name, versionRequiredToExtract, ZipConstants.VersionMadeBy,
174-
CompressionMethod.Deflated)
175+
CompressionMethod.Deflated, true)
175176
{
176177
}
177178

@@ -182,6 +183,7 @@ internal ZipEntry(string name, int versionRequiredToExtract)
182183
/// <param name="madeByInfo">Version and HostSystem Information</param>
183184
/// <param name="versionRequiredToExtract">Minimum required zip feature version required to extract this entry</param>
184185
/// <param name="method">Compression method for this entry.</param>
186+
/// <param name="unicode">Whether the entry uses unicode for name and comment</param>
185187
/// <exception cref="ArgumentNullException">
186188
/// The name passed is null
187189
/// </exception>
@@ -193,7 +195,7 @@ internal ZipEntry(string name, int versionRequiredToExtract)
193195
/// It is not generally useful, use the constructor specifying the name only.
194196
/// </remarks>
195197
internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,
196-
CompressionMethod method)
198+
CompressionMethod method, bool unicode)
197199
{
198200
if (name == null)
199201
{
@@ -216,7 +218,7 @@ internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,
216218
this.versionToExtract = (ushort)versionRequiredToExtract;
217219
this.method = method;
218220

219-
IsUnicodeText = ZipStrings.UseUnicode;
221+
IsUnicodeText = unicode;
220222
}
221223

222224
/// <summary>

src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public enum TimeSetting
6868
public ZipEntryFactory()
6969
{
7070
nameTransform_ = new ZipNameTransform();
71-
isUnicodeText_ = ZipStrings.UseUnicode;
71+
isUnicodeText_ = true;
7272
}
7373

7474
/// <summary>
@@ -162,7 +162,7 @@ public int SetAttributes
162162
}
163163

164164
/// <summary>
165-
/// Get set a value indicating whether unidoce text should be set on.
165+
/// Get set a value indicating whether unicode text should be set on.
166166
/// </summary>
167167
public bool IsUnicodeText
168168
{

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

+37-20
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ public string Password
367367
}
368368
else
369369
{
370-
key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(value));
370+
key = PkzipClassic.GenerateKeys(ZipCryptoEncoding.GetBytes(value));
371371
}
372372

373373
rawPassword_ = value;
@@ -725,6 +725,14 @@ public ZipEntry this[int index]
725725
}
726726
}
727727

728+
729+
/// <inheritdoc cref="StringCodec.ZipCryptoEncoding"/>
730+
public Encoding ZipCryptoEncoding
731+
{
732+
get => _stringCodec.ZipCryptoEncoding;
733+
set => _stringCodec.ZipCryptoEncoding = value;
734+
}
735+
728736
#endregion Properties
729737

730738
#region Input Handling
@@ -1191,6 +1199,8 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
11911199
throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion));
11921200
}
11931201

1202+
var localEncoding = _stringCodec.ZipInputEncoding(localFlags);
1203+
11941204
// Local entry flags dont have reserved bit set on.
11951205
if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0)
11961206
{
@@ -1283,7 +1293,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
12831293
}
12841294

12851295
// Name data has already been read convert it and compare.
1286-
string localName = ZipStrings.ConvertToStringExt(localFlags, nameData);
1296+
string localName = localEncoding.GetString(nameData);
12871297

12881298
// Central directory and local entry name match
12891299
if (localName != entry.Name)
@@ -1581,7 +1591,7 @@ public void CommitUpdate()
15811591
// Create an empty archive if none existed originally.
15821592
if (entries_.Length == 0)
15831593
{
1584-
byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_);
1594+
byte[] theComment = (newComment_ != null) ? newComment_.RawComment : _stringCodec.ZipArchiveCommentEncoding.GetBytes(comment_);
15851595
using (ZipHelperStream zhs = new ZipHelperStream(baseStream_))
15861596
{
15871597
zhs.WriteEndOfCentralDirectory(0, 0, 0, theComment);
@@ -1619,7 +1629,7 @@ public void SetComment(string comment)
16191629

16201630
CheckUpdating();
16211631

1622-
newComment_ = new ZipString(comment);
1632+
newComment_ = new ZipString(comment, _stringCodec.ZipArchiveCommentEncoding);
16231633

16241634
if (newComment_.RawLength > 0xffff)
16251635
{
@@ -2147,7 +2157,8 @@ private void WriteLocalEntryHeader(ZipUpdate update)
21472157
WriteLEInt((int)entry.Size);
21482158
}
21492159

2150-
byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name);
2160+
var entryEncoding = _stringCodec.ZipInputEncoding(entry.Flags);
2161+
byte[] name = entryEncoding.GetBytes(entry.Name);
21512162

21522163
if (name.Length > 0xFFFF)
21532164
{
@@ -2254,7 +2265,8 @@ private int WriteCentralDirectoryHeader(ZipEntry entry)
22542265
WriteLEInt((int)entry.Size);
22552266
}
22562267

2257-
byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name);
2268+
var entryEncoding = _stringCodec.ZipInputEncoding(entry.Flags);
2269+
byte[] name = entryEncoding.GetBytes(entry.Name);
22582270

22592271
if (name.Length > 0xFFFF)
22602272
{
@@ -3081,7 +3093,7 @@ private void RunUpdates()
30813093
}
30823094
}
30833095

3084-
byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_);
3096+
byte[] theComment = newComment_?.RawComment ?? _stringCodec.ZipArchiveCommentEncoding.GetBytes(comment_);
30853097
using (ZipHelperStream zhs = new ZipHelperStream(workFile.baseStream_))
30863098
{
30873099
zhs.WriteEndOfCentralDirectory(updateCount_, sizeEntries, centralDirOffset, theComment);
@@ -3481,7 +3493,7 @@ private void ReadEntries()
34813493
byte[] comment = new byte[commentSize];
34823494

34833495
StreamUtils.ReadFully(baseStream_, comment);
3484-
comment_ = ZipStrings.ConvertToString(comment);
3496+
comment_ = _stringCodec.ZipArchiveCommentEncoding.GetString(comment);
34853497
}
34863498
else
34873499
{
@@ -3598,11 +3610,13 @@ private void ReadEntries()
35983610
long offset = ReadLEUint();
35993611

36003612
byte[] buffer = new byte[Math.Max(nameLen, commentLen)];
3613+
var entryEncoding = _stringCodec.ZipInputEncoding(bitFlags);
36013614

36023615
StreamUtils.ReadFully(baseStream_, buffer, 0, nameLen);
3603-
string name = ZipStrings.ConvertToStringExt(bitFlags, buffer, nameLen);
3616+
string name = entryEncoding.GetString(buffer, 0, nameLen);
3617+
var unicode = entryEncoding.IsZipUnicode();
36043618

3605-
var entry = new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method)
3619+
var entry = new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method, unicode)
36063620
{
36073621
Crc = crc & 0xffffffffL,
36083622
Size = size & 0xffffffffL,
@@ -3635,7 +3649,7 @@ private void ReadEntries()
36353649
if (commentLen > 0)
36363650
{
36373651
StreamUtils.ReadFully(baseStream_, buffer, 0, commentLen);
3638-
entry.Comment = ZipStrings.ConvertToStringExt(bitFlags, buffer, commentLen);
3652+
entry.Comment = entryEncoding.GetString(buffer, 0, commentLen);
36393653
}
36403654

36413655
entries_[i] = entry;
@@ -3787,6 +3801,7 @@ private static void WriteEncryptionHeader(Stream stream, long crcValue)
37873801
private ZipEntry[] entries_;
37883802
private byte[] key;
37893803
private bool isNewArchive_;
3804+
private readonly StringCodec _stringCodec = new StringCodec();
37903805

37913806
// Default is dynamic which is not backwards compatible and can cause problems
37923807
// with XP's built in compression which cant read Zip64 archives.
@@ -3825,19 +3840,23 @@ private class ZipString
38253840
/// Initialise a <see cref="ZipString"/> with a string.
38263841
/// </summary>
38273842
/// <param name="comment">The textual string form.</param>
3828-
public ZipString(string comment)
3843+
/// <param name="encoding"></param>
3844+
public ZipString(string comment, Encoding encoding)
38293845
{
38303846
comment_ = comment;
38313847
isSourceString_ = true;
3848+
_encoding = encoding;
38323849
}
38333850

38343851
/// <summary>
38353852
/// Initialise a <see cref="ZipString"/> using a string in its binary 'raw' form.
38363853
/// </summary>
38373854
/// <param name="rawString"></param>
3838-
public ZipString(byte[] rawString)
3855+
/// <param name="encoding"></param>
3856+
public ZipString(byte[] rawString, Encoding encoding)
38393857
{
38403858
rawComment_ = rawString;
3859+
_encoding = encoding;
38413860
}
38423861

38433862
#endregion Constructors
@@ -3846,10 +3865,7 @@ public ZipString(byte[] rawString)
38463865
/// Get a value indicating the original source of data for this instance.
38473866
/// True if the source was a string; false if the source was binary data.
38483867
/// </summary>
3849-
public bool IsSourceString
3850-
{
3851-
get { return isSourceString_; }
3852-
}
3868+
public bool IsSourceString => isSourceString_;
38533869

38543870
/// <summary>
38553871
/// Get the length of the comment when represented as raw bytes.
@@ -3894,15 +3910,15 @@ private void MakeTextAvailable()
38943910
{
38953911
if (comment_ == null)
38963912
{
3897-
comment_ = ZipStrings.ConvertToString(rawComment_);
3913+
comment_ = _encoding.GetString(rawComment_);
38983914
}
38993915
}
39003916

39013917
private void MakeBytesAvailable()
39023918
{
39033919
if (rawComment_ == null)
39043920
{
3905-
rawComment_ = ZipStrings.ConvertToArray(comment_);
3921+
rawComment_ = _encoding.GetBytes(comment_);
39063922
}
39073923
}
39083924

@@ -3911,7 +3927,7 @@ private void MakeBytesAvailable()
39113927
/// </summary>
39123928
/// <param name="zipString">The <see cref="ZipString"/> to convert to a string.</param>
39133929
/// <returns>The textual equivalent for the input value.</returns>
3914-
static public implicit operator string(ZipString zipString)
3930+
public static implicit operator string(ZipString zipString)
39153931
{
39163932
zipString.MakeTextAvailable();
39173933
return zipString.comment_;
@@ -3922,6 +3938,7 @@ static public implicit operator string(ZipString zipString)
39223938
private string comment_;
39233939
private byte[] rawComment_;
39243940
private readonly bool isSourceString_;
3941+
private readonly Encoding _encoding;
39253942

39263943
#endregion Instance Fields
39273944
}

src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData)
236236
}
237237
}
238238

239-
byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name);
239+
// TODO: This should be class instanced if used!
240+
var stringCodec = new StringCodec();
241+
byte[] name = stringCodec.ZipInputEncoding(entry.Flags).GetBytes(entry.Name);
240242

241243
if (name.Length > 0xFFFF)
242244
{

0 commit comments

Comments
 (0)