Example #1
0
        public void DestinationLength_too_small_but_retry___OK(bool isFinalBlock)
        {
            const int dataLength = 300;
            const int destLength = 350;

            var         sut          = new Base64UrlEncoder();
            Span <byte> data         = new byte[dataLength];
            Span <T>    encoded      = new T[destLength];
            int         requitedSize = sut.GetEncodedLength(dataLength);

            OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written, isFinalBlock);

            Assert.Multiple(() =>
            {
                const int expectedConsumed = destLength / 4 * 3;
                const int expectedWritten  = expectedConsumed / 3 * 4;

                Assert.AreEqual(OperationStatus.DestinationTooSmall, status);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);
            });

            data    = data.Slice(consumed);
            encoded = new T[sut.GetEncodedLength(data.Length)];
            status  = sut.EncodeCore(data, encoded, out consumed, out written, isFinalBlock);

            Assert.AreEqual(OperationStatus.Done, status);
            Assert.AreEqual(data.Length, consumed);
            Assert.AreEqual(encoded.Length, written);
        }
Example #2
0
        public void Buffer_chain_various_length_encode()
        {
            var sut = new Base64UrlEncoder();
            var rnd = new Random(0);

            for (int i = 2; i < 200; ++i)
            {
                var data = new byte[i];
                rnd.NextBytes(data);

                int      encodedLength = sut.GetEncodedLength(data.Length);
                Span <T> encoded       = new T[encodedLength];

                int             partialLength = data.Length / 2;
                OperationStatus status        = sut.EncodeCore(data.AsSpan(0, partialLength), encoded, out int consumed, out int written1, isFinalBlock: false);
                Assert.AreEqual(partialLength % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData, status, "fail at i = {0}", i);

                status = sut.EncodeCore(data.AsSpan(consumed), encoded.Slice(written1), out consumed, out int written2, isFinalBlock: true);
                Assert.AreEqual(OperationStatus.Done, status, "fail at i = {0}", i);
                Assert.AreEqual(encodedLength, written1 + written2, "fail at i = {0}", i);

                Span <T> expected = new T[encodedLength];
                sut.EncodeCore(data, expected, out int _, out int _);

                string encodedText;
                string expectedText;

                if (typeof(T) == typeof(byte))
                {
                    Span <byte> encodedBytes  = MemoryMarshal.AsBytes(encoded);
                    Span <byte> expectedBytes = MemoryMarshal.AsBytes(expected);
#if NETCOREAPP
                    encodedText  = Encoding.ASCII.GetString(encodedBytes);
                    expectedText = Encoding.ASCII.GetString(expectedBytes);
#else
                    encodedText  = Encoding.ASCII.GetString(encodedBytes.ToArray());
                    expectedText = Encoding.ASCII.GetString(expectedBytes.ToArray());
#endif
                }
                else if (typeof(T) == typeof(char))
                {
#if NETCOREAPP
                    encodedText  = new string(MemoryMarshal.Cast <T, char>(encoded));
                    expectedText = new string(MemoryMarshal.Cast <T, char>(expected));
#else
                    encodedText  = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray());
                    expectedText = new string(MemoryMarshal.Cast <T, char>(expected).ToArray());
#endif
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                Assert.AreEqual(expectedText, encodedText, "fail at i = {0}", i);
            }
        }
Example #3
0
        public void Data_of_various_length_isFinalBlock_false()
        {
            var sut   = new Base64UrlEncoder();
            var bytes = new byte[byte.MaxValue + 1];

            for (int i = 0; i < bytes.Length; ++i)
            {
                bytes[i] = (byte)(255 - i);
            }

            for (int i = 0; i < 256; ++i)
            {
                Span <byte>     source  = bytes.AsSpan(0, i + 1);
                Span <T>        encoded = new T[sut.GetEncodedLength(source.Length)];
                OperationStatus status  = sut.EncodeCore(source, encoded, out int consumed, out int written, isFinalBlock: false);

                OperationStatus expectedStatus   = source.Length % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData;
                int             expectedConsumed = source.Length / 3 * 3;
                int             expectedWritten  = expectedConsumed / 3 * 4;

                Assert.AreEqual(expectedStatus, status, "fail at length = {0}", i + 1);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);

                string encodedText;
                source  = source.Slice(0, consumed);
                encoded = encoded.Slice(0, written);

                if (typeof(T) == typeof(byte))
                {
                    Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded);
#if NETCOREAPP
                    encodedText = Encoding.ASCII.GetString(encodedBytes);
#else
                    encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray());
