< Summary

Information
Class: DotnetFuzzing.Fuzzers.SearchValuesStringFuzzer
Assembly: DotnetFuzzing
File(s): D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\SearchValuesStringFuzzer.cs
Line coverage
2%
Covered lines: 1
Uncovered lines: 39
Coverable lines: 40
Total lines: 69
Line coverage: 2.5%
Branch coverage
0%
Covered branches: 0
Total branches: 10
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%220%
Test(...)100%110%
IndexOfAnyReferenceImpl(...)0%660%
AssertEqual(...)0%220%

File(s)

D:\runner\runtime\src\libraries\Fuzzing\DotnetFuzzing\Fuzzers\SearchValuesStringFuzzer.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.Runtime.InteropServices;
 6
 7namespace DotnetFuzzing.Fuzzers;
 8
 9internal sealed class SearchValuesStringFuzzer : IFuzzer
 10{
 011    public string[] TargetAssemblies => [];
 112    public string[] TargetCoreLibPrefixes { get; } = ["System.Buffers", "System.Globalization"];
 13
 14    public void FuzzTarget(ReadOnlySpan<byte> bytes)
 015    {
 016        ReadOnlySpan<char> chars = MemoryMarshal.Cast<byte, char>(bytes);
 17
 018        int newLine = chars.IndexOf('\n');
 019        if (newLine < 0)
 020        {
 021            return;
 22        }
 23
 024        ReadOnlySpan<char> haystack = chars.Slice(newLine + 1);
 025        string[] needles = chars.Slice(0, newLine).ToString().Split(',');
 26
 027        using var haystack0 = PooledBoundedMemory<char>.Rent(haystack, PoisonPagePlacement.Before);
 028        using var haystack1 = PooledBoundedMemory<char>.Rent(haystack, PoisonPagePlacement.After);
 29
 030        Test(haystack0.Span, haystack1.Span, needles, StringComparison.Ordinal);
 031        Test(haystack0.Span, haystack1.Span, needles, StringComparison.OrdinalIgnoreCase);
 032    }
 33
 34    private static void Test(ReadOnlySpan<char> haystack, ReadOnlySpan<char> haystackCopy, string[] needles, StringCompa
 035    {
 036        SearchValues<string> searchValues = SearchValues.Create(needles, comparisonType);
 37
 038        int index = haystack.IndexOfAny(searchValues);
 039        AssertEqual(index, haystackCopy.IndexOfAny(searchValues), searchValues);
 040        AssertEqual(index, IndexOfAnyReferenceImpl(haystack, needles, comparisonType), searchValues);
 041    }
 42
 43    private static int IndexOfAnyReferenceImpl(ReadOnlySpan<char> haystack, string[] needles, StringComparison compariso
 044    {
 045        int minIndex = int.MaxValue;
 46
 047        foreach (string needle in needles)
 048        {
 049            int i = haystack.IndexOf(needle, comparisonType);
 050            if ((uint)i < minIndex)
 051            {
 052                minIndex = i;
 053            }
 054        }
 55
 056        return minIndex == int.MaxValue ? -1 : minIndex;
 057    }
 58
 59    private static void AssertEqual(int expected, int actual, SearchValues<string> searchValues)
 060    {
 061        if (expected != actual)
 062        {
 063            Type implType = searchValues.GetType();
 064            string impl = $"{implType.Name} [{string.Join(", ", implType.GenericTypeArguments.Select(t => t.Name))}]";
 65
 066            throw new Exception($"Expected {expected}, got {actual} for impl='{impl}'");
 67        }
 068    }
 69}