Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit de2ac75

Browse files
committed
Merge pull request #2048 from stephentoub/compression_cc
Improve test coverage of System.IO.Compression
2 parents 74b5c22 + b853d88 commit de2ac75

File tree

4 files changed

+260
-111
lines changed

4 files changed

+260
-111
lines changed

src/System.IO.Compression/src/System/IO/Compression/DeflateStream.cs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,32 @@ public DeflateStream(Stream stream, CompressionMode mode, bool leaveOpen)
4242
{
4343
if (stream == null)
4444
throw new ArgumentNullException("stream");
45-
46-
if (CompressionMode.Compress != mode && CompressionMode.Decompress != mode)
47-
throw new ArgumentException(SR.ArgumentOutOfRange_Enum, "mode");
48-
49-
_stream = stream;
50-
_mode = mode;
51-
_leaveOpen = leaveOpen;
52-
53-
switch (_mode)
45+
46+
switch (mode)
5447
{
5548
case CompressionMode.Decompress:
56-
57-
if (!_stream.CanRead)
49+
if (!stream.CanRead)
5850
{
5951
throw new ArgumentException(SR.NotReadableStream, "stream");
6052
}
61-
6253
_inflater = new Inflater();
63-
6454
break;
6555

6656
case CompressionMode.Compress:
67-
68-
if (!_stream.CanWrite)
57+
if (!stream.CanWrite)
6958
{
7059
throw new ArgumentException(SR.NotWriteableStream, "stream");
7160
}
72-
7361
_deflater = CreateDeflater(null);
74-
7562
break;
76-
} // switch (_mode)
7763

64+
default:
65+
throw new ArgumentException(SR.ArgumentOutOfRange_Enum, "mode");
66+
}
67+
68+
_stream = stream;
69+
_mode = mode;
70+
_leaveOpen = leaveOpen;
7871
_buffer = new byte[DefaultBufferSize];
7972
}
8073

@@ -120,22 +113,16 @@ private static IDeflater CreateDeflater(CompressionLevel? compressionLevel)
120113
deflatorType = s_forcedTestingDeflaterType;
121114
#endif
122115

123-
switch (deflatorType)
116+
if (deflatorType == WorkerType.ZLib)
124117
{
125-
case WorkerType.Managed:
126-
return new DeflaterManaged();
127-
128-
case WorkerType.ZLib:
129-
if (compressionLevel.HasValue)
130-
return new DeflaterZLib(compressionLevel.Value);
131-
else
132-
return new DeflaterZLib();
133-
134-
default:
135-
// We do not expect this to ever be thrown.
136-
// But this is better practice than returning null.
137-
Environment.FailFast("Program entered an unexpected state.");
138-
return null; // we'll not reach here
118+
return compressionLevel.HasValue ?
119+
new DeflaterZLib(compressionLevel.Value) :
120+
new DeflaterZLib();
121+
}
122+
else
123+
{
124+
Debug.Assert(deflatorType == WorkerType.Managed);
125+
return new DeflaterManaged();
139126
}
140127
}
141128

@@ -221,7 +208,6 @@ public override long Position
221208
public override void Flush()
222209
{
223210
EnsureNotDisposed();
224-
return;
225211
}
226212

227213
public override Task FlushAsync(CancellationToken cancellationToken)
@@ -273,9 +259,15 @@ public override int Read(byte[] array, int offset, int count)
273259
Debug.Assert(_inflater.NeedsInput(), "We can only run into this case if we are short of input");
274260

275261
int bytes = _stream.Read(_buffer, 0, _buffer.Length);
276-
if (bytes == 0)
262+
if (bytes <= 0)
277263
{
278-
break; //Do we want to throw an exception here?
264+
break;
265+
}
266+
else if (bytes > _buffer.Length)
267+
{
268+
// The stream is either malicious or poorly implemented and returned a number of
269+
// bytes larger than the buffer supplied to it.
270+
throw new InvalidDataException(SR.GenericInvalidData);
279271
}
280272

281273
_inflater.SetInput(_buffer, 0, bytes);
@@ -386,6 +378,12 @@ private async Task<int> ReadAsyncCore(Task<int> readTask, byte[] array, int offs
386378
// This indicates the base stream has received EOF
387379
return 0;
388380
}
381+
else if (bytesRead > _buffer.Length)
382+
{
383+
// The stream is either malicious or poorly implemented and returned a number of
384+
// bytes larger than the buffer supplied to it.
385+
throw new InvalidDataException(SR.GenericInvalidData);
386+
}
389387

390388
cancellationToken.ThrowIfCancellationRequested();
391389

