From 53bb7dd10d7dd4c2b6280d7c011934fc95d0be21 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Thu, 24 Mar 2022 13:06:32 +0000 Subject: [PATCH] Fix #66727. (#67041) --- .../JsonSerializer.Read.HandleMetadata.cs | 5 +++++ .../src/System/Text/Json/Serialization/ReadStack.cs | 12 ++++++++---- .../src/System/Text/Json/Serialization/WriteStack.cs | 12 ++++++++---- .../Serialization/ReferenceHandlerTests.cs | 1 - 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs index b34efae2572..e61b52c7c11 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs @@ -336,6 +336,11 @@ public static partial class JsonSerializer if (state.Current.ObjectState == StackFrameObjectState.ReadValuesStartArray) { + // Temporary workaround for the state machine accidentally + // erasing the JsonPropertyName property in certain async + // re-entrancy patterns. + state.Current.JsonPropertyName = s_valuesPropertyName; + if (reader.TokenType != JsonTokenType.StartArray) { ThrowHelper.ThrowJsonException_MetadataValuesInvalidToken(reader.TokenType); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index 1bdbba54e5f..c1a748ee440 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -208,15 +208,19 @@ public string JsonPath() { StringBuilder sb = new StringBuilder("$"); - // If a continuation, always report back full stack which does not use Current for the last frame. - int count = Math.Max(_count, _continuationCount + 1); + (int frameCount, bool includeCurrentFrame) = _continuationCount switch + { + 0 => (_count - 1, true), // Not a countinuation, report previous frames and Current. + 1 => (0, true), // Continuation of depth 1, just report Current frame. + int c => (c, false) // Continuation of depth > 1, report the entire stack. + }; - for (int i = 0; i < count - 1; i++) + for (int i = 0; i < frameCount; i++) { AppendStackFrame(sb, ref _stack[i]); } - if (_continuationCount == 0) + if (includeCurrentFrame) { AppendStackFrame(sb, ref Current); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs index a73532d0187..44ce28ed701 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs @@ -332,15 +332,19 @@ public string PropertyPath() { StringBuilder sb = new StringBuilder("$"); - // If a continuation, always report back full stack which does not use Current for the last frame. - int count = Math.Max(_count, _continuationCount + 1); + (int frameCount, bool includeCurrentFrame) = _continuationCount switch + { + 0 => (_count - 1, true), // Not a countinuation, report previous frames and Current. + 1 => (0, true), // Continuation of depth 1, just report Current frame. + int c => (c, false) // Continuation of depth > 1, report the entire stack. + }; - for (int i = 0; i < count - 1; i++) + for (int i = 0; i < frameCount; i++) { AppendStackFrame(sb, ref _stack[i]); } - if (_continuationCount == 0) + if (includeCurrentFrame) { AppendStackFrame(sb, ref Current); } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs index a9257142a40..3cfcdbeff8d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs @@ -15,7 +15,6 @@ public sealed class ReferenceHandlerTestsDynamic_AsyncStream : ReferenceHandlerT public ReferenceHandlerTestsDynamic_AsyncStream() : base(JsonSerializerWrapper.AsyncStreamSerializer) { } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/66727")] public sealed class ReferenceHandlerTestsDynamic_AsyncStreamWithSmallBuffer : ReferenceHandlerTests { public ReferenceHandlerTestsDynamic_AsyncStreamWithSmallBuffer() : base(JsonSerializerWrapper.AsyncStreamSerializerWithSmallBuffer) { } -- GitLab