< Summary

Information
Class: DotnetFuzzing.Fuzzers.IPAddressFuzzer
Assembly: DotnetFuzzing
File(s): D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\IPAddressFuzzer.cs
Line coverage
97%
Covered lines: 66
Uncovered lines: 2
Coverable lines: 68
Total lines: 107
Line coverage: 97%
Branch coverage
100%
Covered branches: 24
Total branches: 24
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
FuzzTarget(...)100%44100%
TestValidInput(System.ReadOnlySpan`1<System.Byte>,System.String)100%44100%
TestUri(System.String)100%1616100%

File(s)

D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\IPAddressFuzzer.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.Net;
 6using System.Net.Sockets;
 7using System.Runtime.InteropServices;
 8using System.Text;
 9using System.Text.Unicode;
 10
 11namespace DotnetFuzzing.Fuzzers
 12{
 13    internal sealed class IPAddressFuzzer : IFuzzer
 14    {
 015        public string[] TargetAssemblies => ["System.Net.Primitives", "System.Private.Uri"];
 016        public string[] TargetCoreLibPrefixes => [];
 17
 18        public void FuzzTarget(ReadOnlySpan<byte> bytes)
 114819        {
 114820            using var poisonedBytes = PooledBoundedMemory<byte>.Rent(bytes, PoisonPagePlacement.After);
 114821            using var poisonedChars = PooledBoundedMemory<char>.Rent(MemoryMarshal.Cast<byte, char>(bytes), PoisonPagePl
 22
 114823            if (IPAddress.IsValidUtf8(poisonedBytes.Span))
 56624            {
 56625                TestValidInput(bytes: poisonedBytes.Span);
 56626            }
 27            else
 58228            {
 58229                Assert.False(IPAddress.TryParse(poisonedBytes.Span, out _));
 58230            }
 31
 114832            if (IPAddress.IsValid(poisonedChars.Span))
 933            {
 934                TestValidInput(chars: poisonedChars.Span.ToString());
 935            }
 36            else
 113937            {
 113938                Assert.False(IPAddress.TryParse(poisonedChars.Span, out _));
 113939            }
 40
 41            static void TestValidInput(ReadOnlySpan<byte> bytes = default, string? chars = null)
 57542            {
 57543                if (chars is null)
 56644                {
 45                    // bytes past the '%' may not be valid UTF-8: https://github.com/dotnet/runtime/issues/111288
 56646                    int percentIndex = bytes.IndexOf((byte)'%');
 56647                    Assert.True(Utf8.IsValid(bytes.Slice(0, percentIndex < 0 ? bytes.Length : percentIndex)));
 48
 56649                    chars = Encoding.UTF8.GetString(bytes);
 56650                }
 51                else
 952                {
 953                    bytes = Encoding.UTF8.GetBytes(chars);
 954                }
 55
 57556                Assert.True(IPAddress.IsValid(chars));
 57557                Assert.True(IPAddress.TryParse(chars, out IPAddress? ipFromChars));
 57558                Assert.True(IPAddress.TryParse(bytes, out IPAddress? ipFromBytes));
 59
 57560                Assert.True(ipFromChars.Equals(ipFromBytes));
 57561                Assert.True(ipFromBytes.Equals(ipFromChars));
 62
 57563                Assert.True(IPAddress.IsValid(ipFromChars.ToString()));
 64
 57565                TestUri(chars);
 57566            }
 67
 68            static void TestUri(string chars)
 57569            {
 57570                bool isIpv6 = chars.Contains(':');
 57571                UriHostNameType hostNameType = isIpv6 ? UriHostNameType.IPv6 : UriHostNameType.IPv4;
 72
 57573                if (isIpv6)
 47074                {
 75                    // Remove the ScopeId
 47076                    int percentIndex = chars.IndexOf('%');
 47077                    if (percentIndex >= 0)
 11678                    {
 11679                        chars = chars.Substring(0, percentIndex);
 11680                        if (chars.StartsWith('['))
 3481                        {
 3482                            chars = $"{chars}]";
 3483                        }
 11684                    }
 85
 47086                    if (!chars.StartsWith('['))
 41287                    {
 41288                        chars = $"[{chars}]";
 41289                    }
 90
 91                    // Remove the port
 47092                    int bracketIndex = chars.IndexOf(']');
 47093                    if (bracketIndex >= 0 &&
 47094                        bracketIndex + 1 < chars.Length &&
 47095                        chars[bracketIndex + 1] == ':')
 2296                    {
 2297                        chars = chars.Substring(0, bracketIndex + 1);
 2298                    }
 47099                }
 100
 575101                Assert.True(Uri.TryCreate($"http://{chars}/", UriKind.Absolute, out Uri? uri));
 575102                Assert.Equal(hostNameType, uri.HostNameType);
 575103                Assert.Equal(hostNameType, Uri.CheckHostName(chars));
 575104            }
 2296105        }
 106    }
 107}