diff --git a/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml b/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml
index e179e73e6ac72f..7ae8ed6594cbc4 100644
--- a/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml
+++ b/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml
@@ -162,6 +162,14 @@ extends:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Send UTF8Fuzzer to OneFuzz
+ - task: onefuzz-task@0
+ inputs:
+ onefuzzOSes: 'Windows'
+ env:
+ onefuzzDropDirectory: $(fuzzerProject)/deployment/Utf8JsonReaderFuzzer
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ displayName: Send Utf8JsonReaderFuzzer to OneFuzz
+
- task: onefuzz-task@0
inputs:
onefuzzOSes: 'Windows'
diff --git a/src/libraries/Fuzzing/DotnetFuzzing/DotnetFuzzing.csproj b/src/libraries/Fuzzing/DotnetFuzzing/DotnetFuzzing.csproj
index 82036d1c0cd522..691eb1a9cc049a 100644
--- a/src/libraries/Fuzzing/DotnetFuzzing/DotnetFuzzing.csproj
+++ b/src/libraries/Fuzzing/DotnetFuzzing/DotnetFuzzing.csproj
@@ -30,6 +30,7 @@
+
diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/Utf8JsonReaderFuzzer.cs b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/Utf8JsonReaderFuzzer.cs
new file mode 100644
index 00000000000000..c3409a239ed967
--- /dev/null
+++ b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/Utf8JsonReaderFuzzer.cs
@@ -0,0 +1,669 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Buffers;
+using System.Buffers.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Pipelines;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+using System.Text.Unicode;
+using SharpFuzz;
+
+namespace DotnetFuzzing.Fuzzers;
+
+internal sealed class Utf8JsonReaderFuzzer : IFuzzer
+{
+ public string[] TargetAssemblies { get; } = ["System.Text.Json"];
+
+ public string[] TargetCoreLibPrefixes => [];
+
+ delegate T RefFunc(ref Utf8JsonReader reader);
+
+ static Random s_random = default!;
+
+ public void FuzzTarget(ReadOnlySpan bytes)
+ {
+ const int minLength = 10;
+ if (bytes.Length < minLength)
+ {
+ return;
+ }
+
+ // Create a random seed from the last 4 bytes of the input
+ int len = bytes.Length;
+ int randomSeed = bytes[len - 1] + (bytes[len - 2] << 8) + (bytes[len - 3] << 16) + (bytes[len - 4] << 24);
+ s_random = new Random(randomSeed);
+
+ // Remove the 4 bytes used for the random seed
+ bytes = bytes.Slice(0, len - 4);
+
+ JsonSerializerOptions options = new JsonSerializerOptions
+ {
+ AllowTrailingCommas = s_random.Next() % 2 == 0,
+ Encoder = s_random.Next() % 2 == 0 ? JavaScriptEncoder.Default : JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ // TODO: JsonExceptions differ between Span and Sequence paths
+ ReadCommentHandling = (JsonCommentHandling)s_random.Next(0, 2),
+ NumberHandling = (JsonNumberHandling)s_random.Next(0, 4),
+ };
+
+ // Fuzz using ReadOnlySpan
+ var readerSpan = new Utf8JsonReader(bytes, isFinalBlock: true, state: default);
+
+ // Fuzz using ReadOnlySequence
+ var sequence = CreateVariableSegmentSequence(bytes);
+ var readerSequence = new Utf8JsonReader(sequence, isFinalBlock: true, state: default);
+
+ //Debugger.Launch();
+
+ var byteArr = bytes.ToArray();
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options, (l, r) => l.AsSpan().SequenceEqual(r.AsSpan()));
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync(byteArr, sequence, options);
+ TestDeserializeAsync