Пример #1
0
        public void DecodingOutputTooSmallRetry()
        {
            Span <byte> source = new byte[1000];

            Base64TestHelper.InitalizeDecodableBytes(source);

            int outputSize   = 240;
            int requiredSize = Base64.GetMaxDecodedFromUtf8Length(source.Length);

            Span <byte> decodedBytes = new byte[outputSize];

            Assert.Equal(OperationStatus.DestinationTooSmall,
                         Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
            int expectedConsumed = decodedBytes.Length / 3 * 4;

            Assert.Equal(expectedConsumed, consumed);
            Assert.Equal(decodedBytes.Length, decodedByteCount);
            Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));

            decodedBytes = new byte[requiredSize - outputSize];
            source       = source.Slice(consumed);
            Assert.Equal(OperationStatus.Done,
                         Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount));
            expectedConsumed = decodedBytes.Length / 3 * 4;
            Assert.Equal(expectedConsumed, consumed);
            Assert.Equal(decodedBytes.Length, decodedByteCount);
            Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
        }
Пример #2
0
        public void BasicDecodingWithFinalBlockFalseInvalidInputLength()
        {
            var rnd = new Random(42);

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

                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitializeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes     = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                int         expectedConsumed = source.Length / 4 * 4; // only consume closest multiple of four since isFinalBlock is false
                int         expectedDecoded  = expectedConsumed / 4 * 3;

                Assert.Equal(OperationStatus.NeedMoreData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock: false));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedDecoded, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
            }
        }
Пример #3
0
        public void BasicDecodingInvalidInputLength()
        {
            var rnd = new Random(42);

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

                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitalizeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes     = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                int         expectedConsumed = numBytes / 4 * 4; // decode input up to the closest multiple of 4
                int         expectedDecoded  = expectedConsumed / 4 * 3;

                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedDecoded, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedDecoded, source, decodedBytes));
            }
        }
Пример #4
0
        public void DecodingInvalidBytes()
        {
            // Invalid Bytes:
            // 0-42
            // 44-46
            // 58-64
            // 91-96
            // 123-255
            byte[] invalidBytes = Base64TestHelper.InvalidBytes;
            Assert.Equal(byte.MaxValue + 1 - 64, invalidBytes.Length); // 192

            for (int j = 0; j < 8; j++)
            {
                Span <byte> source = new byte[8] {
                    50, 50, 50, 50, 80, 80, 80, 80
                };                                                                  // valid input - "2222PPPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];

                for (int i = 0; i < invalidBytes.Length; i++)
                {
                    // Don't test padding (byte 61 i.e. '='), which is tested in DecodingInvalidBytesPadding
                    if (invalidBytes[i] == Base64TestHelper.s_encodingPad)
                    {
                        continue;
                    }

                    // replace one byte with an invalid input
                    source[j] = invalidBytes[i];

                    Assert.Equal(OperationStatus.InvalidData,
                                 Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                    if (j < 4)
                    {
                        Assert.Equal(0, consumed);
                        Assert.Equal(0, decodedByteCount);
                    }
                    else
                    {
                        Assert.Equal(4, consumed);
                        Assert.Equal(3, decodedByteCount);
                        Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
                    }
                }
            }

            // Input that is not a multiple of 4 is considered invalid
            {
                Span <byte> source = new byte[7] {
                    50, 50, 50, 50, 80, 80, 80
                };                                                              // incomplete input - "2222PPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
            }
        }
Пример #5
0
        public void BasicDecodingWithFinalBlockFalseKnownInputInvalid(string inputString, int expectedConsumed, int expectedWritten)
        {
            Span <byte> source       = Encoding.ASCII.GetBytes(inputString);
            Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];

            Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock: false));
            Assert.Equal(expectedConsumed, consumed);
            Assert.Equal(expectedWritten, decodedByteCount);
            Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));
        }
Пример #6
0
        public void DecodingOutputTooSmall()
        {
            for (int numBytes = 5; numBytes < 20; numBytes++)
            {
                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitalizeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes = new byte[3];
                int         consumed, written;
                if (numBytes % 4 != 0)
                {
                    Assert.True(OperationStatus.InvalidData ==
                                Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out written), "Number of Input Bytes: " + numBytes);
                }
                else
                {
                    Assert.True(OperationStatus.DestinationTooSmall ==
                                Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out written), "Number of Input Bytes: " + numBytes);
                }
                int expectedConsumed = 4;
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(decodedBytes.Length, written);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
            }

            // Output too small even with padding characters in the input
            {
                Span <byte> source = new byte[12];
                Base64TestHelper.InitalizeDecodableBytes(source);
                source[10] = Base64TestHelper.s_encodingPad;
                source[11] = Base64TestHelper.s_encodingPad;

                Span <byte> decodedBytes = new byte[6];
                Assert.Equal(OperationStatus.DestinationTooSmall,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int written));
                int expectedConsumed = 8;
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(decodedBytes.Length, written);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
            }

            {
                Span <byte> source = new byte[12];
                Base64TestHelper.InitalizeDecodableBytes(source);
                source[11] = Base64TestHelper.s_encodingPad;

                Span <byte> decodedBytes = new byte[7];
                Assert.Equal(OperationStatus.DestinationTooSmall,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int written));
                int expectedConsumed = 8;
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(6, written);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, 6, source, decodedBytes));
            }
        }
