Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 97af4b4

Browse files
Thieztarekgh
authored andcommitted
Fix various issues with System.Json.JsonValue.Save (#26502)
* Fix various issues with System.Json.JsonValue.Save The `JsonObject` class overrides `JsonValue.Save(Stream)`, but was implemented incorrectly: it would produce output resembling `{"key1","value1""key2","value2"}`, instead of the more reasonable `{"key1": "value1", "key2": "value2"}`. Because `JsonValue` already contains code that can properly serialize a `JsonObject`, the override now simply calls the base method. In addition, it turns out that the `JsonValue.Save(Stream)` method was also implemented incorrectly. This method would invoke `JsonValue.Save(TetxtWriter)`, but the `StreamWriter` it created was never flushed or disposed, so output could go missing. In addition, it would encode json as utf-8, but would include a BOM, while none of the methods that override `JsonValue.Save(Stream)` would write a BOM. Both these issues have been resolved. The tests have also been modified to test for the new and correct behavior. * PR fixes * Add reference to System.Text.Encoding.Extensions
1 parent 3f3e8ec commit 97af4b4

File tree

5 files changed

+25
-32
lines changed

5 files changed

+25
-32
lines changed

src/System.Json/src/System.Json.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<Reference Include="System.Runtime" />
3232
<Reference Include="System.Runtime.Extensions" />
3333
<Reference Include="System.Text.Encoding" />
34+
<Reference Include="System.Text.Encoding.Extensions" />
3435
</ItemGroup>
3536
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
3637
</Project>

src/System.Json/src/System/Json/JsonObject.cs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -114,35 +114,7 @@ public bool Remove(string key)
114114

115115
public override void Save(Stream stream)
116116
{
117-
if (stream == null)
118-
{
119-
throw new ArgumentNullException(nameof(stream));
120-
}
121-
122-
stream.WriteByte((byte)'{');
123-
124-
foreach (JsonPair pair in _map)
125-
{
126-
stream.WriteByte((byte)'"');
127-
byte[] bytes = Encoding.UTF8.GetBytes(EscapeString(pair.Key));
128-
stream.Write(bytes, 0, bytes.Length);
129-
stream.WriteByte((byte)'"');
130-
stream.WriteByte((byte)',');
131-
stream.WriteByte((byte)' ');
132-
if (pair.Value == null)
133-
{
134-
stream.WriteByte((byte)'n');
135-
stream.WriteByte((byte)'u');
136-
stream.WriteByte((byte)'l');
137-
stream.WriteByte((byte)'l');
138-
}
139-
else
140-
{
141-
pair.Value.Save(stream);
142-
}
143-
}
144-
145-
stream.WriteByte((byte)'}');
117+
base.Save(stream);
146118
}
147119

148120
public bool TryGetValue(string key, out JsonValue value) => _map.TryGetValue(key, out value);

src/System.Json/src/System/Json/JsonValue.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ namespace System.Json
1515
{
1616
public abstract class JsonValue : IEnumerable
1717
{
18+
private static readonly UTF8Encoding s_encoding = new UTF8Encoding(false, true);
19+
1820
public static JsonValue Load(Stream stream)
1921
{
2022
if (stream == null)
@@ -122,7 +124,10 @@ public virtual void Save(Stream stream)
122124
throw new ArgumentNullException(nameof(stream));
123125
}
124126

125-
Save(new StreamWriter(stream));
127+
using (StreamWriter writer = new StreamWriter(stream, s_encoding, 1024, true))
128+
{
129+
Save(writer);
130+
}
126131
}
127132

128133
public virtual void Save(TextWriter textWriter)

src/System.Json/tests/JsonObjectTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ public void Save_Stream()
270270
{
271271
obj.Save(stream);
272272
string result = Encoding.UTF8.GetString(stream.ToArray());
273-
Assert.Equal("{\"key\", true\"key2\", null}", result);
273+
Assert.Equal("{\"key\": true, \"key2\": null}", result);
274274
}
275275
}
276276

src/System.Json/tests/JsonValueTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,22 @@ public void Save_Stream()
432432
using (MemoryStream stream = new MemoryStream())
433433
{
434434
value.Save(stream);
435-
Assert.Empty(stream.ToArray());
435+
string json = Encoding.UTF8.GetString(stream.ToArray());
436+
Assert.True(stream.CanWrite);
437+
Assert.Equal("Hello", json);
438+
}
439+
}
440+
441+
[Fact]
442+
public void Save_TextWriter()
443+
{
444+
JsonSubValue value = new JsonSubValue();
445+
446+
using (StringWriter writer = new StringWriter())
447+
{
448+
value.Save(writer);
449+
string json = writer.ToString();
450+
Assert.Equal("Hello", json);
436451
}
437452
}
438453

0 commit comments

Comments
 (0)