Selaa lähdekoodia

Deny direct function access for non base contracts

Deny direct function access for non base contracts

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Cyrill Leutwiler 3 vuotta sitten
vanhempi
sitoutus
8daea5b9fa

+ 11 - 1
src/sema/expression.rs

@@ -4555,7 +4555,7 @@ fn member_access(
                         diagnostics.push(Diagnostic::error(
                             e.loc(),
                             format!(
-                                "contract '{}' does not have a function called '{}'",
+                                "contract '{}' does not have a member called '{}'",
                                 ns.contracts[call_contract_no].name, id.name,
                             ),
                         ));
@@ -5852,6 +5852,11 @@ fn method_call_pos_args(
                         symtable,
                         diagnostics,
                     );
+                } else {
+                    diagnostics.push(Diagnostic::error(
+                        *loc,
+                        "function calls via contract name are only valid for base contracts".into(),
+                    ));
                 }
             }
         }
@@ -6677,6 +6682,11 @@ fn method_call_named_args(
                         symtable,
                         diagnostics,
                     );
+                } else {
+                    diagnostics.push(Diagnostic::error(
+                        *loc,
+                        "function calls via contract name are only valid for base contracts".into(),
+                    ));
                 }
             }
         }

+ 2 - 0
tests/contract_testcases/solana/constant/not_constant.dot

