Forráskód Böngészése

Forbid encoding and decoding of recursive types in sema (#1226)

Cyrill Leutwiler 2 éve
szülő
commit
bf6c6867fa

+ 7 - 7
src/sema/builtin.rs

@@ -1103,11 +1103,11 @@ pub(super) fn resolve_namespace_call(
                             broken = true;
                         }
 
-                        if ty.is_mapping() {
+                        if ty.is_mapping() || ty.is_recursive(ns) {
                             diagnostics.push(Diagnostic::error(
                                 *loc,
-                                "mapping cannot be abi decoded or encoded".to_string(),
-                            ));
+                        format!("Invalid type '{}': mappings and recursive types cannot be abi decoded or encoded", ty.to_string(ns)))
+                            );
                             broken = true;
                         }
 
@@ -1128,10 +1128,10 @@ pub(super) fn resolve_namespace_call(
                     diagnostics,
                 )?;
 
-                if ty.is_mapping() {
+                if ty.is_mapping() || ty.is_recursive(ns) {
                     diagnostics.push(Diagnostic::error(
                         *loc,
-                        "mapping cannot be abi decoded or encoded".to_string(),
+                        format!("Invalid type '{}': mappings and recursive types cannot be abi decoded or encoded", ty.to_string(ns))
                     ));
                     broken = true;
                 }
@@ -1301,10 +1301,10 @@ pub(super) fn resolve_namespace_call(
         let mut expr = expression(arg, context, ns, symtable, diagnostics, ResolveTo::Unknown)?;
         let ty = expr.ty();
 
-        if ty.is_mapping() {
+        if ty.is_mapping() || ty.is_recursive(ns) {
             diagnostics.push(Diagnostic::error(
                 arg.loc(),
-                "mapping type not permitted".to_string(),
+                format!("Invalid type '{}': mappings and recursive types cannot be abi decoded or encoded", ty.to_string(ns)),
             ));
 
             return Err(());

+ 18 - 0
tests/contract_testcases/substrate/builtins/abi_decode_05.dot

@@ -0,0 +1,18 @@
+strict digraph "tests/contract_testcases/substrate/builtins/abi_decode_05.sol" {
+	S [label="name:S\ncontract: Foo\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:2:9-10\nfield name:s ty:struct Foo.S[]"]
+	contract [label="contract Foo\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:1:1-9:2"]
+	decode [label="function decode\ncontract: Foo\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:3:2-38\nsignature decode(bytes)\nvisibility public\nmutability pure"]
+	parameters [label="parameters\nbytes b"]
+	encode [label="function encode\ncontract: Foo\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:6:2-31\nsignature encode()\nvisibility public\nmutability pure"]
+	diagnostic [label="found contract 'Foo'\nlevel Debug\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:1:1-9:2"]
+	diagnostic_9 [label="Invalid type 'struct Foo.S': mappings and recursive types cannot be abi decoded or encoded\nlevel Error\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:4:3-21"]
+	diagnostic_10 [label="Invalid type 'struct Foo.S': mappings and recursive types cannot be abi decoded or encoded\nlevel Error\ntests/contract_testcases/substrate/builtins/abi_decode_05.sol:7:14-34"]
+	structs -> S
+	contracts -> contract
+	contract -> decode [label="function"]
+	decode -> parameters [label="parameters"]
+	contract -> encode [label="function"]
+	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_9 [label="Error"]
+	diagnostics -> diagnostic_10 [label="Error"]
+}

+ 9 - 0
tests/contract_testcases/substrate/builtins/abi_decode_05.sol

@@ -0,0 +1,9 @@
+contract Foo {
+	struct S { S[] s; }
+	function decode(bytes b) public pure {
+		abi.decode(b, (S));
+	}
+	function encode() public pure {
+		abi.encode(S({ s: new S[](0) }));
+	}
+}