Skip to content

Commit

Permalink
Fix JsonSerializer (#2553)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored Aug 1, 2021
1 parent 2040537 commit bebba35
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 10 deletions.
20 changes: 17 additions & 3 deletions src/neo/SmartContract/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Neo.VM.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
Expand Down Expand Up @@ -148,10 +149,18 @@ public static byte[] SerializeToByteArray(StackItem item, uint maxSize)
/// Deserializes a <see cref="StackItem"/> from <see cref="JObject"/>.
/// </summary>
/// <param name="json">The <see cref="JObject"/> to deserialize.</param>
/// <param name="limits">The limits for the deserialization.</param>
/// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param>
/// <returns>The deserialized <see cref="StackItem"/>.</returns>
public static StackItem Deserialize(JObject json, ReferenceCounter referenceCounter = null)
public static StackItem Deserialize(JObject json, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null)
{
uint maxStackSize = limits.MaxStackSize;
return Deserialize(json, ref maxStackSize, referenceCounter);
}

private static StackItem Deserialize(JObject json, ref uint maxStackSize, ReferenceCounter referenceCounter)
{
if (maxStackSize-- == 0) throw new FormatException();
switch (json)
{
case null:
Expand All @@ -160,7 +169,10 @@ public static StackItem Deserialize(JObject json, ReferenceCounter referenceCoun
}
case JArray array:
{
return new Array(referenceCounter, array.Select(p => Deserialize(p, referenceCounter)));
List<StackItem> list = new(array.Count);
foreach (JObject obj in array)
list.Add(Deserialize(obj, ref maxStackSize, referenceCounter));
return new Array(referenceCounter, list);
}
case JString str:
{
Expand All @@ -182,8 +194,10 @@ public static StackItem Deserialize(JObject json, ReferenceCounter referenceCoun

foreach (var entry in obj.Properties)
{
if (maxStackSize-- == 0) throw new FormatException();

var key = entry.Key;
var value = Deserialize(entry.Value, referenceCounter);
var value = Deserialize(entry.Value, ref maxStackSize, referenceCounter);

item[key] = value;
}
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Native/StdLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private static byte[] JsonSerialize(ApplicationEngine engine, StackItem item)
[ContractMethod(CpuFee = 1 << 14)]
private static StackItem JsonDeserialize(ApplicationEngine engine, byte[] json)
{
return JsonSerializer.Deserialize(JObject.Parse(json, 10), engine.ReferenceCounter);
return JsonSerializer.Deserialize(JObject.Parse(json, 10), engine.Limits, engine.ReferenceCounter);
}

/// <summary>
Expand Down
13 changes: 7 additions & 6 deletions tests/neo.UnitTests/SmartContract/UT_JsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO.Json;
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Linq;
Expand Down Expand Up @@ -181,7 +182,7 @@ public void JsonTest_Object()
[TestMethod]
public void Deserialize_WrongJson()
{
Assert.ThrowsException<FormatException>(() => JsonSerializer.Deserialize(JObject.Parse("x")));
Assert.ThrowsException<FormatException>(() => JsonSerializer.Deserialize(JObject.Parse("x"), ExecutionEngineLimits.Default));
}

[TestMethod]
Expand Down Expand Up @@ -215,7 +216,7 @@ public void Serialize_Null()
[TestMethod]
public void Deserialize_EmptyObject()
{
var items = JsonSerializer.Deserialize(JObject.Parse("{}"));
var items = JsonSerializer.Deserialize(JObject.Parse("{}"), ExecutionEngineLimits.Default);

Assert.IsInstanceOfType(items, typeof(Map));
Assert.AreEqual(((Map)items).Count, 0);
Expand All @@ -233,7 +234,7 @@ public void Serialize_EmptyArray()
[TestMethod]
public void Deserialize_EmptyArray()
{
var items = JsonSerializer.Deserialize(JObject.Parse("[]"));
var items = JsonSerializer.Deserialize(JObject.Parse("[]"), ExecutionEngineLimits.Default);

Assert.IsInstanceOfType(items, typeof(VM.Types.Array));
Assert.AreEqual(((VM.Types.Array)items).Count, 0);
Expand All @@ -257,7 +258,7 @@ public void Serialize_Map_Test()
[TestMethod]
public void Deserialize_Map_Test()
{
var items = JsonSerializer.Deserialize(JObject.Parse("{\"test1\":123,\"test2\":321}"));
var items = JsonSerializer.Deserialize(JObject.Parse("{\"test1\":123,\"test2\":321}"), ExecutionEngineLimits.Default);

Assert.IsInstanceOfType(items, typeof(Map));
Assert.AreEqual(((Map)items).Count, 2);
Expand Down Expand Up @@ -286,7 +287,7 @@ public void Serialize_Array_Bool_Str_Num()
[TestMethod]
public void Deserialize_Array_Bool_Str_Num()
{
var items = JsonSerializer.Deserialize(JObject.Parse("[true,\"test\",123]"));
var items = JsonSerializer.Deserialize(JObject.Parse("[true,\"test\",123]"), ExecutionEngineLimits.Default);

Assert.IsInstanceOfType(items, typeof(VM.Types.Array));
Assert.AreEqual(((VM.Types.Array)items).Count, 3);
Expand Down Expand Up @@ -315,7 +316,7 @@ public void Serialize_Array_OfArray()
[TestMethod]
public void Deserialize_Array_OfArray()
{
var items = JsonSerializer.Deserialize(JObject.Parse("[[true,\"test1\",123],[true,\"test2\",321]]"));
var items = JsonSerializer.Deserialize(JObject.Parse("[[true,\"test1\",123],[true,\"test2\",321]]"), ExecutionEngineLimits.Default);

Assert.IsInstanceOfType(items, typeof(VM.Types.Array));
Assert.AreEqual(((VM.Types.Array)items).Count, 2);
Expand Down

0 comments on commit bebba35

Please sign in to comment.