src/System.IO.Compression/src/System/IO/Compression/ZLibNative.cs

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System.Diagnostics;
45
using System.Diagnostics.Contracts;
56
using System.Runtime.InteropServices;
67
using System.Security;
7-
using System.Text;
88

99
namespace System.IO.Compression
1010
{
@@ -221,7 +221,6 @@ public enum State { NotInitialized, InitializedForDeflate, InitializedForInflate
221221

222222

223223
public ZLibStreamHandle()
224-
225224
: base(new IntPtr(-1), true)
226225
{
227226
_zStream = new ZStream();
@@ -236,7 +235,7 @@ public ZLibStreamHandle()
236235
public override bool IsInvalid
237236
{
238237
[SecurityCritical]
239-
get { return DangerousGetHandle() == new IntPtr(-1); }
238+
get { return handle == new IntPtr(-1); }
240239
}
241240

242241
public State InitializationState
@@ -250,9 +249,6 @@ public State InitializationState
250249
[SecurityCritical]
251250
protected override bool ReleaseHandle()
252251
{
253-
// We are in a finalizer thread at the end of the App and the finalization of the dynamically loaded ZLib happend
254-
// to be scheduled first. In such case we have no hope of properly freeing zStream. If the process is dying - we
255-
// do not care. In other cases somethign went badly wrong anyway:
256252
switch (InitializationState)
257253
{
258254
case State.NotInitialized: return true;
@@ -412,33 +408,11 @@ public ErrorCode InflateEnd()
412408
public string GetErrorMessage()
413409
{
414410
// This can work even after XxflateEnd().
415-
416-
if (ZNullPtr.Equals(_zStream.msg))
417-
return String.Empty;
418-
419-
unsafe
420-
{
421-
StringBuilder sb = new StringBuilder();
422-
SByte* pMessage = (SByte*)_zStream.msg;
423-
char c;
424-
do
425-
{
426-
c = (char)*pMessage;
427-
pMessage++;
428-
sb.Append(c);
429-
} while ((sbyte)c != 0);
430-
431-
return sb.ToString();
432-
}
411+
return _zStream.msg != ZNullPtr ? Marshal.PtrToStringAnsi(_zStream.msg) : string.Empty;
433412
}
434413

435414
#endregion // Expose ZLib functions for use by user / Fx code (add more as required)
436415

437-
[SecurityCritical]
438-
internal static Int32 ZLibCompileFlags()
439-
{
440-
return Interop.zlib.zlibCompileFlags();
441-
}
442416
} // class ZLibStreamHandle
443417

444418
#endregion // ZLib Stream Handle type
@@ -447,15 +421,6 @@ internal static Int32 ZLibCompileFlags()
447421
#region public factory methods for ZLibStreamHandle
448422

449423

450-
[SecurityCritical]
451-
public static ErrorCode CreateZLibStreamForDeflate(out ZLibStreamHandle zLibStreamHandle)
452-
{
453-
return CreateZLibStreamForDeflate(out zLibStreamHandle,
454-
CompressionLevel.DefaultCompression, Deflate_DefaultWindowBits,
455-
Deflate_DefaultMemLevel, CompressionStrategy.DefaultStrategy);
456-
}
457-
458-
459424
[SecurityCritical]
460425
public static ErrorCode CreateZLibStreamForDeflate(out ZLibStreamHandle zLibStreamHandle,
461426
CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy)
@@ -465,13 +430,6 @@ public static ErrorCode CreateZLibStreamForDeflate(out ZLibStreamHandle zLibStre
465430
}
466431

467432

468-
[SecurityCritical]
469-
public static ErrorCode CreateZLibStreamForInflate(out ZLibStreamHandle zLibStreamHandle)
470-
{
471-
return CreateZLibStreamForInflate(out zLibStreamHandle, Deflate_DefaultWindowBits);
472-
}
473-
474-
475433
[SecurityCritical]
476434
public static ErrorCode CreateZLibStreamForInflate(out ZLibStreamHandle zLibStreamHandle, int windowBits)
477435
{
@@ -481,15 +439,5 @@ public static ErrorCode CreateZLibStreamForInflate(out ZLibStreamHandle zLibStre
481439

482440
#endregion // public factory methods for ZLibStreamHandle
483441

484-
485-
#region public utility APIs
486-
487-
[SecurityCritical]
488-
public static Int32 ZLibCompileFlags()
489-
{
490-
return ZLibStreamHandle.ZLibCompileFlags();
491-
}
492-
#endregion // public utility APIs
493-
494442
} // internal class ZLibNative
495443
} // namespace System.IO.Compression

0 commit comments

Comments
 (0)