@@ -12,6 +12,7 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant.sol" {
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant.sol:2:9-4:10"]
 	diagnostic_13 [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant.sol:6:9-11:10"]
 	diagnostic_14 [label="'C' is a contract\nlevel Error\ntests/contract_testcases/solana/constant/not_constant.sol:8:26-27"]
+	diagnostic_15 [label="function calls via contract name are only valid for base contracts\nlevel Error\ntests/contract_testcases/solana/constant/not_constant.sol:8:26-36"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -25,4 +26,5 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant.sol" {
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic_13 [label="Debug"]
 	diagnostics -> diagnostic_14 [label="Error"]
+	diagnostics -> diagnostic_15 [label="Error"]
 }

+ 124 - 0
tests/contract_testcases/substrate/inheritance/base_contract_access_via_name.dot

@@ -0,0 +1,124 @@
+strict digraph "tests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol" {
+	contract [label="contract Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:1:1-10:2"]
+	var [label="variable FOO\nvisibility public\nconstant\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:2:5-36"]
+	number_literal [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:2:35-36"]
+	var_4 [label="variable something\nvisibility public\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:3:5-33"]
+	number_literal_5 [label="uint256 literal: 0\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:3:32-33"]
+	FOO [label="function FOO\ncontract: Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:2:29-32\nsignature FOO()\nvisibility public\nmutability view"]
+	returns [label="returns\nuint256 "]
+	return [label="return\nimplicit"]
+	constant [label="constant variable\nBase.FOO\nuint256\nimplicit"]
+	something [label="function something\ncontract: Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:3:20-29\nsignature something()\nvisibility public\nmutability view"]
+	returns_11 [label="returns\nuint256 "]
+	return_12 [label="return\nimplicit"]
+	storage_load [label="storage load uint256\nimplicit"]
+	storage_var [label="storage variable\nBase.something\nuint256 storage\nimplicit"]
+	nop [label="function nop\ncontract: Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:5:5-31\nsignature nop()\nvisibility public\nmutability pure"]
+	set [label="function set\ncontract: Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:7:5-45\nsignature set(uint256)\nvisibility public\nmutability nonpayable\nvirtual"]
+	parameters [label="parameters\nuint256 val"]
+	expr [label="expression\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:8:9-24"]
+	assign [label="assign\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:8:9-18"]
+	storage_var_20 [label="storage variable\nBase.something\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:8:9-18"]
+	variable [label="variable: val\nuint256\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:8:21-24"]
+	contract_22 [label="contract A\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:11:1-18:2"]
+	a [label="function a\ncontract: A\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:13:5-24\nsignature a()\nvisibility public\nmutability nonpayable"]
+	if [label="if\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:14:9-16:10"]
+	equal [label="equal\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:14:13-26"]
+	constant_26 [label="constant variable\nBase.FOO\nuint256\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:14:13-21"]
+	number_literal_27 [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:14:25-26"]
+	expr_28 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:15:13-24"]
+	builtins [label="builtin Print\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:15:13-18"]
+	alloc_array [label="alloc array string\ninitializer: 6869\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:15:19-23"]
+	number_literal_31 [label="uint32 literal: 2\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:15:19-23"]
+	contract_32 [label="contract B\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:19:1-24:2"]
+	b [label="function b\ncontract: B\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:21:5-24\nsignature b()\nvisibility public\nmutability nonpayable"]
+	expr_34 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:22:9-20"]
+	call_internal_function [label="call internal function\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:22:9-20"]
+	internal_function [label="function(uint256) internal returns (void)\nBase.set\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:22:9-20"]
+	number_literal_37 [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:22:18-19"]
+	contract_38 [label="contract C\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:25:1-36:2"]
+	base [label="base Base\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:26:15-19"]
+	c [label="function c\ncontract: C\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:27:5-24\nsignature c()\nvisibility public\nmutability nonpayable"]
+	if_41 [label="if\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:28:9-30:10"]
+	equal_42 [label="equal\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:28:13-26"]
+	constant_43 [label="constant variable\nBase.FOO\nuint256\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:28:13-21"]
+	number_literal_44 [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:28:25-26"]
+	expr_45 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:29:13-24"]
+	call_internal_function_46 [label="call internal function\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:29:13-24"]
+	internal_function_47 [label="function(uint256) internal returns (void)\nBase.set\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:29:13-24"]
+	number_literal_48 [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:29:22-23"]
+	set_49 [label="function set\ncontract: C\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:33:5-54\nsignature set(uint256)\nvisibility public\nmutability nonpayable\nvirtual\noverride"]
+	parameters_50 [label="parameters\nuint256 val"]
+	expr_51 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:9-31"]
+	assign_52 [label="assign\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:9-18"]
+	storage_var_53 [label="storage variable\nBase.something\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:9-18"]
+	add [label="add\nuint256\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:21-31"]
+	variable_55 [label="variable: val\nuint256\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:21-24"]
+	number_literal_56 [label="uint256 literal: 1024\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:34:27-31"]
+	diagnostic [label="found contract 'Base'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:1:1-10:2"]
+	diagnostic_59 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:11:1-18:2"]
+	diagnostic_60 [label="found contract 'B'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:19:1-24:2"]
+	diagnostic_61 [label="function calls via contract name are only valid for base contracts\nlevel Error\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:22:9-20"]
+	diagnostic_62 [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol:25:1-36:2"]
+	contracts -> contract
+	contract -> var [label="variable"]
+	var -> number_literal [label="initializer"]
+	contract -> var_4 [label="variable"]
+	var_4 -> number_literal_5 [label="initializer"]
+	contract -> FOO [label="function"]
+	FOO -> returns [label="returns"]
+	FOO -> return [label="body"]
+	return -> constant [label="expr"]
+	contract -> something [label="function"]
+	something -> returns_11 [label="returns"]
+	something -> return_12 [label="body"]
+	return_12 -> storage_load [label="expr"]
+	storage_load -> storage_var [label="expr"]
+	contract -> nop [label="function"]
+	contract -> set [label="function"]
+	set -> parameters [label="parameters"]
+	set -> expr [label="body"]
+	expr -> assign [label="expr"]
+	assign -> storage_var_20 [label="left"]
+	assign -> variable [label="right"]
+	contracts -> contract_22
+	contract_22 -> a [label="function"]
+	a -> if [label="body"]
+	if -> equal [label="cond"]
+	equal -> constant_26 [label="left"]
+	equal -> number_literal_27 [label="right"]
+	if -> expr_28 [label="then"]
+	expr_28 -> builtins [label="expr"]
+	builtins -> alloc_array [label="arg #0"]
+	alloc_array -> number_literal_31 [label="length"]
+	contracts -> contract_32
+	contract_32 -> b [label="function"]
+	b -> expr_34 [label="body"]
+	expr_34 -> call_internal_function [label="expr"]
+	call_internal_function -> internal_function [label="function"]
+	call_internal_function -> number_literal_37 [label="arg #0"]
+	contracts -> contract_38
+	contract_38 -> base [label="base"]
+	contract_38 -> c [label="function"]
+	c -> if_41 [label="body"]
+	if_41 -> equal_42 [label="cond"]
+	equal_42 -> constant_43 [label="left"]
+	equal_42 -> number_literal_44 [label="right"]
+	if_41 -> expr_45 [label="then"]
+	expr_45 -> call_internal_function_46 [label="expr"]
+	call_internal_function_46 -> internal_function_47 [label="function"]
+	call_internal_function_46 -> number_literal_48 [label="arg #0"]
+	contract_38 -> set_49 [label="function"]
+	set_49 -> parameters_50 [label="parameters"]
+	set_49 -> expr_51 [label="body"]
+	expr_51 -> assign_52 [label="expr"]
+	assign_52 -> storage_var_53 [label="left"]
+	assign_52 -> add [label="right"]
+	add -> variable_55 [label="left"]
+	add -> number_literal_56 [label="right"]
+	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_59 [label="Debug"]
+	diagnostics -> diagnostic_60 [label="Debug"]
+	diagnostics -> diagnostic_61 [label="Error"]
+	diagnostics -> diagnostic_62 [label="Debug"]
+}

+ 36 - 0
tests/contract_testcases/substrate/inheritance/base_contract_access_via_name.sol

@@ -0,0 +1,36 @@
+contract Base {
+    uint256 public constant FOO = 1;
+    uint256 public something = 0;
+
+    function nop() public pure {}
+
+    function set(uint256 val) public virtual {
+        something = val;
+    }
+}
+
+contract A {
+    function a() public {
+        if (Base.FOO == 1) {
+            print("hi");
+        }
+    }
+}
+
+contract B {
+    function b() public {
+        Base.set(1);
+    }
+}
+
+contract C is Base {
+    function c() public {
+        if (Base.FOO == 1) {
+            Base.set(1);
+        }
+    }
+
+    function set(uint256 val) public virtual override {
+        something = val + 1024;
+    }
+}

+ 52 - 0
tests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.dot

@@ -0,0 +1,52 @@
+strict digraph "tests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol" {
+	contract [label="contract Base\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:1:1-7:2"]
+	var [label="variable something\nvisibility private\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:2:5-30"]
+	set [label="function set\ncontract: Base\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:4:5-42\nsignature set(uint256)\nvisibility public\nmutability pure"]
+	parameters [label="parameters\nuint256 val"]
+	expr [label="expression\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:5:9-24"]
+	assign [label="assign\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:5:9-18"]
+	storage_var [label="storage variable\nBase.something\nuint256 storage\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:5:9-18"]
+	variable [label="variable: val\nuint256\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:5:21-24"]
+	contract_9 [label="contract A\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:8:1-13:2"]
+	a [label="function a\ncontract: A\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:10:5-29\nsignature a()\nvisibility public\nmutability pure"]
+	expr_11 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:11:9-27"]
+	call_internal_function [label="call internal function\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:11:9-27"]
+	internal_function [label="function(uint256) internal pure returns (void)\nBase.set\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:11:9-27"]
+	number_literal [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:11:24-25"]
+	contract_15 [label="contract B\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:14:1-19:2"]
+	base [label="base Base\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:15:15-19"]
+	b [label="function b\ncontract: B\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:16:5-29\nsignature b()\nvisibility public\nmutability pure"]
+	expr_18 [label="expression\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:17:9-27"]
+	call_internal_function_19 [label="call internal function\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:17:9-27"]
+	internal_function_20 [label="function(uint256) internal pure returns (void)\nBase.set\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:17:9-27"]
+	number_literal_21 [label="uint256 literal: 1\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:17:24-25"]
+	diagnostic [label="found contract 'Base'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:1:1-7:2"]
+	diagnostic_24 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:8:1-13:2"]
+	diagnostic_25 [label="function calls via contract name are only valid for base contracts\nlevel Error\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:11:9-27"]
+	diagnostic_26 [label="found contract 'B'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol:14:1-19:2"]
+	contracts -> contract
+	contract -> var [label="variable"]
+	contract -> set [label="function"]
+	set -> parameters [label="parameters"]
+	set -> expr [label="body"]
+	expr -> assign [label="expr"]
+	assign -> storage_var [label="left"]
+	assign -> variable [label="right"]
+	contracts -> contract_9
+	contract_9 -> a [label="function"]
+	a -> expr_11 [label="body"]
+	expr_11 -> call_internal_function [label="expr"]
+	call_internal_function -> internal_function [label="function"]
+	call_internal_function -> number_literal [label="arg #0"]
+	contracts -> contract_15
+	contract_15 -> base [label="base"]
+	contract_15 -> b [label="function"]
+	b -> expr_18 [label="body"]
+	expr_18 -> call_internal_function_19 [label="expr"]
+	call_internal_function_19 -> internal_function_20 [label="function"]
+	call_internal_function_19 -> number_literal_21 [label="arg #0"]
+	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_24 [label="Debug"]
+	diagnostics -> diagnostic_25 [label="Error"]
+	diagnostics -> diagnostic_26 [label="Debug"]
+}

+ 19 - 0
tests/contract_testcases/substrate/inheritance/base_contracts_access_named_args_via_name.sol

@@ -0,0 +1,19 @@
+contract Base {
+    uint256 private something;
+
+    function set(uint256 val) public pure {
+        something = val;
+    }
+}
+
+contract A {
+    function a() public pure {
+        Base.set({val: 1});
+    }
+}
+
+contract B is Base {
+    function b() public pure {
+        Base.set({val: 1});
+    }
+}