Skip to content

Commit

Permalink
Add MaxNestedItems to WitnessCondition.FromJson (#2951)
Browse files Browse the repository at this point in the history
* Add MaxNestedItems WitnessCondition.FromJson

* Ensure action

* Fix SubItems
  • Loading branch information
shargon committed Nov 8, 2023
1 parent d824357 commit ec6ddf6
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 34 deletions.
8 changes: 6 additions & 2 deletions src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Expressions);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Expressions = ((JArray)json["expressions"]).Select(p => FromJson((JObject)p)).ToArray();
if (maxNestDepth <= 0) throw new FormatException();
JArray expressions = (JArray)json["expressions"];
if (expressions.Count > MaxSubitems) throw new FormatException();
Expressions = expressions.Select(p => FromJson((JObject)p, maxNestDepth - 1)).ToArray();
if (Expressions.Length == 0) throw new FormatException();
}

public override JObject ToJson()
Expand Down
7 changes: 4 additions & 3 deletions src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.IO;
using Neo.IO;
using Neo.Json;
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
using System.IO;

namespace Neo.Network.P2P.Payloads.Conditions
{
Expand Down Expand Up @@ -42,7 +43,7 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Expression);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Expression = json["expression"].GetBoolean();
}
Expand All @@ -56,7 +57,7 @@ public override JObject ToJson()

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
{
var result = (Array)base.ToStackItem(referenceCounter);
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Expression);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.IO;

namespace Neo.Network.P2P.Payloads.Conditions
Expand Down Expand Up @@ -42,7 +43,7 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Hash);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Hash = UInt160.Parse(json["hash"].GetString());
}
Expand All @@ -56,7 +57,7 @@ public override JObject ToJson()

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
{
var result = (Array)base.ToStackItem(referenceCounter);
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Hash.ToArray());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// modifications are permitted.

using Neo.IO;
using Neo.Json;
using Neo.SmartContract;
using System.IO;

Expand All @@ -18,10 +19,6 @@ public class CalledByEntryCondition : WitnessCondition
{
public override WitnessConditionType Type => WitnessConditionType.CalledByEntry;

protected override void DeserializeWithoutType(ref MemoryReader reader, int maxNestDepth)
{
}

public override bool Match(ApplicationEngine engine)
{
var state = engine.CurrentContext.GetState<ExecutionContextState>();
Expand All @@ -30,8 +27,10 @@ public override bool Match(ApplicationEngine engine)
return state.CallingContext is null;
}

protected override void SerializeWithoutType(BinaryWriter writer)
{
}
protected override void DeserializeWithoutType(ref MemoryReader reader, int maxNestDepth) { }

protected override void SerializeWithoutType(BinaryWriter writer) { }

private protected override void ParseJson(JObject json, int maxNestDepth) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.IO;
using System.Linq;

Expand Down Expand Up @@ -47,7 +48,7 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Group);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Group = ECPoint.Parse(json["group"].GetString(), ECCurve.Secp256r1);
}
Expand All @@ -61,7 +62,7 @@ public override JObject ToJson()

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
{
var result = (Array)base.ToStackItem(referenceCounter);
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Group.ToArray());
return result;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.IO;
using System.Linq;

Expand Down Expand Up @@ -47,7 +48,7 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Group);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Group = ECPoint.Parse(json["group"].GetString(), ECCurve.Secp256r1);
}
Expand All @@ -61,7 +62,7 @@ public override JObject ToJson()

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
{
var result = (Array)base.ToStackItem(referenceCounter);
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Group.ToArray());
return result;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Expression);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Expression = FromJson((JObject)json["expression"]);
if (maxNestDepth <= 0) throw new FormatException();
Expression = FromJson((JObject)json["expression"], maxNestDepth - 1);
}

public override JObject ToJson()
Expand Down
8 changes: 6 additions & 2 deletions src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Expressions);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Expressions = ((JArray)json["expressions"]).Select(p => FromJson((JObject)p)).ToArray();
if (maxNestDepth <= 0) throw new FormatException();
JArray expressions = (JArray)json["expressions"];
if (expressions.Count > MaxSubitems) throw new FormatException();
Expressions = expressions.Select(p => FromJson((JObject)p, maxNestDepth - 1)).ToArray();
if (Expressions.Length == 0) throw new FormatException();
}

public override JObject ToJson()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Neo.SmartContract;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.IO;

