Skip to content

Commit

Permalink
AssemblyNameInfo fuzzer (#107195)
Browse files Browse the repository at this point in the history
* add initial AssemblyNameInfo Fuzzer

* fix the first bug that it has discovered
  • Loading branch information
adamsitnik authored Aug 30, 2024
1 parent 4df1b9a commit ac663e4
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
8 changes: 8 additions & 0 deletions eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ extends:
# displayName: Send to OneFuzz

# ONEFUZZ_TASK_WORKAROUND_START
- task: onefuzz-task@0
inputs:
onefuzzOSes: 'Windows'
env:
onefuzzDropDirectory: $(fuzzerProject)/deployment/AssemblyNameInfoFuzzer
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Send AssemblyNameInfoFuzzer to OneFuzz

- task: onefuzz-task@0
inputs:
onefuzzOSes: 'Windows'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;

namespace DotnetFuzzing.Fuzzers
{
internal sealed class AssemblyNameInfoFuzzer : IFuzzer
{
public string[] TargetAssemblies => ["System.Reflection.Metadata"];

public string[] TargetCoreLibPrefixes => [];

public void FuzzTarget(ReadOnlySpan<byte> bytes)
{
ReadOnlySpan<char> chars = MemoryMarshal.Cast<byte, char>(bytes);

using PooledBoundedMemory<char> inputPoisonedBefore = PooledBoundedMemory<char>.Rent(chars, PoisonPagePlacement.Before);
using PooledBoundedMemory<char> inputPoisonedAfter = PooledBoundedMemory<char>.Rent(chars, PoisonPagePlacement.After);

Test(inputPoisonedBefore);
Test(inputPoisonedAfter);
}

private static void Test(PooledBoundedMemory<char> inputPoisoned)
{
bool shouldSucceed = AssemblyNameInfo.TryParse(inputPoisoned.Span, out _);

try
{
AssemblyNameInfo.Parse(inputPoisoned.Span);
}
catch (ArgumentException)
{
Assert.Equal(false, shouldSucceed);
return;
}

Assert.Equal(true, shouldSucceed);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public static AssemblyNameInfo Parse(ReadOnlySpan<char> assemblyName)
public static bool TryParse(ReadOnlySpan<char> assemblyName, [NotNullWhen(true)] out AssemblyNameInfo? result)
{
AssemblyNameParser.AssemblyNameParts parts = default;
if (AssemblyNameParser.TryParse(assemblyName, ref parts))
if (!assemblyName.IsEmpty && AssemblyNameParser.TryParse(assemblyName, ref parts))
{
result = new(parts);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ public void RetargetableIsPropagated()
public void EscapedSquareBracketIsNotAllowedInTheName()
=> Assert.False(AssemblyNameInfo.TryParse("Esc\\[aped".AsSpan(), out _));

[Fact]
public void EmptyInputIsInvalid()
{
Assert.False(AssemblyNameInfo.TryParse("".AsSpan(), out _));
Assert.Throws<ArgumentException>(() => AssemblyNameInfo.Parse("".AsSpan()));
}

static void Roundtrip(AssemblyName source)
{
AssemblyNameInfo parsed = AssemblyNameInfo.Parse(source.FullName.AsSpan());
Expand Down

0 comments on commit ac663e4

Please sign in to comment.