Skip to content

Commit 48ae967

Browse files
buyaa-nMihaZupanadamsitnik
authored
Add TypeNameFuzzer (#107206)
Co-authored-by: Miha Zupan <[email protected]> Co-authored-by: Adam Sitnik <[email protected]>
1 parent 5b33115 commit 48ae967

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ extends:
129129
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
130130
displayName: Send TextEncodingFuzzer to OneFuzz
131131

132+
- task: onefuzz-task@0
133+
inputs:
134+
onefuzzOSes: 'Windows'
135+
env:
136+
onefuzzDropDirectory: $(fuzzerProject)/deployment/TypeNameFuzzer
137+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
138+
displayName: Send TypeNameFuzzer to OneFuzz
139+
132140
- task: onefuzz-task@0
133141
inputs:
134142
onefuzzOSes: 'Windows'
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
" "
2+
"0"
3+
","
4+
"[*["
5+
" System.Int32 "
6+
"System.Int32&&"
7+
"System.Int32[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]"
8+
"System.Int32[*******************************]"
9+
"System.Int32[][][][][][][][][][][][][][][][][][][][]"
10+
".NoNamespace"
11+
"Namespace.Ko\xC5\x9B\xC4\x87"
12+
"Declaring+Nested"
13+
"Declaring+Deep+Deeper+Nested"
14+
"Declaring+Deep+Deeper+Nested, Lib"
15+
"MyNamespace.MyType+NestedType"
16+
"Pointer*******"
17+
"Generic`1[[A]]"
18+
"Generic`2[[A],[B]]"
19+
"Generic`3[[A],[B],[C]]"
20+
"Generic`3[A,B,C]"
21+
"Generic`2[[System.Int32, mscorlib, Version=4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934],[System.Boolean, mscorlib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
22+
"Generic`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], System.Boolean, [System.Byte, other, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
23+
"TypeNameWith\\TheEscapingCharacter"
24+
"TypeNameWith[[]]NestedSquareBrackets"
25+
"TypeNameWith\\[]+*&,AllSpecialCharacters"
26+
"System.Reflection.Metadata.Tests.TypeNameTests+NestedGeneric_0`1+NestedGeneric_1`2+NestedGeneric_2`3+NestedNonGeneric_3[[System.Int32, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int16, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Byte, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.SByte, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Reflection.Metadata.Tests, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
4+
using System.Buffers;
5+
using System.Reflection.Metadata;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.InteropServices.Marshalling;
8+
using System.Text;
9+
10+
namespace DotnetFuzzing.Fuzzers
11+
{
12+
internal sealed class TypeNameFuzzer : IFuzzer
13+
{
14+
public string[] TargetAssemblies { get; } = ["System.Reflection.Metadata"];
15+
public string[] TargetCoreLibPrefixes => [];
16+
public string Dictionary => "typename.dict";
17+
18+
public void FuzzTarget(ReadOnlySpan<byte> bytes)
19+
{
20+
Span<char> charSpan = new char[Encoding.UTF8.GetCharCount(bytes)];
21+
Encoding.UTF8.GetChars(bytes, charSpan);
22+
using var poisonAfter = PooledBoundedMemory<char>.Rent(charSpan, PoisonPagePlacement.After);
23+
using var poisonBefore = PooledBoundedMemory<char>.Rent(charSpan, PoisonPagePlacement.Before);
24+
25+
Test(poisonAfter.Span);
26+
Test(poisonBefore.Span);
27+
}
28+
29+
private static void Test(Span<char> testSpan)
30+
{
31+
if (TypeName.TryParse(testSpan, out TypeName? result1))
32+
{
33+
TypeName result2 = TypeName.Parse(testSpan);
34+
Assert.Equal(result1.Name, result2.Name);
35+
Assert.Equal(result1.FullName, result2.FullName);
36+
Assert.Equal(result1.AssemblyQualifiedName, result2.AssemblyQualifiedName);
37+
Assert.Equal(result1.IsSimple, result2.IsSimple);
38+
Assert.Equal(result1.IsNested, result2.IsNested);
39+
Assert.Equal(result1.IsArray, result2.IsArray);
40+
Assert.Equal(result1.GetNodeCount(), result2.GetNodeCount());
41+
if (result1.AssemblyName != null)
42+
{
43+
Assert.Equal(result1.AssemblyName.Name, result2.AssemblyName!.Name);
44+
Assert.Equal(result1.AssemblyName.FullName, result2.AssemblyName.FullName);
45+
Assert.Equal(result1.AssemblyName.CultureName, result2.AssemblyName.CultureName);
46+
Assert.Equal(result1.AssemblyName.Version?.ToString(), result2.AssemblyName.Version?.ToString());
47+
}
48+
else
49+
{
50+
Assert.Equal(result1.AssemblyName, result2.AssemblyName);
51+
}
52+
}
53+
else
54+
{
55+
try
56+
{
57+
TypeName.Parse(testSpan);
58+
Assert.Equal(true, false); // should never succeed
59+
}
60+
catch (ArgumentException) { }
61+
catch (InvalidOperationException) { }
62+
}
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)