Skip to content

Commit cc8dd78

Browse files
authored
fix(zip): dont fail test on 0 sizes and descriptor (#736)
1 parent 71fe846 commit cc8dd78

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs

+24
Original file line numberDiff line numberDiff line change
@@ -472,4 +472,28 @@ public static class ZipConstants
472472

473473
#endregion Header Signatures
474474
}
475+
476+
/// <summary>
477+
/// GeneralBitFlags helper extensions
478+
/// </summary>
479+
public static class GenericBitFlagsExtensions
480+
{
481+
/// <summary>
482+
/// Efficiently check if any of the <see cref="GeneralBitFlags">flags</see> are set without enum un-/boxing
483+
/// </summary>
484+
/// <param name="target"></param>
485+
/// <param name="flags"></param>
486+
/// <returns>Returns whether any of flags are set</returns>
487+
public static bool HasAny(this GeneralBitFlags target, GeneralBitFlags flags)
488+
=> ((int)target & (int)flags) != 0;
489+
490+
/// <summary>
491+
/// Efficiently check if all the <see cref="GeneralBitFlags">flags</see> are set without enum un-/boxing
492+
/// </summary>
493+
/// <param name="target"></param>
494+
/// <param name="flags"></param>
495+
/// <returns>Returns whether the flags are all set</returns>
496+
public static bool HasAll(this GeneralBitFlags target, GeneralBitFlags flags)
497+
=> ((int)target & (int)flags) == (int)flags;
498+
}
475499
}

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

+16-16
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
11151115
}
11161116

11171117
var extractVersion = (short)(ReadLEUshort() & 0x00ff);
1118-
var localFlags = (short)ReadLEUshort();
1118+
var localFlags = (GeneralBitFlags)ReadLEUshort();
11191119
var compressionMethod = (short)ReadLEUshort();
11201120
var fileTime = (short)ReadLEUshort();
11211121
var fileDate = (short)ReadLEUshort();
@@ -1142,15 +1142,15 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
11421142
size = localExtraData.ReadLong();
11431143
compressedSize = localExtraData.ReadLong();
11441144

1145-
if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0)
1145+
if (localFlags.HasAny(GeneralBitFlags.Descriptor))
11461146
{
11471147
// These may be valid if patched later
1148-
if ((size != -1) && (size != entry.Size))
1148+
if ((size > 0) && (size != entry.Size))
11491149
{
11501150
throw new ZipException("Size invalid for descriptor");
11511151
}
11521152

1153-
if ((compressedSize != -1) && (compressedSize != entry.CompressedSize))
1153+
if ((compressedSize > 0) && (compressedSize != entry.CompressedSize))
11541154
{
11551155
throw new ZipException("Compressed size invalid for descriptor");
11561156
}
@@ -1181,7 +1181,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
11811181
throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion));
11821182
}
11831183

1184-
if ((localFlags & (int)(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0)
1184+
if (localFlags.HasAny(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked))
11851185
{
11861186
throw new ZipException("The library does not support the zip version required to extract this entry");
11871187
}
@@ -1213,21 +1213,21 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
12131213
var localEncoding = _stringCodec.ZipInputEncoding(localFlags);
12141214

12151215
// Local entry flags dont have reserved bit set on.
1216-
if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0)
1216+
if (localFlags.HasAny(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15))
12171217
{
12181218
throw new ZipException("Reserved bit flags cannot be set.");
12191219
}
12201220

12211221
// Encryption requires extract version >= 20
1222-
if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20))
1222+
if (localFlags.HasAny(GeneralBitFlags.Encrypted) && extractVersion < 20)
12231223
{
12241224
throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion));
12251225
}
12261226

12271227
// Strong encryption requires encryption flag to be set and extract version >= 50.
1228-
if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0)
1228+
if (localFlags.HasAny(GeneralBitFlags.StrongEncryption))
12291229
{
1230-
if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0)
1230+
if (!localFlags.HasAny(GeneralBitFlags.Encrypted))
12311231
{
12321232
throw new ZipException("Strong encryption flag set but encryption flag is not set");
12331233
}
@@ -1239,13 +1239,13 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
12391239
}
12401240

12411241
// Patched entries require extract version >= 27
1242-
if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27))
1242+
if (localFlags.HasAny(GeneralBitFlags.Patched) && extractVersion < 27)
12431243
{
12441244
throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion));
12451245
}
12461246

12471247
// Central header flags match local entry flags.
1248-
if (localFlags != entry.Flags)
1248+
if ((int)localFlags != entry.Flags)
12491249
{
12501250
throw new ZipException("Central header/local header flags mismatch");
12511251
}
@@ -1262,23 +1262,23 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
12621262
}
12631263

12641264
// Strong encryption and extract version match
1265-
if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0)
1265+
if (localFlags.HasAny(GeneralBitFlags.StrongEncryption))
12661266
{
12671267
if (extractVersion < 62)
12681268
{
12691269
throw new ZipException("Strong encryption flag set but version not high enough");
12701270
}
12711271
}
12721272

1273-
if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0)
1273+
if (localFlags.HasAny(GeneralBitFlags.HeaderMasked))
12741274
{
12751275
if ((fileTime != 0) || (fileDate != 0))
12761276
{
12771277
throw new ZipException("Header masked set but date/time values non-zero");
12781278
}
12791279
}
12801280

1281-
if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0)
1281+
if (!localFlags.HasAny(GeneralBitFlags.Descriptor))
12821282
{
12831283
if (crcValue != (uint)entry.Crc)
12841284
{
@@ -1348,7 +1348,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
13481348

13491349
// Size can be verified only if it is known in the local header.
13501350
// it will always be known in the central header.
1351-
if (((localFlags & (int)GeneralBitFlags.Descriptor) == 0) ||
1351+
if (!localFlags.HasAny(GeneralBitFlags.Descriptor) ||
13521352
((size > 0 || compressedSize > 0) && entry.Size > 0))
13531353
{
13541354
if ((size != 0)
@@ -2507,7 +2507,7 @@ private void CopyBytes(ZipUpdate update, Stream destination, Stream source,
25072507
/// <returns>The descriptor size, zero if there isn't one.</returns>
25082508
private static int GetDescriptorSize(ZipUpdate update, bool includingSignature)
25092509
{
2510-
if (!((GeneralBitFlags)update.Entry.Flags).HasFlag(GeneralBitFlags.Descriptor))
2510+
if (!((GeneralBitFlags)update.Entry.Flags).HasAny(GeneralBitFlags.Descriptor))
25112511
return 0;
25122512

25132513
var descriptorWithSignature = update.Entry.LocalHeaderRequiresZip64

0 commit comments

Comments
 (0)