From 22b9cfc39cf96d9188eeca1c72bf122630056d80 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 17 May 2024 15:33:39 -0500 Subject: [PATCH] fix: use contract declarer's scope for name resolution --- .../solc_parsing/expressions/find_variable.py | 2 +- .../scope_with_renaming/core/MainContract.sol | 41 +++++++++++++++++++ .../core/ParentContract.sol | 30 ++++++++++++++ .../scope_with_renaming/errors/MainErrors.sol | 9 ++++ .../errors/ParentContractErrors.sol | 7 ++++ tests/unit/core/test_scope_with_renaming.py | 17 ++++++++ tests/unit/core/test_using_for.py | 2 +- 7 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 tests/unit/core/test_data/scope_with_renaming/core/MainContract.sol create mode 100644 tests/unit/core/test_data/scope_with_renaming/core/ParentContract.sol create mode 100644 tests/unit/core/test_data/scope_with_renaming/errors/MainErrors.sol create mode 100644 tests/unit/core/test_data/scope_with_renaming/errors/ParentContractErrors.sol create mode 100644 tests/unit/core/test_scope_with_renaming.py diff --git a/slither/solc_parsing/expressions/find_variable.py b/slither/solc_parsing/expressions/find_variable.py index 2d8fa58f6..4ea1239e5 100644 --- a/slither/solc_parsing/expressions/find_variable.py +++ b/slither/solc_parsing/expressions/find_variable.py @@ -304,7 +304,7 @@ def _find_variable_init( scope = underlying_function.file_scope else: assert isinstance(underlying_function, FunctionContract) - scope = underlying_function.contract.file_scope + scope = underlying_function.contract_declarer.file_scope elif isinstance(caller_context, StructureTopLevelSolc): direct_contracts = [] diff --git a/tests/unit/core/test_data/scope_with_renaming/core/MainContract.sol b/tests/unit/core/test_data/scope_with_renaming/core/MainContract.sol new file mode 100644 index 000000000..5eb92aa2f --- /dev/null +++ b/tests/unit/core/test_data/scope_with_renaming/core/MainContract.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import { + ParentContract +} from "./ParentContract.sol"; + +import { + MainErrors as Errors +} from "./../errors/MainErrors.sol"; + + +contract MainContract is ParentContract { + + + function functionWithMainError1(uint256 a, uint256 b) external pure returns (uint256) { + if (a == b) { + revert Errors.MainError1(); + } + // Add some arithmetic operations here + return a + b; + } + + function functionWithMainError2(uint256 a, uint256 b) external pure returns (uint256) { + if (a < b) { + revert Errors.MainError2(); + } + // Add some arithmetic operations here + return a - b; + } + + function functionWithMainError3(uint256 a, uint256 b) external pure returns (uint256) { + if (b == 0) { + revert Errors.MainError3(); + } + // Add some arithmetic operations here + return a * b; + } + + +} diff --git a/tests/unit/core/test_data/scope_with_renaming/core/ParentContract.sol b/tests/unit/core/test_data/scope_with_renaming/core/ParentContract.sol new file mode 100644 index 000000000..9ca32a1a6 --- /dev/null +++ b/tests/unit/core/test_data/scope_with_renaming/core/ParentContract.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + + +import { + AccessControlErrors as Errors +} from "../errors/ParentContractErrors.sol"; + + +contract ParentContract { + + + function functionWithAccessControlErrors1(uint256 a, uint256 b) external pure returns (uint256) { + if (a == b) { + revert Errors.AccessControlErrors1(); + } + // Add some arithmetic operations here + return a + b; + } + + function functionWithAccessControlErrors2(uint256 a, uint256 b) external pure returns (uint256) { + if (a < b) { + revert Errors.AccessControlErrors2(); + } + // Add some arithmetic operations here + return a - b; + } + + +} diff --git a/tests/unit/core/test_data/scope_with_renaming/errors/MainErrors.sol b/tests/unit/core/test_data/scope_with_renaming/errors/MainErrors.sol new file mode 100644 index 000000000..e7db5c5c3 --- /dev/null +++ b/tests/unit/core/test_data/scope_with_renaming/errors/MainErrors.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +// TODO: remove unused errors +library MainErrors { + error MainError1(); + error MainError2(); + error MainError3(); +} diff --git a/tests/unit/core/test_data/scope_with_renaming/errors/ParentContractErrors.sol b/tests/unit/core/test_data/scope_with_renaming/errors/ParentContractErrors.sol new file mode 100644 index 000000000..38ce16bdd --- /dev/null +++ b/tests/unit/core/test_data/scope_with_renaming/errors/ParentContractErrors.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +library AccessControlErrors { + error AccessControlErrors1(); + error AccessControlErrors2(); +} diff --git a/tests/unit/core/test_scope_with_renaming.py b/tests/unit/core/test_scope_with_renaming.py new file mode 100644 index 000000000..6984cfaa4 --- /dev/null +++ b/tests/unit/core/test_scope_with_renaming.py @@ -0,0 +1,17 @@ +from pathlib import Path +from crytic_compile import CryticCompile +from crytic_compile.platform.solc_standard_json import SolcStandardJson + +from slither import Slither + +TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" +SCOPE_RENAMING_TEST_DATA_DIR = Path(TEST_DATA_DIR, "scope_with_renaming") + +# https://github.com/crytic/slither/issues/2454 +def test_find_variable_scope_with_renaming(solc_binary_path) -> None: + solc_path = solc_binary_path("0.8.24") + standard_json = SolcStandardJson() + for source_file in SCOPE_RENAMING_TEST_DATA_DIR.rglob("**/*.sol"): + standard_json.add_source_file(Path(source_file).as_posix()) + compilation = CryticCompile(standard_json, solc=solc_path) + Slither(compilation, disallow_partial=True) diff --git a/tests/unit/core/test_using_for.py b/tests/unit/core/test_using_for.py index 4d7634c5c..656fc3a35 100644 --- a/tests/unit/core/test_using_for.py +++ b/tests/unit/core/test_using_for.py @@ -17,7 +17,7 @@ def test_using_for_global_collision(solc_binary_path) -> None: for source_file in Path(USING_FOR_TEST_DATA_DIR, "using_for_global_collision").rglob("*.sol"): standard_json.add_source_file(Path(source_file).as_posix()) compilation = CryticCompile(standard_json, solc=solc_path) - sl = Slither(compilation) + sl = Slither(compilation, disallow_partial=True) _run_all_detectors(sl)