Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert,
ThrowHelper.ThrowJsonException_UnionCannotCreateValue(typeToConvert);
}

if (reader.TokenType is JsonTokenType.Null)
if (reader.TokenType is JsonTokenType.Null && reader.CurrentDepth == state.Current.OriginalDepth)
{
Type? nullableCaseType = typeInfo.UnionNullableCaseType;
if (nullableCaseType is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public NullableConverter(JsonConverter<T> elementConverter)

internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, scoped ref ReadStack state, out T? value)
{
if (!state.IsContinuation && reader.TokenType == JsonTokenType.Null)
if (reader.TokenType == JsonTokenType.Null && reader.CurrentDepth == state.Current.OriginalDepth)
Comment thread
prozolic marked this conversation as resolved.
{
value = null;
return true;
Comment thread
prozolic marked this conversation as resolved.
Expand Down
16 changes: 16 additions & 0 deletions src/libraries/System.Text.Json/tests/Common/UnionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,22 @@ public async Task UnionWithDefaultTokenClassification_RoundTripsObjectCaseAsProp
Assert.Equal(new[] { 6, 7, 8 }, payload.Values);
}

[Fact]
public async Task UnionWithDefaultTokenClassification_ObjectCaseWithNullPropertyAsPropertyWithSmallBuffer()
{
JsonSerializerOptions options = CreateSmallBufferOptions();

string json = """{"Union":{"Name":null,"Values":[6,7,8]},"After":42}""";
UnionContainer? result = await Serializer.DeserializeWrapper<UnionContainer>(json, options);

Assert.NotNull(result);
Assert.Equal(42, result!.After);
Assert.NotNull(result.Union);
PayloadCase payload = Assert.IsType<PayloadCase>(GetUnionValue(result.Union!));
Assert.Null(payload.Name);
Assert.Equal(new[] { 6, 7, 8 }, payload.Values);
}

[Fact]
public async Task UnionWithDefaultTokenClassification_RoundTripsNullableScalarCaseAsPropertyWithSmallBuffer()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using Xunit;

namespace System.Text.Json.Serialization.Tests
Expand Down Expand Up @@ -489,5 +490,29 @@ public struct RecursiveNullableStruct
{
public RecursiveNullableStruct?[] Next { get; set; }
}

[Fact]
public static void NullableStructProperty_StreamWithContinuationAfterNullToken()
{
string json = """{"Value":{"Total":1,"a":null,"b":0}}""";
byte[] bytes = Encoding.UTF8.GetBytes(json);
var options = new JsonSerializerOptions { DefaultBufferSize = 32 };

using var stream = new MemoryStream(bytes);
var fromStream = JsonSerializer.Deserialize<MyPoco>(stream, options)!;
Assert.NotNull(fromStream);
Assert.NotNull(fromStream.Value);
Assert.Equal(1, fromStream.Value.Value.Total);
}

public class MyPoco
{
public MyStruct? Value { get; set; }
}

public struct MyStruct
{
public int Total { get; set; }
}
Comment thread
prozolic marked this conversation as resolved.
}
}
Loading