< Summary

Information
Class: DotnetFuzzing.Fuzzers.IPAddressFuzzer
Assembly: DotnetFuzzing
File(s): D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\IPAddressFuzzer.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 68
Coverable lines: 68
Total lines: 107
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
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%440%
TestValidInput(System.ReadOnlySpan`1<System.Byte>,System.String)0%440%
TestUri(System.String)0%16160%

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)
 019        {
 020            using var poisonedBytes = PooledBoundedMemory<byte>.Rent(bytes, PoisonPagePlacement.After);
 021            using var poisonedChars = PooledBoundedMemory<char>.Rent(MemoryMarshal.Cast<byte, char>(bytes), PoisonPagePl
 22
 023            if (IPAddress.IsValidUtf8(poisonedBytes.Span))
 024            {
 025                TestValidInput(bytes: poisonedBytes.Span);
 026            }
 27            else
 028            {
 029                Assert.False(IPAddress.TryParse(poisonedBytes.Span, out _));
 030            }
 31
 032            if (IPAddress.IsValid(poisonedChars.Span))
 033            {
 034                TestValidInput(chars: poisonedChars.Span.ToString());
 035            }
 36            else
 037            {
 038                Assert.False(IPAddress.TryParse(poisonedChars.Span, out _));
 039            }
 40
 41            static void TestValidInput(ReadOnlySpan<byte> bytes = default, string? chars = null)
 042            {
 043                if (chars is null)
 044                {
 45                    // bytes past the '%' may not be valid UTF-8: https://github.com/dotnet/runtime/issues/111288
 046                    int percentIndex = bytes.IndexOf((byte)'%');
 047                    Assert.True(Utf8.IsValid(bytes.Slice(0, percentIndex < 0 ? bytes.Length : percentIndex)));
 48
 049                    chars = Encoding.UTF8.GetString(bytes);
 050                }
 51                else
 052                {
 053                    bytes = Encoding.UTF8.GetBytes(chars);
 054                }
 55
 056                Assert.True(IPAddress.IsValid(chars));
 057                Assert.True(IPAddress.TryParse(chars, out IPAddress? ipFromChars));
 058                Assert.True(IPAddress.TryParse(bytes, out IPAddress? ipFromBytes));
 59
 060                Assert.True(ipFromChars.Equals(ipFromBytes));
 061                Assert.True(ipFromBytes.Equals(ipFromChars));
 62
 063                Assert.True(IPAddress.IsValid(ipFromChars.ToString()));
 64
 065                TestUri(chars);
 066            }
 67
 68            static void TestUri(string chars)
 069            {
 070                bool isIpv6 = chars.Contains(':');
 071                UriHostNameType hostNameType = isIpv6 ? UriHostNameType.IPv6 : UriHostNameType.IPv4;
 72
 073                if (isIpv6)
 074                {
 75                    // Remove the ScopeId
 076                    int percentIndex = chars.IndexOf('%');
 077                    if (percentIndex >= 0)
 078                    {
 079                        chars = chars.Substring(0, percentIndex);
 080                        if (chars.StartsWith('['))
 081                        {
 082                            chars = $"{chars}]";
 083                        }
 084                    }
 85
 086                    if (!chars.StartsWith('['))
 087                    {
 088                        chars = $"[{chars}]";
 089                    }
 90
 91                    // Remove the port
 092                    int bracketIndex = chars.IndexOf(']');
 093                    if (bracketIndex >= 0 &&
 094                        bracketIndex + 1 < chars.Length &&
 095                        chars[bracketIndex + 1] == ':')
 096                    {
 097                        chars = chars.Substring(0, bracketIndex + 1);
 098                    }
 099                }
 100
 0101                Assert.True(Uri.TryCreate($"http://{chars}/", UriKind.Absolute, out Uri? uri));
 0102                Assert.Equal(hostNameType, uri.HostNameType);
 0103                Assert.Equal(hostNameType, Uri.CheckHostName(chars));
 0104            }
 0105        }
 106    }
 107}