Esempio n. 1
0
        public void Basic_decoding_with_known_input_isFinalBlock_false___Done(string input, int expectedWritten)
        {
            var sut = new Base64Encoder();
            ReadOnlySpan <T> encoded;

            if (typeof(T) == typeof(byte))
            {
                ReadOnlySpan <byte> tmp = Encoding.ASCII.GetBytes(input);
                encoded = MemoryMarshal.Cast <byte, T>(tmp);
            }
            else if (typeof(T) == typeof(char))
            {
                encoded = MemoryMarshal.Cast <char, T>(input.AsSpan());  // .AsSpan() for net48
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Span <byte>     data   = new byte[sut.GetMaxDecodedLength(encoded.Length)];
            OperationStatus status = sut.DecodeCore(encoded, data, out int consumed, out int written, isFinalBlock: false);

            byte[] actualData = data.Slice(0, written).ToArray();

            Assert.Multiple(() =>
            {
                Assert.AreEqual(OperationStatus.Done, status);
                Assert.AreEqual(input.Length, consumed);
                Assert.AreEqual(expectedWritten, written);

                byte[] expectedData = Convert.FromBase64String(input);
                CollectionAssert.AreEqual(expectedData, actualData);
            });
        }
Esempio n. 2
0
        public void Malformed_input___status_InvalidData(string input, bool isFinalBlock, int expectedConsumed, int expectedWritten)
        {
            var sut = new Base64Encoder();
            ReadOnlySpan <T> encoded;

            if (typeof(T) == typeof(byte))
            {
                ReadOnlySpan <byte> tmp = Encoding.ASCII.GetBytes(input);
                encoded = MemoryMarshal.Cast <byte, T>(tmp);
            }
            else if (typeof(T) == typeof(char))
            {
                encoded = MemoryMarshal.Cast <char, T>(input.AsSpan());  // AsSpan() for net48
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Span <byte>     data   = new byte[sut.GetMaxDecodedLength(encoded.Length)];
            OperationStatus status = sut.DecodeCore(encoded, data, out int consumed, out int written, isFinalBlock);

            Assert.Multiple(() =>
            {
                Assert.AreEqual(OperationStatus.InvalidData, status);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);
            });
        }
Esempio n. 3
0
        public void Padding_can_only_be_last_two___InvalidData(bool isFinalBlock)
        {
            var sut = new Base64Encoder();

            for (int j = 0; j < 7; ++j)
            {
                Span <byte> tmp = stackalloc byte[8] {
                    50, 50, 50, 50, 80, 80, 80, 80
                };                                                                        // valid input - "2222PPPP"
                Span <T> encoded = stackalloc T[tmp.Length];
                T        padding;

                if (typeof(T) == typeof(byte))
                {
                    padding = (T)(object)Base64Encoder.EncodingPad;
                    encoded = MemoryMarshal.Cast <byte, T>(tmp);
                }
                else if (typeof(T) == typeof(char))
                {
                    padding = (T)(object)(char)Base64Encoder.EncodingPad;
                    for (int i = 0; i < tmp.Length; ++i)
                    {
                        encoded[i] = (T)(object)(char)tmp[i];
                    }
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                byte[] data = new byte[sut.GetMaxDecodedLength(encoded.Length)];

                encoded[j] = padding;

                OperationStatus status = sut.DecodeCore <T>(encoded, data, out int consumed, out int written, isFinalBlock);

                Assert.Multiple(() =>
                {
                    Assert.AreEqual(OperationStatus.InvalidData, status, "j = {0}", j);

                    if (j < 4)
                    {
                        Assert.AreEqual(0, consumed, "j = {0}", j);
                        Assert.AreEqual(0, written, "j = {0}", j);
                    }
                    else
                    {
                        Assert.AreEqual(4, consumed, "j = {0}", j);
                        Assert.AreEqual(3, written, "j = {0}", j);
#if NETCOREAPP
                        string actual = Convert.ToBase64String(data.AsSpan(0, 3));
#else
                        string actual = Convert.ToBase64String(data, 0, 3);
#endif
                        Assert.AreEqual("2222", actual, "j = {0}", j);
                    }
                });
            }
        }
Esempio n. 4
0
        public void EncodedLength_is_negative___throws_ArgumentOutOfRange([Values(-1, int.MinValue)] int encodedLength)
        {
            var sut = new Base64Encoder();

            Exception exception = Assert.Catch(() => sut.GetMaxDecodedLength(encodedLength));

            Assert.Multiple(() =>
            {
                Assert.IsInstanceOf <ArgumentOutOfRangeException>(exception);
                string msg = $"The 'encodedLength' is outside the allowed range by the base64 standard. It must be >= 4.";
                StringAssert.StartsWith(msg, exception.Message);
            });
        }
Esempio n. 5
0
        public void EncodedLength_1_to_50_given___correct_max_decoded_len()
        {
            var sut = new Base64Encoder();

            Assert.Multiple(() =>
            {
                for (int i = 1; i < 50; ++i)
                {
                    var data      = new byte[i];
                    string base64 = Convert.ToBase64String(data);

                    int actual = sut.GetMaxDecodedLength(base64.Length);

                    Assert.GreaterOrEqual(actual, i);
                }
            });
        }
Esempio n. 6
0
        public void Padding_is_only_valid_for_isFinalBlock_true(
            [Values("2222PP==", "2222PPP=")] string encodedString,
            [Values(true, false)]            bool isFinalBlock)
        {
            var sut = new Base64Encoder();
            ReadOnlySpan <T> encoded;

            if (typeof(T) == typeof(byte))
            {
                ReadOnlySpan <byte> tmp = Encoding.ASCII.GetBytes(encodedString);
                encoded = MemoryMarshal.Cast <byte, T>(tmp);
            }
            else if (typeof(T) == typeof(char))
            {
                encoded = MemoryMarshal.Cast <char, T>(encodedString.AsSpan());  // .AsSpan() for net48
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Span <byte>     data   = new byte[sut.GetMaxDecodedLength(encoded.Length)];
            OperationStatus status = sut.DecodeCore(encoded, data, out int consumed, out int written, isFinalBlock);

            byte[] actualData = data.Slice(0, written).ToArray();

            Assert.Multiple(() =>
            {
                OperationStatus expectedStatus = isFinalBlock ? OperationStatus.Done : OperationStatus.InvalidData;
                int expectedConsumed           = isFinalBlock ? 8 : 4;
                int expectedWritten            = isFinalBlock
                    ? encodedString.Count(c => c == '=') == 2 ? 4 : 5
                    : 3;

                Assert.AreEqual(expectedStatus, status);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);

                byte[] expectedData = Convert.FromBase64String(encodedString.Substring(0, consumed));
                CollectionAssert.AreEqual(expectedData, actualData);
            });
        }
Esempio n. 7
0
        public void Basic_decoding_with_invalid_input_length_isFinalBlock_false___NeedMoreData()
        {
            var sut = new Base64Encoder();
            var rnd = new Random(42);

            for (int i = 0; i < 10; ++i)
            {
                int encodedLength;
                do
                {
                    encodedLength = rnd.Next(100, 1_000 * 1_000);
                }while (encodedLength % 4 == 0);      // ensure we have invalid length

                ReadOnlySpan <T> encoded;

                if (typeof(T) == typeof(byte))
                {
                    ReadOnlySpan <byte> tmp = Enumerable.Repeat((byte)'a', encodedLength).ToArray();
                    encoded = MemoryMarshal.Cast <byte, T>(tmp);
                }
                else if (typeof(T) == typeof(char))
                {
                    ReadOnlySpan <char> tmp = Enumerable.Repeat('a', encodedLength).ToArray();
                    encoded = MemoryMarshal.Cast <char, T>(tmp);
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                Span <byte>     data   = new byte[sut.GetMaxDecodedLength(encoded.Length)];
                OperationStatus status = sut.DecodeCore(encoded, data, out int consumed, out int written, isFinalBlock: false);

                Assert.AreEqual(OperationStatus.NeedMoreData, status, "fail at i = {0}", i);
            }
        }
Esempio n. 8
0
        public void Invalid_bytes___InvalidData(bool isFinalBlock)
        {
            var sut = new Base64Encoder();

            // Don't test padding ('=') here -> -1
            byte[] invalidBytes = TestHelper.GetInvalidBytes(Base64Encoder.DecodingMap)
                                  .Where(b => b != Base64Encoder.EncodingPad)
                                  .ToArray();

            Assume.That(invalidBytes.Length + 1, Is.EqualTo(byte.MaxValue - 64 + 1));   // +1 for padding on the left side
            T[] invalid = new T[invalidBytes.Length - 1];

            if (typeof(T) == typeof(byte))
            {
                invalid = invalidBytes.Select(b => (T)(object)b).ToArray();
            }
            else if (typeof(T) == typeof(char))
            {
                invalid = invalidBytes.Select(b => (T)(object)(char)b).ToArray();
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            for (int j = 0; j < 8; ++j)
            {
                Span <byte> tmp = stackalloc byte[8] {
                    50, 50, 50, 50, 80, 80, 80, 80
                };                                                                        // valid input - "2222PPPP"
                Span <T> encoded = stackalloc T[tmp.Length];

                if (typeof(T) == typeof(byte))
                {
                    encoded = MemoryMarshal.Cast <byte, T>(tmp);
                }
                else if (typeof(T) == typeof(char))
                {
                    for (int i = 0; i < tmp.Length; ++i)
                    {
                        encoded[i] = (T)(object)(char)tmp[i];
                    }
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                byte[] data = new byte[sut.GetMaxDecodedLength(encoded.Length)];

                for (int i = 0; i < invalid.Length; ++i)
                {
                    encoded[j] = invalid[i];

                    OperationStatus status = sut.DecodeCore <T>(encoded, data, out int consumed, out int written, isFinalBlock);

                    Assert.Multiple(() =>
                    {
                        Assert.AreEqual(OperationStatus.InvalidData, status, "j = {0}, i = {1}", j, i);

                        if (j < 4)
                        {
                            Assert.AreEqual(0, consumed, "j = {0}, i = {1}", j, i);
                            Assert.AreEqual(0, written, "j = {0}, i = {1}", j, i);
                        }
                        else
                        {
                            Assert.AreEqual(4, consumed, "j = {0}, i = {1}", j, i);
                            Assert.AreEqual(3, written, "j = {0}, i = {1}", j, i);
#if NETCOREAPP
                            string actual = Convert.ToBase64String(data.AsSpan(0, 3));
#else
                            string actual = Convert.ToBase64String(data, 0, 3);
#endif
                            Assert.AreEqual("2222", actual, "j = {0}, i = {1}", j, i);
                        }
                    });
                }
            }
        }