diff --git a/FUZZING.md b/FUZZING.md
index 146b015edfb..df30c8a8f55 100644
--- a/FUZZING.md
+++ b/FUZZING.md
@@ -23,10 +23,7 @@ We currently maintain fuzzers for the following languages:
- Python
- Rust
- Swift
-
-We are working on adding fuzzers for the following languages:
-
-- netstd
+- netstd (only supported locally, and not on oss-fuzz)
## Fuzzer Types
diff --git a/lib/netstd/Makefile.am b/lib/netstd/Makefile.am
index ed855e45f3f..34036d73806 100644
--- a/lib/netstd/Makefile.am
+++ b/lib/netstd/Makefile.am
@@ -28,6 +28,21 @@ check-local:
$(DOTNETCORE) test Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj
$(DOTNETCORE) test Tests/Thrift.Tests/Thrift.Tests.csproj
$(DOTNETCORE) test Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+ $(MAKE) build-fuzzers
+
+build-fuzzers:
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Binary -p:FuzzerType=Parse -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Binary -p:FuzzerType=Parse -p:Engine=Libfuzzer
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Binary -p:FuzzerType=Roundtrip -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Binary -p:FuzzerType=Roundtrip -p:Engine=Libfuzzer
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Compact -p:FuzzerType=Parse -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Compact -p:FuzzerType=Parse -p:Engine=Libfuzzer
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Compact -p:FuzzerType=Roundtrip -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Compact -p:FuzzerType=Roundtrip -p:Engine=Libfuzzer
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Json -p:FuzzerType=Parse -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Json -p:FuzzerType=Parse -p:Engine=Libfuzzer
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Json -p:FuzzerType=Roundtrip -p:Engine=AFL
+ $(DOTNETCORE) build Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj -p:Protocol=Json -p:FuzzerType=Roundtrip -p:Engine=Libfuzzer
clean-local:
$(RM) -r Thrift/bin
@@ -44,6 +59,8 @@ clean-local:
$(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.net9/obj
$(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/bin
$(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/obj
+ $(RM) -r Tests/Thrift.FuzzTests/bin
+ $(RM) -r Tests/Thrift.FuzzTests/obj
distdir:
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -60,6 +77,7 @@ EXTRA_DIST = \
Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj \
Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj \
Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj \
+ Tests/Thrift.FuzzTests \
Tests/Thrift.Tests/Collections \
Tests/Thrift.Tests/DataModel \
Tests/Thrift.Tests/Protocols \
diff --git a/lib/netstd/README.md b/lib/netstd/README.md
index 912ea011c1d..0fb72887245 100644
--- a/lib/netstd/README.md
+++ b/lib/netstd/README.md
@@ -53,3 +53,14 @@ Because of the different environment requirements, migration from C# takes sligh
- In case you are using Thrift server event handlers: the `SetEventHandler` method now starts with an uppercase letter
- and you will also have to revise the method names of all `TServerEventHandler` descendants you have in your code
+# Fuzzing
+
+We use SharpFuzz (and its libfuzzer variant) for fuzzing. This is **not** supported on oss-fuzz, so all fuzzing must be run locally (currently only tested on a linux machine)
+
+To get started:
+
+* Install https://github.com/Metalnem/sharpfuzz
+* Install https://github.com/Metalnem/libfuzzer-dotnet
+* Create a directory which contains the executable `libfuzzer-dotnet` and set $SHARPFUZZ_DIR to point to it.
+
+Then you can run `buildfuzzers.sh` to build the fuzzers and `runfuzzer.sh` to run a given fuzzer.
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/ProtocolFuzzerBase.cs b/lib/netstd/Tests/Thrift.FuzzTests/ProtocolFuzzerBase.cs
new file mode 100644
index 00000000000..aaf258d493b
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/ProtocolFuzzerBase.cs
@@ -0,0 +1,101 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ ///
+ /// Base class for protocol fuzzers that handles the common fuzzing logic.
+ ///
+ /// The type of protocol to use for deserialization.
+ public abstract class ProtocolFuzzerBase where FuzzProtocol : TProtocol
+ {
+ ///
+ /// Environment variable that controls whether to use in-process fuzzing for AFL.
+ /// When set to "1", uses Fuzzer.Run instead of Fuzzer.OutOfProcess.Run.
+ ///
+ protected const string UseInProcessFuzzingEnvVar = "THRIFT_AFL_IN_PROCESS";
+
+ ///
+ /// 10MB message size limit to prevent over-allocation during fuzzing
+ ///
+ protected const int FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024;
+
+ ///
+ /// Creates a new instance of the protocol for the given transport.
+ ///
+ protected abstract FuzzProtocol CreateProtocol(TTransport transport);
+
+ ///
+ /// Helper method that contains the core fuzzing logic.
+ ///
+ private void ProcessFuzzStream(Stream stream)
+ {
+ try
+ {
+ var config = new TConfiguration();
+ config.MaxMessageSize = FUZZ_MAX_MESSAGE_SIZE;
+ var transport = new TStreamTransport(stream, null, config);
+ var protocol = CreateProtocol(transport);
+
+ var obj = new FuzzTest();
+ obj.ReadAsync(protocol, default).GetAwaiter().GetResult();
+ }
+ catch (TException) { /* Expected for malformed input */ }
+ catch (Exception) { /* Expected for malformed input */ }
+ }
+
+ ///
+ /// The core fuzzing logic that processes a single input.
+ ///
+ protected void ProcessFuzzInput(ReadOnlySpan span)
+ {
+ using var stream = new MemoryStream(span.ToArray());
+ ProcessFuzzStream(stream);
+ }
+
+ ///
+ /// Runs the fuzzer with LibFuzzer.
+ ///
+ protected void RunLibFuzzer()
+ {
+ Fuzzer.LibFuzzer.Run(ProcessFuzzInput);
+ }
+
+ ///
+ /// Runs the fuzzer with AFL.
+ ///
+ protected void RunAFL()
+ {
+ var useInProcess = Environment.GetEnvironmentVariable(UseInProcessFuzzingEnvVar) == "1";
+ if (useInProcess)
+ {
+ Fuzzer.Run(ProcessFuzzStream);
+ }
+ else
+ {
+ Fuzzer.OutOfProcess.Run(ProcessFuzzStream);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/ProtocolRoundtripFuzzerBase.cs b/lib/netstd/Tests/Thrift.FuzzTests/ProtocolRoundtripFuzzerBase.cs
new file mode 100644
index 00000000000..70b85fa9fa8
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/ProtocolRoundtripFuzzerBase.cs
@@ -0,0 +1,124 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ ///
+ /// Base class for protocol round-trip fuzzers that handles the common fuzzing logic.
+ ///
+ /// The type of protocol to use for serialization/deserialization.
+ public abstract class ProtocolRoundtripFuzzerBase where FuzzProtocol : TProtocol
+ {
+ ///
+ /// Environment variable that controls whether to use in-process fuzzing for AFL.
+ /// When set to "1", uses Fuzzer.Run instead of Fuzzer.OutOfProcess.Run.
+ ///
+ protected const string UseInProcessFuzzingEnvVar = "THRIFT_AFL_IN_PROCESS";
+
+ ///
+ /// 10MB message size limit to prevent over-allocation during fuzzing
+ ///
+ protected const int FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024;
+
+ ///
+ /// Creates a new instance of the protocol for the given transport.
+ ///
+ protected abstract FuzzProtocol CreateProtocol(TTransport transport);
+
+ ///
+ /// Helper method that contains the core fuzzing logic.
+ ///
+ private void ProcessFuzzStream(Stream stream)
+ {
+ try
+ {
+ // First deserialize the input
+ var config = new TConfiguration();
+ config.MaxMessageSize = FUZZ_MAX_MESSAGE_SIZE;
+ var inputTransport = new TStreamTransport(stream, null, config);
+ var inputProtocol = CreateProtocol(inputTransport);
+
+ var inputObj = new FuzzTest();
+ inputObj.ReadAsync(inputProtocol, default).GetAwaiter().GetResult();
+
+ // Now serialize it back
+ using var outputStream = new MemoryStream();
+ var outputTransport = new TStreamTransport(null, outputStream, config);
+ var outputProtocol = CreateProtocol(outputTransport);
+ inputObj.WriteAsync(outputProtocol, default).GetAwaiter().GetResult();
+ outputTransport.FlushAsync(default).GetAwaiter().GetResult();
+
+ // Get the serialized bytes and deserialize again
+ var serialized = outputStream.ToArray();
+ using var reStream = new MemoryStream(serialized);
+ var reTransport = new TStreamTransport(reStream, null, config);
+ var reProtocol = CreateProtocol(reTransport);
+
+ var outputObj = new FuzzTest();
+ outputObj.ReadAsync(reProtocol, default).GetAwaiter().GetResult();
+
+ // Compare the objects
+ if (!inputObj.Equals(outputObj))
+ {
+ throw new Exception("Round-trip objects are not equal");
+ }
+ }
+ catch (TException) { /* Expected for malformed input */ }
+ catch (Exception) { /* Expected for malformed input */ }
+ }
+
+ ///
+ /// The core fuzzing logic that processes a single input.
+ ///
+ protected void ProcessFuzzInput(ReadOnlySpan span)
+ {
+ using var stream = new MemoryStream(span.ToArray());
+ ProcessFuzzStream(stream);
+ }
+
+ ///
+ /// Runs the fuzzer with LibFuzzer.
+ ///
+ protected void RunLibFuzzer()
+ {
+ Fuzzer.LibFuzzer.Run(ProcessFuzzInput);
+ }
+
+ ///
+ /// Runs the fuzzer with AFL.
+ ///
+ protected void RunAFL()
+ {
+ var useInProcess = Environment.GetEnvironmentVariable(UseInProcessFuzzingEnvVar) == "1";
+ if (useInProcess)
+ {
+ Fuzzer.Run(ProcessFuzzStream);
+ }
+ else
+ {
+ Fuzzer.OutOfProcess.Run(ProcessFuzzStream);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolAFL.cs
new file mode 100644
index 00000000000..6827a4cdd47
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TBinaryProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TBinaryProtocol CreateProtocol(TTransport transport)
+ {
+ return new TBinaryProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TBinaryProtocolFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolLibfuzzer.cs
new file mode 100644
index 00000000000..5d2cb52a848
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolLibfuzzer.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TBinaryProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TBinaryProtocol CreateProtocol(TTransport transport)
+ {
+ return new TBinaryProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TBinaryProtocolFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripAFL.cs
new file mode 100644
index 00000000000..6f7b071cd95
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TBinaryProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TBinaryProtocol CreateProtocol(TTransport transport)
+ {
+ return new TBinaryProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TBinaryProtocolRoundtripFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripLibfuzzer.cs
new file mode 100644
index 00000000000..298698b6a44
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TBinaryProtocolRoundtripLibfuzzer.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TBinaryProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TBinaryProtocol CreateProtocol(TTransport transport)
+ {
+ return new TBinaryProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TBinaryProtocolRoundtripFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolAFL.cs
new file mode 100644
index 00000000000..3391b3cd05d
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TCompactProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TCompactProtocol CreateProtocol(TTransport transport)
+ {
+ return new TCompactProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TCompactProtocolFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolLibfuzzer.cs
new file mode 100644
index 00000000000..e2fa0f7a879
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolLibfuzzer.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TCompactProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TCompactProtocol CreateProtocol(TTransport transport)
+ {
+ return new TCompactProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TCompactProtocolFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripAFL.cs
new file mode 100644
index 00000000000..4b4afc39d4b
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TCompactProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TCompactProtocol CreateProtocol(TTransport transport)
+ {
+ return new TCompactProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TCompactProtocolRoundtripFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripLibfuzzer.cs
new file mode 100644
index 00000000000..6bb97423bd2
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TCompactProtocolRoundtripLibfuzzer.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TCompactProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TCompactProtocol CreateProtocol(TTransport transport)
+ {
+ return new TCompactProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TCompactProtocolRoundtripFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolAFL.cs
new file mode 100644
index 00000000000..a68659bfd85
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TJsonProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TJsonProtocol CreateProtocol(TTransport transport)
+ {
+ return new TJsonProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TJsonProtocolFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolLibfuzzer.cs
new file mode 100644
index 00000000000..e6d46746043
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolLibfuzzer.cs
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// Boilerplate fuzzer for TJSONProtocol using SharpFuzz
+// Attempts to deserialize a FuzzTest struct from the input stream using TJSONProtocol
+// Expected exceptions (e.g., TProtocolException) are caught and ignored
+// Unexpected exceptions are reported as crashes
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TJsonProtocolFuzzer : ProtocolFuzzerBase
+ {
+ protected override TJsonProtocol CreateProtocol(TTransport transport)
+ {
+ return new TJsonProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TJsonProtocolFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripAFL.cs b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripAFL.cs
new file mode 100644
index 00000000000..6b956c0d825
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripAFL.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TJsonProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TJsonProtocol CreateProtocol(TTransport transport)
+ {
+ return new TJsonProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TJsonProtocolRoundtripFuzzer().RunAFL();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripLibfuzzer.cs b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripLibfuzzer.cs
new file mode 100644
index 00000000000..5f16813c2c0
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/TJsonProtocolRoundtripLibfuzzer.cs
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.IO;
+using SharpFuzz;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols.Fuzzers
+{
+ public class TJsonProtocolRoundtripFuzzer : ProtocolRoundtripFuzzerBase
+ {
+ protected override TJsonProtocol CreateProtocol(TTransport transport)
+ {
+ return new TJsonProtocol(transport);
+ }
+
+ public static void Main(string[] args)
+ {
+ new TJsonProtocolRoundtripFuzzer().RunLibFuzzer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj b/lib/netstd/Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj
new file mode 100644
index 00000000000..724d8c270a4
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.FuzzTests/Thrift.FuzzTests.csproj
@@ -0,0 +1,70 @@
+
+
+
+
+ net9.0
+ latestMajor
+ enable
+ Exe
+ false
+
+
+ Binary
+ Parse
+ AFL
+
+
+ Thrift.FuzzTests.$(Protocol)$(FuzzerType)$(Engine)
+
+
+ obj\$(Configuration)\$(TargetFramework)\$(Protocol)$(FuzzerType)$(Engine)\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/netstd/buildfuzzers.sh b/lib/netstd/buildfuzzers.sh
new file mode 100755
index 00000000000..53d9e5660cb
--- /dev/null
+++ b/lib/netstd/buildfuzzers.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -e
+
+# Check for SHARPFUZZ_DIR environment variable
+if [ -z "$SHARPFUZZ_DIR" ]; then
+ echo "Error: SHARPFUZZ_DIR environment variable is not set."
+ echo "Please set SHARPFUZZ_DIR to the location of your SharpFuzz installation."
+ echo "See README for installation instructions."
+ exit 1
+fi
+
+# Verify libfuzzer-dotnet exists
+LIBFUZZER="$SHARPFUZZ_DIR/libfuzzer-dotnet"
+if [ ! -f "$LIBFUZZER" ]; then
+ echo "Error: libfuzzer-dotnet not found at $LIBFUZZER"
+ echo "Please ensure SharpFuzz is properly installed in $SHARPFUZZ_DIR"
+ echo "See README for installation instructions."
+ exit 1
+fi
+
+# Find the local Thrift compiler
+THRIFT="$(dirname "$0")/../../compiler/cpp/thrift"
+THRIFT=$(realpath "$THRIFT")
+
+# Paths
+THRIFT_FILE="$(dirname "$0")/../../test/FuzzTest.thrift"
+GEN_DIR="$(dirname "$0")/Tests/Thrift.FuzzTests/gen-netstd"
+FUZZERS_DIR="$(dirname "$0")/Tests/Thrift.FuzzTests"
+OUTPUT_DIR="$FUZZERS_DIR/bin/Debug/net9.0"
+
+# Step 1: Generate C# code from FuzzTest.thrift
+if [ ! -x "$THRIFT" ]; then
+ echo "Error: Thrift compiler not found at $THRIFT"
+ exit 1
+fi
+
+# Clean and create the generated directory
+rm -rf "$GEN_DIR"
+mkdir -p "$GEN_DIR"
+
+echo "[1/13] Generating C# code from $THRIFT_FILE ..."
+"$THRIFT" --gen netstd:net9 -out "$GEN_DIR" "$THRIFT_FILE"
+echo "C# code generated in $GEN_DIR."
+
+# Step 2: Build all fuzzer projects
+cd "$(dirname "$0")"
+
+# Build all fuzzer combinations using the consolidated project
+BUILD_COUNT=2
+for protocol in Binary Compact Json; do
+ for fuzzer_type_raw in Parse Roundtrip; do
+ for engine in AFL Libfuzzer; do
+ # Construct display name
+ if [ "$fuzzer_type_raw" = "Parse" ]; then
+ display_name="$protocol Protocol $engine"
+ fuzzer_type=""
+ else
+ display_name="$protocol Protocol round-trip $engine"
+ fuzzer_type="Roundtrip"
+ fi
+
+ echo "[$BUILD_COUNT/13] Building $display_name ..."
+ dotnet build "$FUZZERS_DIR/Thrift.FuzzTests.csproj" \
+ -p:Protocol=$protocol \
+ -p:FuzzerType=$fuzzer_type_raw \
+ -p:Engine=$engine
+
+ BUILD_COUNT=$((BUILD_COUNT + 1))
+ done
+ done
+done
+
+# Step 3: Instrument the assemblies
+echo "Instrumenting assemblies for fuzzing ..."
+
+# Exclusions for instrumentation
+EXCLUSIONS=("dnlib.dll" "SharpFuzz.dll" "SharpFuzz.Common.dll")
+
+# Find and instrument fuzzing targets
+while IFS= read -r -d '' dll; do
+ dll_name=$(basename "$dll")
+ skip=false
+ for excl in "${EXCLUSIONS[@]}"; do
+ if [[ "$dll_name" == "$excl" ]]; then
+ skip=true
+ break
+ fi
+ done
+ if [[ "$dll_name" == System.*.dll ]]; then
+ skip=true
+ fi
+ if [[ "$dll_name" == Thrift.FuzzTests.*.dll ]]; then
+ skip=true # Skip the fuzzer assemblies themselves
+ fi
+ if [ "$skip" = true ]; then
+ echo "Skipping $dll_name"
+ continue
+ fi
+ if [ "$skip" = false ]; then
+ echo "Instrumenting $dll_name"
+ sharpfuzz "$dll"
+ if [ $? -ne 0 ]; then
+ echo "An error occurred while instrumenting $dll"
+ exit 1
+ fi
+ fi
+done < <(find "$OUTPUT_DIR" -maxdepth 1 -type f -name "*.dll" -print0)
+
+echo "Build and instrumentation complete."
\ No newline at end of file
diff --git a/lib/netstd/runfuzzer.sh b/lib/netstd/runfuzzer.sh
new file mode 100755
index 00000000000..7bc649e2611
--- /dev/null
+++ b/lib/netstd/runfuzzer.sh
@@ -0,0 +1,160 @@
+#!/bin/bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -e
+
+# Check if a fuzzer name and type were provided
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 [additional fuzzer arguments...]"
+ echo "Available fuzzer names: json, compact, binary, json-roundtrip, compact-roundtrip, binary-roundtrip"
+ echo "Available fuzzer types: libfuzzer, afl"
+ exit 1
+fi
+
+FUZZER_NAME="$1"
+FUZZER_TYPE="$2"
+shift 2 # Remove the first two arguments, leaving only additional arguments
+
+VALID_FUZZERS=("json" "compact" "binary" "json-roundtrip" "compact-roundtrip" "binary-roundtrip")
+VALID_TYPES=("libfuzzer" "afl")
+
+# Validate fuzzer name
+VALID=0
+for f in "${VALID_FUZZERS[@]}"; do
+ if [ "$f" = "$FUZZER_NAME" ]; then
+ VALID=1
+ break
+ fi
+done
+
+if [ $VALID -eq 0 ]; then
+ echo "Invalid fuzzer name: $FUZZER_NAME"
+ echo "Available fuzzers: json, compact, binary, json-roundtrip, compact-roundtrip, binary-roundtrip"
+ exit 1
+fi
+
+# Validate fuzzer type
+VALID=0
+for t in "${VALID_TYPES[@]}"; do
+ if [ "$t" = "$FUZZER_TYPE" ]; then
+ VALID=1
+ break
+ fi
+done
+
+if [ $VALID -eq 0 ]; then
+ echo "Invalid fuzzer type: $FUZZER_TYPE"
+ echo "Available types: libfuzzer, afl"
+ exit 1
+fi
+
+# Map fuzzer name and type to assembly name
+# With the consolidated project, names follow the pattern:
+# Thrift.FuzzTests.{Protocol}{FuzzerType}{Engine}
+# where FuzzerType is "Parse" or "Roundtrip"
+case "$FUZZER_NAME" in
+ "json")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.JsonParseLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.JsonParseAFL"
+ fi
+ ;;
+ "compact")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.CompactParseLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.CompactParseAFL"
+ fi
+ ;;
+ "binary")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.BinaryParseLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.BinaryParseAFL"
+ fi
+ ;;
+ "json-roundtrip")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.JsonRoundtripLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.JsonRoundtripAFL"
+ fi
+ ;;
+ "compact-roundtrip")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.CompactRoundtripLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.CompactRoundtripAFL"
+ fi
+ ;;
+ "binary-roundtrip")
+ if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ ASSEMBLY_NAME="Thrift.FuzzTests.BinaryRoundtripLibfuzzer"
+ else
+ ASSEMBLY_NAME="Thrift.FuzzTests.BinaryRoundtripAFL"
+ fi
+ ;;
+esac
+
+# Check for SHARPFUZZ_DIR environment variable
+if [ -z "$SHARPFUZZ_DIR" ]; then
+ echo "Error: SHARPFUZZ_DIR environment variable is not set."
+ echo "Please set SHARPFUZZ_DIR to the location of your SharpFuzz installation."
+ echo "See README for installation instructions."
+ exit 1
+fi
+
+# Verify libfuzzer-dotnet exists
+LIBFUZZER="$SHARPFUZZ_DIR/libfuzzer-dotnet"
+if [ ! -f "$LIBFUZZER" ]; then
+ echo "Error: libfuzzer-dotnet not found at $LIBFUZZER"
+ echo "Please ensure SharpFuzz is properly installed in $SHARPFUZZ_DIR"
+ echo "See README for installation instructions."
+ exit 1
+fi
+OUTPUT_DIR="$(dirname "$0")/Tests/Thrift.FuzzTests/bin/Debug/net9.0"
+CORPUS_DIR="$(dirname "$0")/corpus/$FUZZER_NAME"
+
+# Create corpus directory if it doesn't exist
+mkdir -p "$CORPUS_DIR"
+
+# Get project path
+PROJECT_PATH="$OUTPUT_DIR/$ASSEMBLY_NAME.dll"
+
+# Run the appropriate fuzzer
+echo "Running $ASSEMBLY_NAME fuzzer..."
+if [ "$FUZZER_TYPE" = "libfuzzer" ]; then
+ "$LIBFUZZER" --target_path=dotnet --target_arg="$PROJECT_PATH" "$CORPUS_DIR" "$@"
+else
+ # For AFL, we need separate input and findings directories
+ AFL_INPUT_DIR="$CORPUS_DIR/input"
+ AFL_FINDINGS_DIR="$CORPUS_DIR/findings"
+ mkdir -p "$AFL_INPUT_DIR"
+ mkdir -p "$AFL_FINDINGS_DIR"
+
+ # If input directory is empty, create a minimal test case
+ if [ ! "$(ls -A $AFL_INPUT_DIR)" ]; then
+ echo -n "test" > "$AFL_INPUT_DIR/test.txt"
+ fi
+ export AFL_SKIP_BIN_CHECK=1
+ afl-fuzz -i "$AFL_INPUT_DIR" -o "$AFL_FINDINGS_DIR" -m none dotnet "$PROJECT_PATH" "$@"
+fi
\ No newline at end of file