From 7912621a54c2ed646bf0684a97323d8e6fb3f077 Mon Sep 17 00:00:00 2001 From: Gonzalo Paniagua Javier Date: Thu, 7 Oct 2010 21:15:55 -0400 Subject: [PATCH] Buffer sizes workingBlock should be the InputBlockSize and currentBlock the OutputBlockSize. Allocate currentBlock lazily. Test contributed by Bassam Tabbara. Fixes bug #644740. --- .../CryptoStream.cs | 14 ++++----- .../CryptoStreamTest.cs | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs index 3c4890d6105..48f3794f8cb 100644 --- a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs +++ b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs @@ -71,14 +71,7 @@ namespace System.Security.Cryptography { _mode = mode; _disposed = false; if (transform != null) { - if (mode == CryptoStreamMode.Read) { - _currentBlock = new byte [transform.InputBlockSize]; - _workingBlock = new byte [transform.InputBlockSize]; - } - else if (mode == CryptoStreamMode.Write) { - _currentBlock = new byte [transform.OutputBlockSize]; - _workingBlock = new byte [transform.OutputBlockSize]; - } + _workingBlock = new byte [transform.InputBlockSize]; } } @@ -250,7 +243,7 @@ namespace System.Security.Cryptography { } if (_stream == null) - throw new ArgumentNullException ("inner stream was diposed"); + throw new ArgumentNullException ("inner stream was disposed"); int buffer_length = count; @@ -267,6 +260,9 @@ namespace System.Security.Cryptography { int bufferPos = offset; while (count > 0) { if (_partialCount == _transform.InputBlockSize) { + if (_currentBlock == null) + _currentBlock = new byte [_transform.OutputBlockSize]; + // use partial block to avoid (re)allocation int len = _transform.TransformBlock (_workingBlock, 0, _partialCount, _currentBlock, 0); _stream.Write (_currentBlock, 0, len); diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs index 8d306d3e6e2..580fac8e107 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs @@ -1457,6 +1457,16 @@ namespace MonoTests.System.Security.Cryptography { CryptoStream cs = new CryptoStream (Stream.Null, SHA1.Create (), (CryptoStreamMode) 0xff); } + [Test] + public void OutputBlock_Smaller () + { + // The OutputBlockSize is smaller than the InputBlockSize + using (CryptoStream cs = new CryptoStream(Stream.Null, new MyCryptAlgorithm(), CryptoStreamMode.Write)) { + byte[] buffer = new byte[512 * 1024]; + cs.Write(buffer, 0, buffer.Length); + } + } + class MyCryptoStream : CryptoStream { public bool DisposeCalled { get; private set;} @@ -1629,6 +1639,25 @@ namespace MonoTests.System.Security.Cryptography { } } + class MyCryptAlgorithm : ICryptoTransform { + public bool CanReuseTransform { get { return true; } } + public bool CanTransformMultipleBlocks { get { return false; } } + public int InputBlockSize { get { return 128 * 1024; } } + public int OutputBlockSize { get { return 64 * 1024; } } + + public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) + { + return this.OutputBlockSize; + } + + public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) + { + return new byte[this.OutputBlockSize]; + } + + public void Dispose() {} + } + class MyStream : Stream { public bool FlushCounterEnabled; public int FlushCounter; -- GitLab