Пример #7
0
        public void DecodeEmptySpan()
        {
            Span <byte> source       = Span <byte> .Empty;
            Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];

            Assert.Equal(OperationStatus.Done,
                         Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
            Assert.Equal(source.Length, consumed);
            Assert.Equal(decodedBytes.Length, decodedByteCount);
            Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, decodedBytes.Length, source, decodedBytes));
        }
Пример #8
0
        public void DecodeGuid()
        {
            Span <byte> source       = new byte[24];
            Span <byte> decodedBytes = Guid.NewGuid().ToByteArray();

            Base64.EncodeToUtf8(decodedBytes, source, out int _, out int _);

            Assert.Equal(OperationStatus.Done, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
            Assert.Equal(24, consumed);
            Assert.Equal(16, decodedByteCount);
            Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, decodedBytes.Length, source, decodedBytes));
        }
Пример #9
0
        public void DecodingOutputTooSmallWithFinalBlockFalse()
        {
            for (int numBytes = 8; numBytes < 20; numBytes++)
            {
                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitializeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes = new byte[4];
                int         consumed, written;
                Assert.True(OperationStatus.DestinationTooSmall ==
                            Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out written, isFinalBlock: false), "Number of Input Bytes: " + numBytes);
                int expectedConsumed = 4;
                int expectedWritten  = 3;
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, written);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));
            }
        }
Пример #10
0
        public void BasicDecoding()
        {
            var rnd = new Random(42);

            for (int i = 0; i < 10; i++)
            {
                int numBytes = rnd.Next(100, 1000 * 1000);
                while (numBytes % 4 != 0)
                {
                    numBytes = rnd.Next(100, 1000 * 1000);
                }
                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitalizeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
                Assert.Equal(source.Length, consumed);
                Assert.Equal(decodedBytes.Length, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, decodedBytes.Length, source, decodedBytes));
            }
        }
Пример #11
0
        public void DecodingInvalidBytesPadding()
        {
            // Only last 2 bytes can be padding, all other occurrence of padding is invalid
            for (int j = 0; j < 7; j++)
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[j] = Base64TestHelper.s_encodingPad;
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                if (j < 4)
                {
                    Assert.Equal(0, consumed);
                    Assert.Equal(0, decodedByteCount);
                }
                else
                {
                    Assert.Equal(4, consumed);
                    Assert.Equal(3, decodedByteCount);
                    Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
                }
            }

            // Invalid input with valid padding
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.s_encodingPad;
                source[7] = Base64TestHelper.s_encodingPad; // invalid input - "2222P*=="
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.s_encodingPad; // invalid input - "2222PP**="
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
            }

            // The last byte or the last 2 bytes being the padding character is valid
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.s_encodingPad;
                source[7] = Base64TestHelper.s_encodingPad; // valid input - "2222PP=="
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                Assert.Equal(source.Length, consumed);
                Assert.Equal(4, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, 4, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.s_encodingPad; // valid input - "2222PPP="
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount));

                Assert.Equal(source.Length, consumed);
                Assert.Equal(5, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, 5, source, decodedBytes));
            }
        }
Пример #12
0
        public void DecodingInvalidBytesPadding(bool isFinalBlock)
        {
            // Only last 2 bytes can be padding, all other occurrence of padding is invalid
            for (int j = 0; j < 7; j++)
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[j] = Base64TestHelper.EncodingPad;
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));

                if (j < 4)
                {
                    Assert.Equal(0, consumed);
                    Assert.Equal(0, decodedByteCount);
                }
                else
                {
                    Assert.Equal(4, consumed);
                    Assert.Equal(3, decodedByteCount);
                    Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
                }
            }

            // Invalid input with valid padding
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.EncodingPad;
                source[7] = Base64TestHelper.EncodingPad; // invalid input - "2222P*=="
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.EncodingPad; // invalid input - "2222PP**="
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount, isFinalBlock));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
            }

            // The last byte or the last 2 bytes being the padding character is valid, if isFinalBlock = true
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.EncodingPad;
                source[7] = Base64TestHelper.EncodingPad; // valid input - "2222PP=="

                OperationStatus expectedStatus   = isFinalBlock ? OperationStatus.Done : OperationStatus.InvalidData;
                int             expectedConsumed = isFinalBlock ? source.Length : 4;
                int             expectedWritten  = isFinalBlock ? 4 : 3;

                Assert.Equal(expectedStatus, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.EncodingPad; // valid input - "2222PPP="

                expectedConsumed = isFinalBlock ? source.Length : 4;
                expectedWritten  = isFinalBlock ? 5 : 3;
                Assert.Equal(expectedStatus, Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount, isFinalBlock));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));
            }
        }