#endif
                }
                else if (typeof(T) == typeof(char))
                {
#if NETCOREAPP
                    encodedText = new string(MemoryMarshal.Cast <T, char>(encoded));
#else
                    encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray());
#endif
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }
#if NETCOREAPP
                string expected = Convert.ToBase64String(source);
#else
                string expected = Convert.ToBase64String(source.ToArray());
#endif
                Assert.AreEqual(expected.ToBase64Url(), encodedText);
            }
        }
Example #4
0
        public void Invalid_data_various_length___status_InvalidData()
        {
            var sut = new Base64UrlEncoder();
            var rnd = new Random(0);

            for (int i = 2; i < 200; ++i)
            {
                var data = new byte[i];
                rnd.NextBytes(data);

                int             encodedLength = sut.GetEncodedLength(data.Length);
                Span <T>        encoded       = new T[encodedLength];
                OperationStatus status        = sut.EncodeCore(data, encoded, out int consumed, out int written);
                Assume.That(status, Is.EqualTo(OperationStatus.Done));
                Assume.That(consumed, Is.EqualTo(data.Length));
                Assume.That(written, Is.EqualTo(encodedLength));

                int decodedLength;

                if (typeof(T) == typeof(byte))
                {
                    Span <byte> tmp = MemoryMarshal.AsBytes(encoded);
                    decodedLength = sut.GetDecodedLength(tmp);

                    // Insert invalid data, just before eventual padding
                    tmp[tmp.Length - 3] = (byte)'~';
                }
                else if (typeof(T) == typeof(char))
                {
                    Span <char> tmp = MemoryMarshal.Cast <T, char>(encoded);
                    decodedLength = sut.GetDecodedLength(tmp);

                    // Insert invalid data, just before eventual padding
                    tmp[tmp.Length - 3] = '~';
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                Span <byte> decoded = new byte[decodedLength];

                status = sut.DecodeCore <T>(encoded, decoded, out consumed, out written);

                // Invalid data is in the last 4 bytes, so everyting up to the last multiple of 4 is read.
                int expectedConsumed = (encoded.Length - 3) / 4 * 4;
                int expectedWritten  = expectedConsumed / 4 * 3;

                Assert.Multiple(() =>
                {
                    Assert.AreEqual(OperationStatus.InvalidData, status);
                    Assert.AreEqual(expectedConsumed, consumed, "Fail at i = {0}", i);
                    Assert.AreEqual(expectedWritten, written, "Fail at i = {0}", i);
                });
            }
        }
Example #5
0
        public void Basic_encoding_with_known_input_isFinalBlock_false(int numBytes, string expectedText, int expectedConsumed, int expectedWritten)
        {
            var sut = new Base64UrlEncoder();

            Span <byte> source = new byte[numBytes];

            for (int i = 0; i < source.Length; ++i)
            {
                source[i] = (byte)(i + 1);
            }

            Span <T> encoded = new T[sut.GetEncodedLength(source.Length)];

            OperationStatus status         = sut.EncodeCore(source, encoded, out int consumed, out int written, isFinalBlock: false);
            OperationStatus expectedStatus = source.Length % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData;

            Assert.Multiple(() =>
            {
                Assert.AreEqual(expectedStatus, status);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);
            });

            string encodedText;

            source  = source.Slice(0, consumed);
            encoded = encoded.Slice(0, written);

            if (typeof(T) == typeof(byte))
            {
                Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded);
#if NETCOREAPP
                encodedText = Encoding.ASCII.GetString(encodedBytes);
#else
                encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray());
#endif
            }
            else if (typeof(T) == typeof(char))
            {
#if NETCOREAPP
                encodedText = new string(MemoryMarshal.Cast <T, char>(encoded));
#else
                encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray());
#endif
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Assert.AreEqual(expectedText.ToBase64Url(), encodedText);
        }
Example #6
0
        public void Empty_input(bool isFinalBlock)
        {
            var sut = new Base64UrlEncoder();
            ReadOnlySpan <byte> source = ReadOnlySpan <byte> .Empty;

            Span <T>        encoded = new T[sut.GetEncodedLength(source.Length)];
            OperationStatus status  = sut.EncodeCore(source, encoded, out int consumed, out int written, isFinalBlock);

            Assert.AreEqual(OperationStatus.Done, status);
            Assert.AreEqual(0, consumed);
            Assert.AreEqual(0, written);
            Assert.IsTrue(encoded.IsEmpty);
        }
