Skip to content

Commit

Permalink
Fix InvalidOperationException (#3558)
Browse files Browse the repository at this point in the history
* Fix InvalidOperationException

* use !

* Unify

* fix
  • Loading branch information
shargon authored Oct 30, 2024
1 parent 03ba1dc commit a42bc8d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
18 changes: 6 additions & 12 deletions src/Neo/SmartContract/ContractParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,28 +162,22 @@ private static JObject ToJson(ContractParameter parameter, HashSet<ContractParam
json["value"] = parameter.Value.ToString();
break;
case ContractParameterType.Array:
if (context is null)
context = new HashSet<ContractParameter>();
else if (context.Contains(parameter))
throw new InvalidOperationException();
context.Add(parameter);
context ??= [];
if (!context.Add(parameter)) throw new InvalidOperationException("Circular reference.");
json["value"] = new JArray(((IList<ContractParameter>)parameter.Value).Select(p => ToJson(p, context)));
context.Remove(parameter);
if (!context.Remove(parameter)) throw new InvalidOperationException("Circular reference.");
break;
case ContractParameterType.Map:
if (context is null)
context = new HashSet<ContractParameter>();
else if (context.Contains(parameter))
throw new InvalidOperationException();
context.Add(parameter);
context ??= [];
if (!context.Add(parameter)) throw new InvalidOperationException("Circular reference.");
json["value"] = new JArray(((IList<KeyValuePair<ContractParameter, ContractParameter>>)parameter.Value).Select(p =>
{
JObject item = new();
item["key"] = ToJson(p.Key, context);
item["value"] = ToJson(p.Value, context);
return item;
}));
context.Remove(parameter);
if (!context.Remove(parameter)) throw new InvalidOperationException("Circular reference.");
break;
}
return json;
Expand Down
6 changes: 4 additions & 2 deletions src/Neo/VM/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,14 @@ private static JObject ToJson(StackItem item, HashSet<StackItem> context, ref in
{
case Array array:
{
context ??= new HashSet<StackItem>(ReferenceEqualityComparer.Instance);
context ??= new(ReferenceEqualityComparer.Instance);
if (!context.Add(array)) throw new InvalidOperationException("Circular reference.");
maxSize -= 2/*[]*/+ Math.Max(0, (array.Count - 1))/*,*/;
JArray a = new();
foreach (StackItem stackItem in array)
a.Add(ToJson(stackItem, context, ref maxSize));
value = a;
if (!context.Remove(array)) throw new InvalidOperationException("Circular reference.");
break;
}
case Boolean boolean:
Expand All @@ -397,7 +398,7 @@ private static JObject ToJson(StackItem item, HashSet<StackItem> context, ref in
}
case Map map:
{
context ??= new HashSet<StackItem>(ReferenceEqualityComparer.Instance);
context ??= new(ReferenceEqualityComparer.Instance);
if (!context.Add(map)) throw new InvalidOperationException("Circular reference.");
maxSize -= 2/*[]*/+ Math.Max(0, (map.Count - 1))/*,*/;
JArray a = new();
Expand All @@ -412,6 +413,7 @@ private static JObject ToJson(StackItem item, HashSet<StackItem> context, ref in
a.Add(i);
}
value = a;
if (!context.Remove(map)) throw new InvalidOperationException("Circular reference.");
break;
}
case Pointer pointer:
Expand Down
24 changes: 24 additions & 0 deletions tests/Neo.UnitTests/VM/UT_Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -689,5 +689,29 @@ public void TestCharAsUInt16()
CollectionAssert.AreEqual(sbUInt16.ToArray(), sbChar.ToArray());
}
}

[TestMethod]
public void TestCyclicReference()
{
var map = new VM.Types.Map
{
[1] = 2,
};

var item = new VM.Types.Array
{
map,
map
};

// just check there is no exception
var json = item.ToJson();
Assert.AreEqual(json.ToString(), @"{""type"":""Array"",""value"":[{""type"":""Map"",""value"":[{""key"":{""type"":""Integer"",""value"":""1""},""value"":{""type"":""Integer"",""value"":""2""}}]},{""type"":""Map"",""value"":[{""key"":{""type"":""Integer"",""value"":""1""},""value"":{""type"":""Integer"",""value"":""2""}}]}]}");

// check cyclic reference
map[2] = item;
var action = () => item.ToJson();
action.Should().Throw<System.InvalidOperationException>();
}
}
}

0 comments on commit a42bc8d

Please sign in to comment.