diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs index 2be0f0489000f2..26cbeb7a25fc61 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs @@ -18,7 +18,7 @@ internal override bool OnTryRead( scoped ref ReadStack state, out Memory value) { - if (reader.TokenType is JsonTokenType.Null) + if (reader.TokenType is JsonTokenType.Null && state.Current.ReturnValue is null) { value = default; return true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs index 6c6c079f6b878d..be069d580d8275 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs @@ -18,7 +18,7 @@ internal override bool OnTryRead( scoped ref ReadStack state, out ReadOnlyMemory value) { - if (reader.TokenType is JsonTokenType.Null) + if (reader.TokenType is JsonTokenType.Null && state.Current.ReturnValue is null) { value = default; return true; diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs index b99428c39c7d6c..26331175eeeb46 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Xunit; @@ -137,5 +139,39 @@ public async Task DeserializeMemoryByteClassAsync() MemoryOfTClass memoryOfByteClass = await Serializer.DeserializeWrapper>(json); AssertExtensions.SequenceEqual(s_testData.AsSpan(), memoryOfByteClass.Memory.Span); } + + [Fact] + public async Task DeserializeReadOnlyMemoryFromStreamWithManyNulls() + { + // Regression test for https://github.com/dotnet/runtime/issues/118346 + if (StreamingSerializer is null) + { + return; + } + + // Create an array of ~200 null elements to force resumptions with smallest buffer size + string json = $"[{string.Join(",", Enumerable.Repeat("null", 200))}]"; + using var stream = new Utf8MemoryStream(json); + ReadOnlyMemory result = await StreamingSerializer.DeserializeWrapper>(stream); + + Assert.Equal(200, result.Length); + } + + [Fact] + public async Task DeserializeMemoryFromStreamWithManyNulls() + { + // Regression test for https://github.com/dotnet/runtime/issues/118346 + if (StreamingSerializer is null) + { + return; + } + + // Create an array of ~200 null elements to force resumptions with smallest buffer size + string json = $"[{string.Join(",", Enumerable.Repeat("null", 200))}]"; + using var stream = new Utf8MemoryStream(json); + Memory result = await StreamingSerializer.DeserializeWrapper>(stream); + + Assert.Equal(200, result.Length); + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs index cb88437b6b552a..0551d24f6438cb 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs @@ -461,6 +461,8 @@ public async Task DeserializeAsyncEnumerable() [JsonSerializable(typeof(StackWrapper))] [JsonSerializable(typeof(ClassWithRecursiveCollectionTypes))] [JsonSerializable(typeof(MemoryOfTClass))] + [JsonSerializable(typeof(ReadOnlyMemory))] + [JsonSerializable(typeof(Memory))] [JsonSerializable(typeof(ReadOnlyMemoryOfTClass))] [JsonSerializable(typeof(MemoryOfTClass))] [JsonSerializable(typeof(ReadOnlyMemoryOfTClass))] @@ -883,6 +885,8 @@ public CollectionTests_Default() [JsonSerializable(typeof(StackWrapper))] [JsonSerializable(typeof(ClassWithRecursiveCollectionTypes))] [JsonSerializable(typeof(MemoryOfTClass))] + [JsonSerializable(typeof(ReadOnlyMemory))] + [JsonSerializable(typeof(Memory))] [JsonSerializable(typeof(ReadOnlyMemoryOfTClass))] [JsonSerializable(typeof(MemoryOfTClass))] [JsonSerializable(typeof(ReadOnlyMemoryOfTClass))]