Example #7
0
        public void DestinationLength_too_small___status_DestinationTooSmall(int dataLength)
        {
            var      sut     = new Base64UrlEncoder();
            var      data    = new byte[dataLength];
            Span <T> encoded = new T[1];

            OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written);

            Assert.Multiple(() =>
            {
                Assert.AreEqual(OperationStatus.DestinationTooSmall, status);
                Assert.AreEqual(0, written);
            });
        }
Example #8
0
        public void Guid___ssse3_event_fired()
        {
            var sut  = new Base64UrlEncoder();
            var data = Guid.NewGuid().ToByteArray();

            int      encodedLength = sut.GetEncodedLength(data.Length);
            Span <T> encoded       = new T[encodedLength];

            bool ssse3Executed = false;

            Base64UrlEncoder.Ssse3Encoded += (s, e) => ssse3Executed = true;

            OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written);

            Assert.IsTrue(ssse3Executed);
        }
Example #9
0
        public void Invalid_data_various_length___status_InvalidData()
        {
            var sut = new Base64UrlEncoder();
            var rnd = new Random(0);

            for (int i = 2; i < 200; ++i)
            {
                var data = new byte[i];
                rnd.NextBytes(data);

                int             encodedLength = sut.GetEncodedLength(data.Length);
                Span <T>        encoded       = new T[encodedLength];
                OperationStatus status        = sut.EncodeCore(data, encoded, out int consumed, out int written);
                Assume.That(status, Is.EqualTo(OperationStatus.Done));
                Assume.That(consumed, Is.EqualTo(data.Length));
                Assume.That(written, Is.EqualTo(encodedLength));

                int decodedLength;

                if (typeof(T) == typeof(byte))
                {
                    Span <byte> tmp = MemoryMarshal.AsBytes(encoded);
                    decodedLength = sut.GetDecodedLength(tmp);

                    // Insert invalid data
                    tmp[0] = (byte)'~';
                }
                else if (typeof(T) == typeof(char))
                {
                    Span <char> tmp = MemoryMarshal.Cast <T, char>(encoded);
                    decodedLength = sut.GetDecodedLength(tmp);

                    // Insert invalid data
                    tmp[0] = '~';
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                Span <byte> decoded = new byte[decodedLength];

                status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _);

                Assert.AreEqual(OperationStatus.InvalidData, status);
            }
        }
Example #10
0
        public void Buffer_chain_various_length_decode()
        {
            var sut = new Base64UrlEncoder();
            var rnd = new Random(0);

            for (int i = 2; i < 200; ++i)
            {
                var data = new byte[i];
                rnd.NextBytes(data);

                int             encodedLength = sut.GetEncodedLength(data.Length);
                Span <T>        encoded       = new T[encodedLength];
                OperationStatus status        = sut.EncodeCore(data, encoded, out int consumed, out int written);
                Assume.That(status, Is.EqualTo(OperationStatus.Done), "fail at i = {0}", i);
                Assume.That(consumed, Is.EqualTo(data.Length), "fail at i = {0}", i);
                Assume.That(written, Is.EqualTo(encodedLength), "fail at i = {0}", i);

                //int decodedLength  = sut.GetDecodedLength(encodedLength);

                int decodedLength;

                if (typeof(T) == typeof(byte))
                {
                    decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded));
                }
                else if (typeof(T) == typeof(char))
                {
                    decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded));
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }

                Span <byte> decoded = new byte[decodedLength];

                int partialLength = encoded.Length / 2;
                status = sut.DecodeCore <T>(encoded.Slice(0, partialLength), decoded, out consumed, out int written1, isFinalBlock: false);
                Assert.AreEqual(partialLength % 4 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData, status, "fail at i = {0}", i);

                status = sut.DecodeCore <T>(encoded.Slice(consumed), decoded.Slice(written1), out consumed, out int written2, isFinalBlock: true);
                Assert.AreEqual(OperationStatus.Done, status, "fail at i = {0}", i);
                Assert.AreEqual(decodedLength, written1 + written2, "fail at i = {0}", i);

                CollectionAssert.AreEqual(data, decoded.ToArray(), "fail at i = {0}", i);
            }
        }
Example #11
0
        public void Large_data___avx2_event_fired()
        {
            Assume.That(Avx2.IsSupported);

            var sut  = new Base64UrlEncoder();
            var data = new byte[50];
            var rnd  = new Random(0);

            rnd.NextBytes(data);

            int             encodedLength = sut.GetEncodedLength(data.Length);
            Span <T>        encoded       = new T[encodedLength];
            OperationStatus status        = sut.EncodeCore(data, encoded, out int consumed, out int written);

            Assume.That(status, Is.EqualTo(OperationStatus.Done));
            Assume.That(consumed, Is.EqualTo(data.Length));
            Assume.That(written, Is.EqualTo(encodedLength));

            int decodedLength;

            if (typeof(T) == typeof(byte))
            {
                decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded));
            }
            else if (typeof(T) == typeof(char))
            {
                decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded));
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Span <byte> decoded = new byte[decodedLength];

            bool avxExecuted = false;

            Base64UrlEncoder.Avx2Decoded += (s, e) => avxExecuted = true;

            status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _);
            Assume.That(status, Is.EqualTo(OperationStatus.Done));

            Assert.IsTrue(avxExecuted);
        }
