X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Security.Cryptography%2FCryptoStream.cs;h=9190921da57d3338c2ef4f645b34e17d55cd9ec7;hb=a5b3f56d50d09f37c6eaedc7e6971e3f63f7ac80;hp=28511eec1b188f35b13439e594222453907814e5;hpb=9d61782c6e2392d7ceec2006b35be582598a70ae;p=mono.git diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs index 28511eec1b1..9190921da57 100644 --- a/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs +++ b/mcs/class/corlib/System.Security.Cryptography/CryptoStream.cs @@ -6,7 +6,7 @@ // Sebastien Pouliot (sebastien@ximian.com) // // Portions (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// Copyright (C) 2004-2005, 2007 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -145,10 +145,13 @@ namespace System.Security.Cryptography { Locale.GetText ("buffer overflow")); } // for some strange reason ObjectDisposedException isn't throw - // instead we get a ArgumentNullException (probably from an internal method) if (_workingBlock == null) { - throw new ArgumentNullException ( - Locale.GetText ("object _disposed")); +#if NET_2_0 + return 0; +#else + // instead we get a ArgumentNullException (probably from an internal method) + throw new ArgumentNullException (Locale.GetText ("CryptoStream was disposed.")); +#endif } int result = 0; @@ -172,7 +175,7 @@ namespace System.Security.Cryptography { int transformed = 0; // load a new block - _workingCount = _stream.Read (_workingBlock, 0, _workingBlock.Length); + _workingCount = _stream.Read (_workingBlock, 0, _transform.InputBlockSize); _endOfStream = (_workingCount < _transform.InputBlockSize); if (!_endOfStream) { @@ -195,11 +198,14 @@ namespace System.Security.Cryptography { length += transformed; _transformedCount += transformed; } - byte[] input = _transform.TransformFinalBlock (_waitingBlock, 0, _waitingCount); - transformed = input.Length; - Buffer.BlockCopy (input, 0, _transformedBlock, _transformedCount, input.Length); - // zeroize this last block - Array.Clear (input, 0, input.Length); + if (!_flushedFinalBlock) { + byte[] input = _transform.TransformFinalBlock (_waitingBlock, 0, _waitingCount); + transformed = input.Length; + Buffer.BlockCopy (input, 0, _transformedBlock, _transformedCount, input.Length); + // zeroize this last block + Array.Clear (input, 0, input.Length); + _flushedFinalBlock = true; + } } length += transformed; @@ -252,6 +258,11 @@ namespace System.Security.Cryptography { Locale.GetText ("buffer overflow")); } + if (_stream == null) + throw new ArgumentNullException ("inner stream was diposed"); + + int buffer_length = count; + // partial block (in progress) if ((_partialCount > 0) && (_partialCount != _transform.InputBlockSize)) { int remainder = _transform.InputBlockSize - _partialCount; @@ -273,25 +284,25 @@ namespace System.Security.Cryptography { } if (_transform.CanTransformMultipleBlocks) { - // transform all except the last block (which may be the last block - // of the stream and require TransformFinalBlock) - int numBlock = ((_partialCount + count) / _transform.InputBlockSize); - int multiSize = (numBlock * _transform.InputBlockSize); - if (numBlock > 0) { - byte[] multiBlocks = new byte [multiSize]; - int len = _transform.TransformBlock (buffer, offset, multiSize, multiBlocks, 0); - _stream.Write (multiBlocks, 0, len); - // copy last block into _currentBlock - _partialCount = count - multiSize; - Buffer.BlockCopy (buffer, offset + multiSize, _workingBlock, 0, _partialCount); + // get the biggest multiple of InputBlockSize in count (without mul or div) + int size = (count & ~(_transform.OutputBlockSize - 1)); + int rem = (count & (_transform.OutputBlockSize - 1)); + // avoid reallocating memory at each call (reuse same buffer whenever possible) + if (_workingBlock.Length < size) { + Array.Clear (_workingBlock, 0, _workingBlock.Length); + _workingBlock = new byte [size]; } - else { - Buffer.BlockCopy (buffer, offset, _workingBlock, _partialCount, count); - _partialCount += count; + + if (size > 0) { + int len = _transform.TransformBlock (buffer, offset, size, _workingBlock, 0); + _stream.Write (_workingBlock, 0, len); } + + if (rem > 0) + Buffer.BlockCopy (buffer, buffer_length - rem, _workingBlock, 0, rem); + _partialCount = rem; count = 0; // the last block, if any, is in _workingBlock - } - else { + } else { int len = Math.Min (_transform.InputBlockSize - _partialCount, count); Buffer.BlockCopy (buffer, bufferPos, _workingBlock, _partialCount, len); bufferPos += len; @@ -311,15 +322,17 @@ namespace System.Security.Cryptography { public void FlushFinalBlock () { - if (_flushedFinalBlock) { - throw new NotSupportedException ( - Locale.GetText ("This method cannot be called twice.")); - } - if (_mode != CryptoStreamMode.Write) { - throw new NotSupportedException ( - Locale.GetText ("cannot flush a non-writeable CryptoStream")); - } - + if (_flushedFinalBlock) + throw new NotSupportedException (Locale.GetText ("This method cannot be called twice.")); +#if NET_2_0 + if (_disposed) + throw new NotSupportedException (Locale.GetText ("CryptoStream was disposed.")); + if (_mode != CryptoStreamMode.Write) + return; +#else + if (_mode != CryptoStreamMode.Write) + throw new NotSupportedException (Locale.GetText ("cannot flush a non-writeable CryptoStream")); +#endif _flushedFinalBlock = true; byte[] finalBuffer = _transform.TransformFinalBlock (_workingBlock, 0, _partialCount); if (_stream != null) {