namespace Neo.Network.P2P.Payloads.Conditions
Expand Down Expand Up @@ -42,7 +43,7 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(Hash);
}

private protected override void ParseJson(JObject json)
private protected override void ParseJson(JObject json, int maxNestDepth)
{
Hash = UInt160.Parse(json["hash"].GetString());
}
Expand All @@ -56,7 +57,7 @@ public override JObject ToJson()

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
{
var result = (Array)base.ToStackItem(referenceCounter);
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Hash.ToArray());
return result;
}
Expand Down
11 changes: 5 additions & 6 deletions src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Neo.Network.P2P.Payloads.Conditions
{
public abstract class WitnessCondition : IInteroperable, ISerializable
{
private const int MaxSubitems = 16;
internal const int MaxSubitems = 16;
internal const int MaxNestingDepth = 2;

/// <summary>
Expand Down Expand Up @@ -92,21 +92,20 @@ void ISerializable.Serialize(BinaryWriter writer)
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
protected abstract void SerializeWithoutType(BinaryWriter writer);

private protected virtual void ParseJson(JObject json)
{
}
private protected abstract void ParseJson(JObject json, int maxNestDepth);

/// <summary>
/// Converts the <see cref="WitnessCondition"/> from a JSON object.
/// </summary>
/// <param name="json">The <see cref="WitnessCondition"/> represented by a JSON object.</param>
/// <param name="maxNestDepth">The maximum nesting depth allowed during deserialization.</param>
/// <returns>The converted <see cref="WitnessCondition"/>.</returns>
public static WitnessCondition FromJson(JObject json)
public static WitnessCondition FromJson(JObject json, int maxNestDepth)
{
WitnessConditionType type = Enum.Parse<WitnessConditionType>(json["type"].GetString());
if (ReflectionCache<WitnessConditionType>.CreateInstance(type) is not WitnessCondition condition)
throw new FormatException("Invalid WitnessConditionType.");
condition.ParseJson(json);
condition.ParseJson(json, maxNestDepth);
return condition;
}

Expand Down
9 changes: 7 additions & 2 deletions src/Neo/Network/P2P/Payloads/WitnessRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ void ISerializable.Serialize(BinaryWriter writer)
/// <returns>The converted <see cref="WitnessRule"/>.</returns>
public static WitnessRule FromJson(JObject json)
{
WitnessRuleAction action = Enum.Parse<WitnessRuleAction>(json["action"].GetString());

if (action != WitnessRuleAction.Allow && action != WitnessRuleAction.Deny)
throw new FormatException();

return new()
{
Action = Enum.Parse<WitnessRuleAction>(json["action"].GetString()),
Condition = WitnessCondition.FromJson((JObject)json["condition"])
Action = action,
Condition = WitnessCondition.FromJson((JObject)json["condition"], WitnessCondition.MaxNestingDepth)
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void TestFromJson1()
}
};
var json = condition.ToJson();
var new_condi = WitnessCondition.FromJson(json);
var new_condi = WitnessCondition.FromJson(json, 2);
Assert.IsTrue(new_condi is OrCondition);
var or_condi = (OrCondition)new_condi;
Assert.AreEqual(2, or_condi.Expressions.Length);
Expand All @@ -42,7 +42,7 @@ public void TestFromJson2()
var hash2 = UInt160.Parse("0xd2a4cff31913016155e38e474a2c06d08be276cf");
var jstr = "{\"type\":\"Or\",\"expressions\":[{\"type\":\"And\",\"expressions\":[{\"type\":\"CalledByContract\",\"hash\":\"0x0000000000000000000000000000000000000000\"},{\"type\":\"ScriptHash\",\"hash\":\"0xd2a4cff31913016155e38e474a2c06d08be276cf\"}]},{\"type\":\"Or\",\"expressions\":[{\"type\":\"CalledByGroup\",\"group\":\"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c\"},{\"type\":\"Boolean\",\"expression\":true}]}]}";
var json = (JObject)JToken.Parse(jstr);
var condi = WitnessCondition.FromJson(json);
var condi = WitnessCondition.FromJson(json, 2);
var or_condi = (OrCondition)condi;
Assert.AreEqual(2, or_condi.Expressions.Length);
var and_condi = (AndCondition)or_condi.Expressions[0];
Expand Down

0 comments on commit ec6ddf6

Please sign in to comment.