Example #12
0
        public void DestiantationLength_large_but_too_small___status_DestinationTooSmall()
        {
            const int dataLength = 300;
            const int destLength = 40;

            var      sut     = new Base64UrlEncoder();
            var      data    = new byte[dataLength];
            Span <T> encoded = new T[destLength];

            OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written);

            Assert.Multiple(() =>
            {
                const int expectedConsumed = destLength / 4 * 3;
                const int expectedWritten  = expectedConsumed / 3 * 4;

                Assert.AreEqual(OperationStatus.DestinationTooSmall, status);
                Assert.AreEqual(expectedConsumed, consumed);
                Assert.AreEqual(expectedWritten, written);
            });
        }
Example #13
0
        public void Guid___ssse3_event_fired()
        {
            var sut  = new Base64UrlEncoder();
            var data = Guid.NewGuid().ToByteArray();

            int             encodedLength = sut.GetEncodedLength(data.Length);
            Span <T>        encoded       = new T[encodedLength];
            OperationStatus status        = sut.EncodeCore(data, encoded, out int consumed, out int written);

            Assume.That(status, Is.EqualTo(OperationStatus.Done));
            Assume.That(consumed, Is.EqualTo(data.Length));
            Assume.That(written, Is.EqualTo(encodedLength));

            int decodedLength;

            if (typeof(T) == typeof(byte))
            {
                decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded));
            }
            else if (typeof(T) == typeof(char))
            {
                decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded));
            }
            else
            {
                throw new NotSupportedException(); // just in case new types are introduced in the future
            }

            Span <byte> decoded = new byte[decodedLength];

            bool ssse3Executed = false;

            Base64UrlEncoder.Ssse3Decoded += (s, e) => ssse3Executed = true;

            status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _);
            Assume.That(status, Is.EqualTo(OperationStatus.Done));

            Assert.IsTrue(ssse3Executed);
        }
Example #14
0
        public void Data_of_various_length___roundtrips_correclty()
        {
            var sut   = new Base64UrlEncoder();
            var bytes = new byte[byte.MaxValue + 1];

            for (int i = 0; i < bytes.Length; ++i)
            {
                bytes[i] = (byte)(255 - i);
            }

            for (int i = 0; i < 256; ++i)
            {
                Span <byte>     source  = bytes.AsSpan(0, i + 1);
                Span <T>        encoded = new T[sut.GetEncodedLength(source.Length)];
                OperationStatus status  = sut.EncodeCore(source, encoded, out int consumed, out int written);

                Assert.AreEqual(OperationStatus.Done, status);
                Assert.AreEqual(source.Length, consumed);
                Assert.AreEqual(encoded.Length, written);

                string encodedText;
                int    decodedLength;

                if (typeof(T) == typeof(byte))
                {
                    Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded);
#if NETCOREAPP
                    encodedText = Encoding.ASCII.GetString(encodedBytes);
#else
                    encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray());
#endif
                    decodedLength = sut.GetDecodedLength(encodedBytes);
                }
                else if (typeof(T) == typeof(char))
                {
#if NETCOREAPP
                    encodedText = new string(MemoryMarshal.Cast <T, char>(encoded));
#else
                    encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray());
#endif
                    decodedLength = sut.GetDecodedLength(encodedText.AsSpan());
                }
                else
                {
                    throw new NotSupportedException(); // just in case new types are introduced in the future
                }
#if NETCOREAPP
                string expectedText = Convert.ToBase64String(source);
#else
                string expectedText = Convert.ToBase64String(source.ToArray());
#endif
                Assert.AreEqual(expectedText.ToBase64Url(), encodedText);

                Span <byte> decoded = new byte[decodedLength];
                status = sut.DecodeCore <T>(encoded, decoded, out consumed, out written);

                Assert.AreEqual(OperationStatus.Done, status);
                Assert.AreEqual(encoded.Length, consumed);
                Assert.AreEqual(decodedLength, written);

                CollectionAssert.AreEqual(source.ToArray(), decoded.ToArray());
            }
        }