Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/libraries/System.Text.Json/System.Text.Json.sln
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "System.Text.Json.FSharp.Tes
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.TestLibrary.Roslyn3.11", "tests\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn3.11.csproj", "{5C0CE30B-DD4A-4F7A-87C0-5243F0C86885}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.TestLibrary.Roslyn4.0", "tests\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn4.0.csproj", "{FCA21178-0411-45D6-B597-B7BE145CEE33}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.TestLibrary.Roslyn4.4", "tests\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn4.4.csproj", "{FCA21178-0411-45D6-B597-B7BE145CEE33}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn3.11.Tests", "tests\System.Text.Json.SourceGeneration.Tests\System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj", "{66AD4B7E-CF15-4A8F-8BF8-7E1BC6176D07}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn4.0.Tests", "tests\System.Text.Json.SourceGeneration.Tests\System.Text.Json.SourceGeneration.Roslyn4.0.Tests.csproj", "{33599A6C-F340-4E1B-9B4D-CB8946C22140}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn4.4.Tests", "tests\System.Text.Json.SourceGeneration.Tests\System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csproj", "{33599A6C-F340-4E1B-9B4D-CB8946C22140}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn3.11.Unit.Tests", "tests\System.Text.Json.SourceGeneration.Unit.Tests\System.Text.Json.SourceGeneration.Roslyn3.11.Unit.Tests.csproj", "{256A4653-4287-44B3-BDEF-67FC1522ED2F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn4.0.Unit.Tests", "tests\System.Text.Json.SourceGeneration.Unit.Tests\System.Text.Json.SourceGeneration.Roslyn4.0.Unit.Tests.csproj", "{F6A18EB5-A8CC-4A39-9E85-5FA226019C3D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests", "tests\System.Text.Json.SourceGeneration.Unit.Tests\System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests.csproj", "{F6A18EB5-A8CC-4A39-9E85-5FA226019C3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.Tests", "tests\System.Text.Json.Tests\System.Text.Json.Tests.csproj", "{A0178BAA-A1AF-4C69-8E4A-A700A2723DDC}"
EndProject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace System.Text.Json
/// </remarks>
public sealed partial class JsonDocument : IDisposable
{
private ReadOnlyMemory<byte> _utf8Json;
private readonly ReadOnlyMemory<byte> _utf8Json;
private MetadataDb _parsedData;

private byte[]? _extraRentedArrayPoolBytes;
Expand All @@ -41,7 +41,11 @@ private JsonDocument(
PooledByteBufferWriter? extraPooledByteBufferWriter = null,
bool isDisposable = true)
{
Debug.Assert(!utf8Json.IsEmpty);
if (utf8Json.IsEmpty)
{
// replaces debug assertion with runtime check.
throw new ArgumentException();
}

// Both rented values better be null if we're not disposable.
Debug.Assert(isDisposable ||
Expand All @@ -60,32 +64,7 @@ private JsonDocument(
/// <inheritdoc />
public void Dispose()
{
int length = _utf8Json.Length;
if (length == 0 || !IsDisposable)
{
return;
}

_parsedData.Dispose();
_utf8Json = ReadOnlyMemory<byte>.Empty;

if (_extraRentedArrayPoolBytes != null)
{
byte[]? extraRentedBytes = Interlocked.Exchange<byte[]?>(ref _extraRentedArrayPoolBytes, null);

if (extraRentedBytes != null)
{
// When "extra rented bytes exist" it contains the document,
// and thus needs to be cleared before being returned.
extraRentedBytes.AsSpan(0, length).Clear();
ArrayPool<byte>.Shared.Return(extraRentedBytes);
}
}
else if (_extraPooledByteBufferWriter != null)
{
PooledByteBufferWriter? extraBufferWriter = Interlocked.Exchange<PooledByteBufferWriter?>(ref _extraPooledByteBufferWriter, null);
extraBufferWriter?.Dispose();
}
// Make no-op, disables clearing of the _utf8Json buffer
}

/// <summary>
Expand Down Expand Up @@ -1059,6 +1038,7 @@ private static void Parse(

private void CheckNotDisposed()
{
// Given the other changes in this class, this should never be true.
if (_utf8Json.IsEmpty)
{
ThrowHelper.ThrowObjectDisposedException_JsonDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<Import Project="System.Text.Json.TestLibrary.targets" />

<ItemGroup>
<ProjectReference Include="..\..\gen\System.Text.Json.SourceGeneration.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\..\gen\System.Text.Json.SourceGeneration.Roslyn4.4.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text;
using System.Text.Json.Serialization;
using Xunit;

namespace System.Text.Json.SourceGeneration.Tests
{
public sealed class WasmReproTest
{
[Fact]
public static void TestFailingOnWasmOnly()
{
// Failing test adapted from ReferenceHandlerTests.ReadTestClassesWithExtensionOption

var options = new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.Preserve
};

string json = GetLargeJsonObject();

// First five calls succeed without issue
for (int i = 0; i < 5; i++)
{
object value = JsonSerializer.Deserialize<object>(json, options);
Assert.IsType<JsonElement>(value);
}

// Fails on wasm release:
// System.ObjectDisposedException : Cannot access a disposed object.
// Object name: 'JsonDocument'.
// at System.Text.Json.ThrowHelper.ThrowObjectDisposedException_JsonDocument()
// at System.Text.Json.JsonDocument.CheckNotDisposed()
// at System.Text.Json.JsonDocument.TextEquals(Int32 index, ReadOnlySpan`1 otherUtf8Text, Boolean isPropertyName, Boolean shouldUnescape)
// at System.Text.Json.JsonElement.TextEqualsHelper(ReadOnlySpan`1 utf8Text, Boolean isPropertyName, Boolean shouldUnescape)
// at System.Text.Json.JsonProperty.EscapedNameEquals(ReadOnlySpan`1 utf8Text)
// at System.Text.Json.JsonSerializer.TryHandleReferenceFromJsonElement(Utf8JsonReader& reader, ReadStack& state, JsonElement element, Object& referenceValue)
// at System.Text.Json.Serialization.Converters.ObjectConverter.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, Rea
JsonSerializer.Deserialize<object>(json, options);
}

private static string GetLargeJsonObject()
{
var sb = new StringBuilder();
sb.Append('{');

for (int i = 0; i < 200; i++)
{
sb.Append($@"""Key{i}"":{i},");
}

sb.Length -= 1;
sb.Append('}');
return sb.ToString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<ItemGroup Condition="'$(ContinuousIntegrationBuild)' == 'true'">
<HighAotMemoryUsageAssembly Include="Microsoft.CodeAnalysis.CSharp.dll" />
<HighAotMemoryUsageAssembly Include="System.Text.Json.SourceGeneration.Roslyn4.0.Tests.dll"/>
<HighAotMemoryUsageAssembly Include="System.Text.Json.SourceGeneration.Roslyn4.4.Tests.dll" />
</ItemGroup>

<Import Project="System.Text.Json.SourceGeneration.Tests.targets" />

<ItemGroup>
<ProjectReference Include="..\..\gen\System.Text.Json.SourceGeneration.Roslyn4.0.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn4.0.csproj" />
<ProjectReference Include="..\..\gen\System.Text.Json.SourceGeneration.Roslyn4.4.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" SetTargetFramework="TargetFramework=netstandard2.0" SkipGetTargetFrameworkProperties="true" />
<ProjectReference Include="..\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn4.4.csproj" />
</ItemGroup>
</Project>
Loading