diff --git a/mcs/class/corlib/System.IO/Stream.cs b/mcs/class/corlib/System.IO/Stream.cs index 17c8cc457eb82bc3b2733a00659fb5546c423e09..eeaedd8b15ad1e32f00f20fa69cd2954a8aad11f 100644 --- a/mcs/class/corlib/System.IO/Stream.cs +++ b/mcs/class/corlib/System.IO/Stream.cs @@ -105,6 +105,7 @@ namespace System.IO public virtual void Close () { Dispose (true); + GC.SuppressFinalize (this); } [ComVisible (false)] diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs index 7eb680847ec7e701ba50be60bbabcb14d2c0cf6f..63f310885dc07a607ba01db2757d4e119a0cfab0 100644 --- a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs +++ b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs @@ -109,19 +109,13 @@ namespace System.Security.Cryptography { public void Clear () { - Dispose (true); - GC.SuppressFinalize (this); // not called in Stream.Dispose + Close (); } // LAMESPEC: A CryptoStream can be close in read mode public override void Close () { - // only flush in write mode (bugzilla 46143) - if ((!_flushedFinalBlock) && (_mode == CryptoStreamMode.Write)) - FlushFinalBlock (); - - if (_stream != null) - _stream.Close (); + base.Close (); } public override int Read ([In,Out] byte[] buffer, int offset, int count) @@ -353,6 +347,21 @@ namespace System.Security.Cryptography { protected override void Dispose (bool disposing) { if (!_disposed) { + if (disposing) { + // only flush in write mode (bugzilla 46143) + if (!_flushedFinalBlock) { + if (_mode == CryptoStreamMode.Write) { + FlushFinalBlock (); + } else { + // See bug #644648 + _transform.TransformFinalBlock (new byte [0], 0, 0); + } + _flushedFinalBlock = true; + } + + if (_stream != null) + _stream.Close (); + } _disposed = true; // always cleared for security reason if (_workingBlock != null) diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs index c4bfae156a5d6951f7664c322d1ca5a5a138e445..60746defc1cff1dba0ee6b0f3f54db9130733536 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs @@ -1389,6 +1389,46 @@ namespace MonoTests.System.Security.Cryptography { #endif } + [Test] + public void ReadModeDispose_FinalBlock () + { + using (SHA1 sha1 = SHA1.Create()) { + using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false)) + using (CryptoStream cs = new CryptoStream(mem, sha1, CryptoStreamMode.Read)) + { + } + byte b = sha1.Hash [0]; // This will throw if TransformFinalBlock not called in sha1 + GC.KeepAlive (b); // just the warning... + } + } + + [Test] + public void CustomDisposeCalled () + { + using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false)) { + MyCryptoStream cs; + using (cs = new MyCryptoStream (mem, SHA1.Create())) + { + } + Assert.IsTrue (cs.DisposeCalled, "#1"); + } + } + + class MyCryptoStream : CryptoStream { + public bool DisposeCalled { get; private set;} + + public MyCryptoStream(Stream stream, ICryptoTransform transform) + : base(stream, transform, CryptoStreamMode.Read) + { + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + DisposeCalled = true; + } + } + class ExpandTransform : ICryptoTransform { public bool CanReuseTransform {