Skip to content

Commit a858d3b

Browse files
backport opportunistic bugfixes
1 parent 5221db9 commit a858d3b

File tree

6 files changed

+32
-20
lines changed

6 files changed

+32
-20
lines changed

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ internal sealed override bool OnTryWrite(
312312

313313
if (!jsonPropertyInfo.GetMemberAndWriteJson(objectValue!, ref state, writer))
314314
{
315-
Debug.Assert(jsonPropertyInfo.ConverterBase.ConverterStrategy != ConverterStrategy.Value);
315+
Debug.Assert(jsonPropertyInfo.ConverterBase.ConverterStrategy != ConverterStrategy.Value ||
316+
jsonPropertyInfo.ConverterBase.TypeToConvert == JsonTypeInfo.ObjectType);
317+
316318
return false;
317319
}
318320

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, Json
476476

477477
// Ignore the naming policy for extension data.
478478
state.Current.IgnoreDictionaryKeyPolicy = true;
479+
state.Current.DeclaredJsonPropertyInfo = state.Current.JsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo;
479480

480481
success = dictionaryConverter.OnWriteResume(writer, value, options, ref state);
481482
if (success)

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@ private static string WriteUsingMetadata<TValue>(in TValue value, JsonTypeInfo?
125125
throw new ArgumentNullException(nameof(jsonTypeInfo));
126126
}
127127

128-
WriteStack state = default;
129-
state.Initialize(jsonTypeInfo, supportContinuation: false);
130-
131128
JsonSerializerOptions options = jsonTypeInfo.Options;
132129

133130
using (var output = new PooledByteBufferWriter(options.DefaultBufferSize))

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,7 @@ static void AppendStackFrame(StringBuilder sb, in ReadStackFrame frame)
258258

259259
if (frame.JsonTypeInfo != null && frame.IsProcessingEnumerable())
260260
{
261-
IEnumerable? enumerable = (IEnumerable?)frame.ReturnValue;
262-
if (enumerable == null)
261+
if (frame.ReturnValue is not IEnumerable enumerable)
263262
{
264263
return;
265264
}

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,10 @@ public void DisposePendingDisposablesOnException()
253253
DisposeFrame(Current.CollectionEnumerator, ref exception);
254254

255255
int stackSize = Math.Max(_count, _continuationCount);
256-
if (stackSize > 1)
256+
for (int i = 0; i < stackSize - 1; i++)
257257
{
258-
for (int i = 0; i < stackSize - 1; i++)
259-
{
260-
Debug.Assert(_previous[i].AsyncEnumerator is null);
261-
DisposeFrame(_previous[i].CollectionEnumerator, ref exception);
262-
}
258+
Debug.Assert(_previous[i].AsyncEnumerator is null);
259+
DisposeFrame(_previous[i].CollectionEnumerator, ref exception);
263260
}
264261

265262
if (exception is not null)
@@ -294,12 +291,9 @@ public async ValueTask DisposePendingDisposablesOnExceptionAsync()
294291
exception = await DisposeFrame(Current.CollectionEnumerator, Current.AsyncEnumerator, exception).ConfigureAwait(false);
295292

296293
int stackSize = Math.Max(_count, _continuationCount);
297-
if (stackSize > 1)
294+
for (int i = 0; i < stackSize - 1; i++)
298295
{
299-
for (int i = 0; i < stackSize - 1; i++)
300-
{
301-
exception = await DisposeFrame(_previous[i].CollectionEnumerator, _previous[i].AsyncEnumerator, exception).ConfigureAwait(false);
302-
}
296+
exception = await DisposeFrame(_previous[i].CollectionEnumerator, _previous[i].AsyncEnumerator, exception).ConfigureAwait(false);
303297
}
304298

305299
if (exception is not null)
@@ -353,7 +347,7 @@ public string PropertyPath()
353347

354348
return sb.ToString();
355349

356-
void AppendStackFrame(StringBuilder sb, in WriteStackFrame frame)
350+
static void AppendStackFrame(StringBuilder sb, in WriteStackFrame frame)
357351
{
358352
// Append the property name.
359353
string? propertyName = frame.DeclaredJsonPropertyInfo?.MemberInfo?.Name;
@@ -366,7 +360,7 @@ void AppendStackFrame(StringBuilder sb, in WriteStackFrame frame)
366360
AppendPropertyName(sb, propertyName);
367361
}
368362

369-
void AppendPropertyName(StringBuilder sb, string? propertyName)
363+
static void AppendPropertyName(StringBuilder sb, string? propertyName)
370364
{
371365
if (propertyName != null)
372366
{

src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.IgnoreCycles.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace System.Text.Json.Serialization.Tests
1414
public class ReferenceHandlerTests_IgnoreCycles
1515
{
1616
private static readonly JsonSerializerOptions s_optionsIgnoreCycles =
17-
new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles };
17+
new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles, DefaultBufferSize = 1 };
1818

1919
[Fact]
2020
public async Task IgnoreCycles_OnObject()
@@ -401,6 +401,25 @@ public async void IgnoreCycles_BoxedValueShouldNotBeIgnored()
401401
await Test_Serialize_And_SerializeAsync_Contains(root, expectedSubstring: @"""DayOfBirth"":15", expectedTimes: 2, s_optionsIgnoreCycles);
402402
}
403403

404+
[Fact]
405+
public async Task CycleDetectionStatePersistsAcrossContinuations()
406+
{
407+
string expectedValueJson = @"{""LargePropertyName"":""A large-ish string to force continuations"",""Nested"":null}";
408+
var recVal = new RecursiveValue { LargePropertyName = "A large-ish string to force continuations" };
409+
recVal.Nested = recVal;
410+
411+
var value = new List<RecursiveValue> { recVal, recVal };
412+
string expectedJson = $"[{expectedValueJson},{expectedValueJson}]";
413+
414+
await Test_Serialize_And_SerializeAsync(value, expectedJson, s_optionsIgnoreCycles);
415+
}
416+
417+
public class RecursiveValue
418+
{
419+
public string LargePropertyName { get; set; }
420+
public RecursiveValue? Nested { get; set; }
421+
}
422+
404423
private async Task Test_Serialize_And_SerializeAsync<T>(T obj, string expected, JsonSerializerOptions options)
405424
{
406425
string json;

0 commit comments

Comments
 (0)