< Summary

Information
Class: DotnetFuzzing.Fuzzers.Base64UrlFuzzer
Assembly: DotnetFuzzing
File(s): D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\Base64UrlFuzzer.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 94
Coverable lines: 94
Total lines: 136
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
FuzzTarget(...)0%660%

File(s)

D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\Base64UrlFuzzer.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Buffers;
 5using System.Buffers.Text;
 6using System.Formats.Asn1;
 7using System.Reflection;
 8
 9namespace DotnetFuzzing.Fuzzers
 10{
 11    internal sealed class Base64UrlFuzzer : IFuzzer
 12    {
 013        public string[] TargetAssemblies => [];
 14
 015        public string[] TargetCoreLibPrefixes => ["System.Buffers.Text"];
 16
 17        public void FuzzTarget(ReadOnlySpan<byte> bytes)
 018        {
 019            int encodedLength = Base64Url.GetEncodedLength(bytes.Length);
 020            int maxDecodedLength = Base64Url.GetMaxDecodedLength(encodedLength);
 21
 022            using PooledBoundedMemory<byte> inputPoisoned = PooledBoundedMemory<byte>.Rent(bytes, PoisonPagePlacement.Af
 023            using PooledBoundedMemory<char> destPoisoned = PooledBoundedMemory<char>.Rent(encodedLength, PoisonPagePlace
 024            using PooledBoundedMemory<byte> decoderDestPoisoned = PooledBoundedMemory<byte>.Rent(maxDecodedLength, Poiso
 25
 026            Span<byte> input = inputPoisoned.Span;
 027            Span<char> encoderDest = destPoisoned.Span;
 028            Span<byte> decoderDest = decoderDestPoisoned.Span;
 29
 030            { // IsFinalBlock = true
 031                OperationStatus status = Base64Url.EncodeToChars(input, encoderDest, out int bytesConsumed, out int byte
 32
 033                Assert.Equal(OperationStatus.Done, status);
 034                Assert.Equal(bytes.Length, bytesConsumed);
 035                Assert.Equal(true, encodedLength == bytesEncoded);
 36
 037                string encodedString = Base64Url.EncodeToString(input);
 038                Assert.Equal(encodedString, new string(encoderDest));
 39
 040                status = Base64Url.DecodeFromChars(encoderDest, decoderDest, out int bytesRead, out int bytesDecoded);
 41
 042                Assert.Equal(OperationStatus.Done, status);
 043                Assert.Equal(bytes.Length, bytesDecoded);
 044                Assert.Equal(bytesEncoded, bytesRead);
 045                Assert.SequenceEqual(bytes, decoderDest.Slice(0, bytesDecoded));
 046            }
 47
 048            { // IsFinalBlock = false
 049                encoderDest.Clear();
 050                decoderDest.Clear();
 051                OperationStatus status = Base64Url.EncodeToChars(input, encoderDest, out int bytesConsumed, out int byte
 052                Span<char> decodeInput = encoderDest.Slice(0, bytesEncoded);
 53
 054                if (bytes.Length % 3 == 0)
 055                {
 056                    Assert.Equal(OperationStatus.Done, status);
 057                    Assert.Equal(bytes.Length, bytesConsumed);
 058                    Assert.Equal(true, encodedLength == bytesEncoded);
 59
 060                    status = Base64Url.DecodeFromChars(decodeInput, decoderDest, out int bytesRead, out int bytesDecoded
 61
 062                    Assert.Equal(OperationStatus.Done, status);
 063                    Assert.Equal(bytes.Length, bytesDecoded);
 064                    Assert.Equal(bytesEncoded, bytesRead);
 065                    Assert.SequenceEqual(bytes, decoderDest.Slice(0, bytesDecoded));
 066                }
 67                else
 068                {
 069                    Assert.Equal(OperationStatus.NeedMoreData, status);
 070                    Assert.Equal(true, input.Length / 3 * 4 == bytesEncoded);
 71
 072                    status = Base64Url.DecodeFromChars(decodeInput, decoderDest, out int bytesRead, out int bytesDecoded
 73
 074                    if (decodeInput.Length % 4 == 0)
 075                    {
 076                        Assert.Equal(OperationStatus.Done, status);
 077                        Assert.Equal(bytesConsumed, bytesDecoded);
 078                        Assert.Equal(bytesEncoded, bytesRead);
 079                    }
 80                    else
 081                    {
 082                        Assert.Equal(OperationStatus.NeedMoreData, status);
 083                    }
 84
 085                    Assert.SequenceEqual(bytes.Slice(0, bytesDecoded), decoderDest.Slice(0, bytesDecoded));
 086                }
 087            }
 88
 089            { // Encode / decode in place
 090                using PooledBoundedMemory<byte> destPoisoned2 = PooledBoundedMemory<byte>.Rent(encodedLength, PoisonPage
 091                Span<byte> tryEncode = destPoisoned2.Span;
 092                input.CopyTo(tryEncode);
 93
 094                Assert.Equal(true, Base64Url.TryEncodeToUtf8InPlace(tryEncode, input.Length, out int bytesEncoded));
 095                Assert.Equal(encodedLength, bytesEncoded);
 96
 097                int bytesDecoded = Base64Url.DecodeFromUtf8InPlace(tryEncode);
 98
 099                Assert.Equal(bytes.Length, bytesDecoded);
 0100                Assert.SequenceEqual(bytes, tryEncode.Slice(0, bytesDecoded));
 0101            }
 102
 0103            { // Decode the random input directly, Assert IsValid result matches with decoded result
 0104                decoderDest.Clear();
 0105                if (Base64Url.IsValid(input, out int decodedLength))
 0106                {
 0107                    maxDecodedLength = Base64Url.GetMaxDecodedLength(input.Length);
 0108                    OperationStatus status = Base64Url.DecodeFromUtf8(input, decoderDest, out int bytesRead, out int byt
 0109                    Assert.Equal(OperationStatus.Done, status);
 0110                    Assert.Equal(input.Length, bytesRead);
 0111                    Assert.Equal(decodedLength, bytesDecoded);
 0112                    Assert.Equal(true, maxDecodedLength >= bytesDecoded);
 113
 0114                    Span<byte> tryDecode = new byte[maxDecodedLength];
 0115                    Assert.Equal(true, Base64Url.TryDecodeFromUtf8(input, tryDecode, out bytesDecoded));
 0116                    Assert.Equal(decodedLength, bytesDecoded);
 0117                    Assert.SequenceEqual<byte>(tryDecode.Slice(0, bytesDecoded), decoderDest.Slice(0, bytesDecoded));
 118
 0119                    int decoded = Base64Url.DecodeFromUtf8InPlace(input);
 0120                    Assert.Equal(OperationStatus.Done, status);
 0121                    Assert.Equal(bytesDecoded, decoded);
 0122                    Assert.SequenceEqual<byte>(input.Slice(0, decoded), decoderDest.Slice(0, bytesDecoded));
 0123                }
 124                else
 0125                {
 0126                    Assert.Equal(OperationStatus.InvalidData, Base64Url.DecodeFromUtf8(input, decoderDest, out int _, ou
 127                    try
 0128                    {
 0129                        Assert.Equal(0, Base64Url.DecodeFromUtf8InPlace(input));
 0130                    }
 0131                    catch (FormatException) { /* DecodeFromUtf8InPlace would throw FormatException for InvalidData*/ }
 0132                }
 0133            }
 0134        }
 135    }
 136}