Switch to compiler-tester
[mono.git] / mcs / class / corlib / System.Security.Cryptography / FromBase64Transform.cs
index 375c42d5510e7d73d84d3c7504fbb611d3a461eb..59b71d2587ef6d082269fcb316b108307559c9a9 100644 (file)
@@ -4,40 +4,58 @@
 // Author:
 //   Sergey Chaban (serge@wildwestsoftware.com)
 //
+// Copyright (C) 2004-2005 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
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
 
-using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
 
 namespace System.Security.Cryptography {
 
        [Serializable]
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        public enum FromBase64TransformMode : int {
                IgnoreWhiteSpaces,
                DoNotIgnoreWhiteSpaces
        }
 
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        public class FromBase64Transform : ICryptoTransform {
 
                private FromBase64TransformMode mode;
-               private byte [] accumulator;
-               private byte [] filterBuffer;
+               private byte[] accumulator;
+               private byte[] filterBuffer;
                private int accPtr;
                private bool m_disposed;
 
-
-               /// <summary>
-               ///  Creates a new instance of the decoder
-               ///  with the default transformation mode (IgnoreWhiteSpaces).
-               /// </summary>
                public FromBase64Transform ()
                        : this (FromBase64TransformMode.IgnoreWhiteSpaces)
                {
                }
 
-
-               /// <summary>
-               ///  Creates a new instance of the decoder
-               ///  with the specified transformation mode.
-               /// </summary>
                public FromBase64Transform (FromBase64TransformMode mode)
                {
                        this.mode = mode;
@@ -52,42 +70,20 @@ namespace System.Security.Cryptography {
                        Dispose (false);
                }
 
-
-               /// <summary>
-               /// </summary>
                public bool CanTransformMultipleBlocks {
-                       get {
-                               return false;
-                       }
+                       get { return false; }
                }
 
                public virtual bool CanReuseTransform {
-                       get { return false; }
+                       get { return true; }
                }
 
-               /// <summary>
-               ///  Returns the input block size for the Base64 decoder.
-               /// </summary>
-               /// <remarks>
-               ///  The input block size for Base64 decoder is always 1 byte.
-               /// </remarks>
                public int InputBlockSize {
-                       get {
-                               return 1;
-                       }
+                       get { return 1; }
                }
 
-
-               /// <summary>
-               ///  Returns the output block size for the Base64 decoder.
-               /// </summary>
-               /// <remarks>
-               ///  The value returned by this property is always 3.
-               /// </remarks>
                public int OutputBlockSize {
-                       get {
-                               return 3;
-                       }
+                       get { return 3; }
                }
 
                public void Clear() 
@@ -104,9 +100,17 @@ namespace System.Security.Cryptography {
                protected virtual void Dispose (bool disposing) 
                {
                        if (!m_disposed) {
+                               // zeroize data
+                               if (accumulator != null)
+                                       Array.Clear (accumulator, 0, accumulator.Length);
+                               if (filterBuffer != null)
+                                       Array.Clear (filterBuffer, 0, filterBuffer.Length);
+
                                // dispose unmanaged objects
                                if (disposing) {
                                        // dispose managed objects
+                                       accumulator = null;
+                                       filterBuffer = null;
                                }
                                m_disposed = true;
                        }
@@ -117,7 +121,7 @@ namespace System.Security.Cryptography {
                        int end = offset + count;
                        int len = filterBuffer.Length;
                        int ptr = 0;
-                       byte [] filter = this.filterBuffer;
+                       byte[] filter = this.filterBuffer;
 
                        for (int i = offset; i < end; i++) {
                                byte b = buffer [i];
@@ -125,7 +129,7 @@ namespace System.Security.Cryptography {
                                        if (ptr >= len) {
                                                len <<= 1;
                                                this.filterBuffer = new byte [len];
-                                               Array.Copy(filter, 0, this.filterBuffer, 0, len >> 1);
+                                               Buffer.BlockCopy (filter, 0, this.filterBuffer, 0, len >> 1);
                                                filter = this.filterBuffer;
                                        }
                                        filter [ptr++] = b;
@@ -135,15 +139,29 @@ namespace System.Security.Cryptography {
                        return ptr;
                }
 
+               private byte[] lookupTable; 
+
+               private byte lookup (byte input)
+               {
+                       if (input >= lookupTable.Length) {
+                               throw new FormatException (
+                                       Locale.GetText ("Invalid character in a Base-64 string."));
+                       }
+
+                       byte ret = lookupTable [input];
+                       if (ret == Byte.MaxValue) {
+                               throw new FormatException (
+                                       Locale.GetText ("Invalid character in a Base-64 string."));
+                       }
 
-               private int DoTransform (byte [] inputBuffer,
-                                        int inputOffset,
-                                        int inputCount,
-                                        byte [] outputBuffer,
-                                        int outputOffset)
+                       return ret;
+               }
+
+               private int DoTransform (byte [] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
                {
                        int full = inputCount >> 2;
-                       if (full == 0) return 0;
+                       if (full == 0)
+                               return 0;
 
                        int rem = 0;
 
@@ -152,16 +170,17 @@ namespace System.Security.Cryptography {
                                --full;
                        }
 
-                       if (inputBuffer[inputCount - 2] == (byte)'=') ++rem;
+                       if (inputBuffer[inputCount - 2] == (byte)'=')
+                               ++rem;
 
-                       byte [] lookup = Base64Table.DecodeTable;
+                       lookupTable = Base64Constants.DecodeTable;
                        int b0,b1,b2,b3;
 
                        for (int i = 0; i < full; i++) {
-                               b0 = lookup [inputBuffer [inputOffset++]];
-                               b1 = lookup [inputBuffer [inputOffset++]];
-                               b2 = lookup [inputBuffer [inputOffset++]];
-                               b3 = lookup [inputBuffer [inputOffset++]];
+                               b0 = lookup (inputBuffer [inputOffset++]);
+                               b1 = lookup (inputBuffer [inputOffset++]);
+                               b2 = lookup (inputBuffer [inputOffset++]);
+                               b3 = lookup (inputBuffer [inputOffset++]);
 
                                outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
                                outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
@@ -174,35 +193,47 @@ namespace System.Security.Cryptography {
                        case 0:
                                break;
                        case 1:
-                               b0 = lookup [inputBuffer [inputOffset++]];
-                               b1 = lookup [inputBuffer [inputOffset++]];
-                               b2 = lookup [inputBuffer [inputOffset++]];
+                               b0 = lookup (inputBuffer [inputOffset++]);
+                               b1 = lookup (inputBuffer [inputOffset++]);
+                               b2 = lookup (inputBuffer [inputOffset++]);
                                outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
                                outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
                                res += 2;
                                break;
                        case 2:
-                               b0 = lookup [inputBuffer [inputOffset++]];
-                               b1 = lookup [inputBuffer [inputOffset++]];
+                               b0 = lookup (inputBuffer [inputOffset++]);
+                               b1 = lookup (inputBuffer [inputOffset++]);
                                outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
                                ++res;
                                break;
-                       default:
-                               break;
                        }
 
                        return res;
                }
 
+               private void CheckInputParameters (byte[] inputBuffer, int inputOffset, int inputCount)
+               {
+                       if (inputBuffer == null)
+                               throw new ArgumentNullException ("inputBuffer");
+                       if (inputOffset < 0)
+                               throw new ArgumentOutOfRangeException ("inputOffset", "< 0");
+                       if (inputCount > inputBuffer.Length)
+                               throw new OutOfMemoryException ("inputCount " + Locale.GetText ("Overflow"));
+                       if (inputOffset > inputBuffer.Length - inputCount)
+                               throw new ArgumentException ("inputOffset", Locale.GetText ("Overflow"));
+                       if (inputCount < 0)
+                               throw new OverflowException ("inputCount < 0");
+               }
 
-               /// <summary>
-               /// </summary>
-               public int TransformBlock (byte [] inputBuffer,
-                                                  int inputOffset,
-                                                  int inputCount,
-                                                  byte [] outputBuffer,
-                                                  int outputOffset)
+               public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
                {
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("FromBase64Transform");
+                       // LAMESPEC: undocumented exceptions
+                       CheckInputParameters (inputBuffer, inputOffset, inputCount);
+                       if ((outputBuffer == null) || (outputOffset < 0) || (inputCount > outputBuffer.Length - outputOffset))
+                               throw new FormatException ("outputBuffer");
+
                        int n;
                        byte [] src;
                        int srcOff;
@@ -212,39 +243,39 @@ namespace System.Security.Cryptography {
                                n = Filter (inputBuffer, inputOffset, inputCount);
                                src = filterBuffer;
                                srcOff = 0;
-                       } else {
+                       }
+                       else {
                                n = inputCount;
                                src = inputBuffer;
                                srcOff = inputOffset;
                        }
 
-
                        int count = accPtr + n;
 
                        if (count < 4) {
-                               Array.Copy (src, srcOff, accumulator, accPtr, n);
+                               Buffer.BlockCopy (src, srcOff, accumulator, accPtr, n);
                                accPtr = count;
-                       } else {
-                               byte [] tmpBuff = new byte [count];
-                               Array.Copy (accumulator, 0, tmpBuff, 0, accPtr);
-                               Array.Copy (src, srcOff, tmpBuff, accPtr, n);
+                       }
+                       else {
+                               byte[] tmpBuff = new byte [count];
+                               Buffer.BlockCopy (accumulator, 0, tmpBuff, 0, accPtr);
+                               Buffer.BlockCopy (src, srcOff, tmpBuff, accPtr, n);
                                accPtr = count & 3;
-                               Array.Copy (src, srcOff + (n - accPtr), accumulator, 0, accPtr);
-                               res = DoTransform (tmpBuff, 0, count & (~3), outputBuffer, outputOffset);
+                               Buffer.BlockCopy (src, srcOff + (n - accPtr), accumulator, 0, accPtr);
+                               res = DoTransform (tmpBuff, 0, count & (~3), outputBuffer, outputOffset) ;
                        }
 
-
                        return res;
                }
 
-
-               /// <summary>
-               /// </summary>
-               public byte [] TransformFinalBlock (byte [] inputBuffer,
-                                                           int inputOffset,
-                                                           int inputCount)
+               public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
                {
-                       byte [] src;
+                       if (m_disposed)
+                               throw new ObjectDisposedException ("FromBase64Transform");
+                       // LAMESPEC: undocumented exceptions
+                       CheckInputParameters (inputBuffer, inputOffset, inputCount);
+
+                       byte[] src;
                        int srcOff;
                        int n;
 
@@ -252,35 +283,33 @@ namespace System.Security.Cryptography {
                                n = Filter (inputBuffer, inputOffset, inputCount);
                                src = filterBuffer;
                                srcOff = 0;
-                       } else {
+                       }
+                       else {
                                n = inputCount;
                                src = inputBuffer;
                                srcOff = inputOffset;
                        }
 
-
                        int dataLen = accPtr + n;
-                       byte [] tmpBuf = new byte [dataLen];
+                       byte[] tmpBuf = new byte [dataLen];
 
                        int resLen = ((dataLen) >> 2) * 3;
-                       byte [] res = new byte [resLen];
-
-                       Array.Copy (accumulator, 0, tmpBuf, 0, accPtr);
-                       Array.Copy (src, srcOff, tmpBuf, accPtr, n);
+                       byte[] res = new byte [resLen];
 
+                       Buffer.BlockCopy (accumulator, 0, tmpBuf, 0, accPtr);
+                       Buffer.BlockCopy (src, srcOff, tmpBuf, accPtr, n);
+                       
                        int actLen = DoTransform (tmpBuf, 0, dataLen, res, 0);
-
                        accPtr = 0;
 
                        if (actLen < resLen) {
-                               byte [] newres = new byte [actLen];
+                               byte[] newres = new byte [actLen];
 
-                               Array.Copy (res, newres, actLen);
+                               Buffer.BlockCopy (res, 0, newres, 0, actLen);
                                return newres;
-                       } else
-                       return res;
+                       } 
+                       else
+                               return res;
                }
-
-       } // FromBase64Transform
-
-} // System.Security.Cryptography
+       }
+}