From c47fa62b712af745cecbb0f20329d567c24affff Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 28 Jul 2023 17:36:04 -0500 Subject: [PATCH 1/8] ci: add problem matchers for yamllint and pylint --- .github/workflows/linter.yml | 7 +++--- .github/workflows/matchers/pylint.json | 32 ++++++++++++++++++++++++ .github/workflows/matchers/yamllint.json | 22 ++++++++++++++++ .github/workflows/pylint.yml | 6 +++++ 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/matchers/pylint.json create mode 100644 .github/workflows/matchers/yamllint.json diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index b352a8301..0468b07f8 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -9,8 +9,6 @@ defaults: on: pull_request: branches: [master, dev] - paths: - - "**/*.py" schedule: # run CI every day even if no PRs/merges occur @@ -42,6 +40,10 @@ jobs: mkdir -p .github/linters cp pyproject.toml .github/linters + - name: Register yamllint problem matcher + run: | + echo "::add-matcher::.github/workflows/matchers/yamllint.json" + - name: Lint everything else uses: super-linter/super-linter/slim@v4.9.2 if: always() @@ -55,7 +57,6 @@ jobs: VALIDATE_PYTHON_PYLINT: false VALIDATE_PYTHON_BLACK: false VALIDATE_PYTHON_ISORT: false - # Always false VALIDATE_JSON: false VALIDATE_JAVASCRIPT_STANDARD: false VALIDATE_PYTHON_FLAKE8: false diff --git a/.github/workflows/matchers/pylint.json b/.github/workflows/matchers/pylint.json new file mode 100644 index 000000000..4d9e13fca --- /dev/null +++ b/.github/workflows/matchers/pylint.json @@ -0,0 +1,32 @@ +{ + "problemMatcher": [ + { + "owner": "pylint-error", + "severity": "error", + "pattern": [ + { + "regexp": "^(.+):(\\d+):(\\d+):\\s(([EF]\\d{4}):\\s.+)$", + "file": 1, + "line": 2, + "column": 3, + "message": 4, + "code": 5 + } + ] + }, + { + "owner": "pylint-warning", + "severity": "warning", + "pattern": [ + { + "regexp": "^(.+):(\\d+):(\\d+):\\s(([CRW]\\d{4}):\\s.+)$", + "file": 1, + "line": 2, + "column": 3, + "message": 4, + "code": 5 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/workflows/matchers/yamllint.json b/.github/workflows/matchers/yamllint.json new file mode 100644 index 000000000..b0b2f125c --- /dev/null +++ b/.github/workflows/matchers/yamllint.json @@ -0,0 +1,22 @@ +{ + "problemMatcher": [ + { + "owner": "yamllint", + "pattern": [ + { + "regexp": "^(.*\\.ya?ml)$", + "file": 1 + }, + { + "regexp": "^\\s{2}(\\d+):(\\d+)\\s+(error|warning)\\s+(.*?)\\s+\\((.*)\\)$", + "line": 1, + "column": 2, + "severity": 3, + "message": 4, + "code": 5, + "loop": true + } + ] + } + ] + } \ No newline at end of file diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 207f98eac..8c7e7bce9 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -9,6 +9,8 @@ defaults: on: pull_request: branches: [master, dev] + paths: + - "**/*.py" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -36,6 +38,10 @@ jobs: mkdir -p .github/linters cp pyproject.toml .github/linters + - name: Register pylint problem matcher + run: | + echo "::add-matcher::.github/workflows/matchers/pylint.json" + - name: Pylint uses: super-linter/super-linter/slim@v4.9.2 if: always() From d90505826f952526f5daccd107b4100ed44ab2cb Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 3 Aug 2023 16:51:49 -0500 Subject: [PATCH 2/8] fix ternary rewrite test and make assertion more strict (#2067) --- .../unit/slithir/test_ternary_expressions.py | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/tests/unit/slithir/test_ternary_expressions.py b/tests/unit/slithir/test_ternary_expressions.py index 0acd9345d..712c9582b 100644 --- a/tests/unit/slithir/test_ternary_expressions.py +++ b/tests/unit/slithir/test_ternary_expressions.py @@ -1,8 +1,13 @@ from pathlib import Path from slither import Slither from slither.core.cfg.node import NodeType -from slither.slithir.operations import Assignment -from slither.core.expressions import AssignmentOperation, TupleExpression +from slither.slithir.operations import Assignment, Unpack +from slither.core.expressions import ( + AssignmentOperation, + TupleExpression, + NewElementaryType, + CallExpression, +) TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" @@ -12,27 +17,29 @@ def test_ternary_conversions(solc_binary_path) -> None: solc_path = solc_binary_path("0.8.0") slither = Slither(Path(TEST_DATA_DIR, "ternary_expressions.sol").as_posix(), solc=solc_path) for contract in slither.contracts: - for function in contract.functions: - vars_declared = 0 - vars_assigned = 0 - for node in function.nodes: - if node.type in [NodeType.IF, NodeType.IFLOOP]: + if not contract.is_signature_only: + for function in contract.functions: + vars_declared = 0 + vars_assigned = 0 + for node in function.nodes: + if node.type in [NodeType.IF, NodeType.IFLOOP]: - # Iterate over true and false son - for inner_node in node.sons: - # Count all variables declared - expression = inner_node.expression - if isinstance(expression, AssignmentOperation): - var_expr = expression.expression_left - # Only tuples declare more than one var - if isinstance(var_expr, TupleExpression): - vars_declared += len(var_expr.expressions) - else: - vars_declared += 1 + # Iterate over true and false son + for inner_node in node.sons: + # Count all variables declared + expression = inner_node.expression + if isinstance( + expression, (AssignmentOperation, NewElementaryType, CallExpression) + ): + var_expr = expression.expression_left + # Only tuples declare more than one var + if isinstance(var_expr, TupleExpression): + vars_declared += len(var_expr.expressions) + else: + vars_declared += 1 - for ir in inner_node.irs: - # Count all variables defined - if isinstance(ir, Assignment): - vars_assigned += 1 - - assert vars_declared == vars_assigned + for ir in inner_node.irs: + # Count all variables defined + if isinstance(ir, (Assignment, Unpack)): + vars_assigned += 1 + assert vars_declared == vars_assigned and vars_assigned != 0 From e0098907c998fede544525f859f917074a752e63 Mon Sep 17 00:00:00 2001 From: Simone <79767264+smonicas@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:53:09 +0200 Subject: [PATCH 3/8] Add CustomError as printable output (#2063) --- slither/core/declarations/__init__.py | 2 ++ .../declarations/custom_error_contract.py | 4 +++ .../declarations/custom_error_top_level.py | 4 +++ slither/utils/output.py | 29 +++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/slither/core/declarations/__init__.py b/slither/core/declarations/__init__.py index 92e0b9eca..f34118751 100644 --- a/slither/core/declarations/__init__.py +++ b/slither/core/declarations/__init__.py @@ -18,3 +18,5 @@ from .structure_top_level import StructureTopLevel from .function_contract import FunctionContract from .function_top_level import FunctionTopLevel from .custom_error_contract import CustomErrorContract +from .custom_error_top_level import CustomErrorTopLevel +from .custom_error import CustomError diff --git a/slither/core/declarations/custom_error_contract.py b/slither/core/declarations/custom_error_contract.py index cd279a3a6..2c8bec9ef 100644 --- a/slither/core/declarations/custom_error_contract.py +++ b/slither/core/declarations/custom_error_contract.py @@ -16,3 +16,7 @@ class CustomErrorContract(CustomError, ContractLevel): :return: """ return self.contract == contract + + @property + def canonical_name(self) -> str: + return self.contract.name + "." + self.full_name diff --git a/slither/core/declarations/custom_error_top_level.py b/slither/core/declarations/custom_error_top_level.py index 64a6a8535..b80356b24 100644 --- a/slither/core/declarations/custom_error_top_level.py +++ b/slither/core/declarations/custom_error_top_level.py @@ -12,3 +12,7 @@ class CustomErrorTopLevel(CustomError, TopLevel): def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope") -> None: super().__init__(compilation_unit) self.file_scope: "FileScope" = scope + + @property + def canonical_name(self) -> str: + return self.full_name diff --git a/slither/utils/output.py b/slither/utils/output.py index 84c9ac65a..4a91ca9b9 100644 --- a/slither/utils/output.py +++ b/slither/utils/output.py @@ -18,6 +18,7 @@ from slither.core.declarations import ( Structure, Pragma, FunctionContract, + CustomError, ) from slither.core.source_mapping.source_mapping import SourceMapping from slither.core.variables.local_variable import LocalVariable @@ -438,6 +439,8 @@ class Output: self.add_event(add, additional_fields=additional_fields) elif isinstance(add, Structure): self.add_struct(add, additional_fields=additional_fields) + elif isinstance(add, CustomError): + self.add_custom_error(add, additional_fields=additional_fields) elif isinstance(add, Pragma): self.add_pragma(add, additional_fields=additional_fields) elif isinstance(add, Node): @@ -585,6 +588,32 @@ class Output: self._data["elements"].append(element) + # endregion + ################################################################################### + ################################################################################### + # region CustomError + ################################################################################### + ################################################################################### + + def add_custom_error( + self, custom_error: CustomError, additional_fields: Optional[Dict] = None + ) -> None: + if additional_fields is None: + additional_fields = {} + type_specific_fields = { + "parent": _create_parent_element(custom_error), + "signature": custom_error.full_name, + } + element = _create_base_element( + "custom_error", + custom_error.name, + custom_error.source_mapping.to_json(), + type_specific_fields, + additional_fields, + ) + + self._data["elements"].append(element) + # endregion ################################################################################### ################################################################################### From d86bd4109d69f7e99ea84e716f7d41d9ac29b1ea Mon Sep 17 00:00:00 2001 From: SheldonHolmgren <116484297+SheldonHolmgren@users.noreply.github.com> Date: Thu, 3 Aug 2023 22:54:15 +0100 Subject: [PATCH 4/8] UnaryOperation: -variable and +variable doesn't make variable an lvalue (#2027) --- slither/core/expressions/unary_operation.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/slither/core/expressions/unary_operation.py b/slither/core/expressions/unary_operation.py index 657224927..405132613 100644 --- a/slither/core/expressions/unary_operation.py +++ b/slither/core/expressions/unary_operation.py @@ -106,8 +106,6 @@ class UnaryOperation(Expression): UnaryOperationType.MINUSMINUS_PRE, UnaryOperationType.PLUSPLUS_POST, UnaryOperationType.MINUSMINUS_POST, - UnaryOperationType.PLUS_PRE, - UnaryOperationType.MINUS_PRE, ]: expression.set_lvalue() From 3f90e86badfa956b5cc692e0421c2b8065c31d43 Mon Sep 17 00:00:00 2001 From: yisun92 Date: Thu, 3 Aug 2023 17:56:04 -0400 Subject: [PATCH 5/8] fix: get_state_variable_from_canonical_name() filter by canonical_name (#1983) --- slither/core/declarations/contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index fd2cdd468..9b1488db3 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -861,7 +861,7 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods Returns: StateVariable """ - return next((v for v in self.state_variables if v.name == canonical_name), None) + return next((v for v in self.state_variables if v.canonical_name == canonical_name), None) def get_structure_from_name(self, structure_name: str) -> Optional["StructureContract"]: """ From 4b0482014dbf911f886a5f1221260ccb71a7cd22 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 8 Aug 2023 10:01:12 -0500 Subject: [PATCH 6/8] chore: bump sigstore to 2.0.0 (#2081) --- .github/workflows/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 24f04ee87..977a92ab2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,8 +47,7 @@ jobs: uses: pypa/gh-action-pypi-publish@v1.8.8 - name: sign - uses: sigstore/gh-action-sigstore-python@v1.2.3 + uses: sigstore/gh-action-sigstore-python@v2.0.0 with: inputs: ./dist/*.tar.gz ./dist/*.whl release-signing-artifacts: true - bundle-only: true From 2bc6a0f1a4349e2cb6a45bf7a078f65e050d7e28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 22:22:08 +0000 Subject: [PATCH 7/8] Bump pypa/gh-action-pypi-publish from 1.8.8 to 1.8.10 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.8 to 1.8.10. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.8...v1.8.10) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 977a92ab2..ed11178e3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,7 +44,7 @@ jobs: path: dist/ - name: publish - uses: pypa/gh-action-pypi-publish@v1.8.8 + uses: pypa/gh-action-pypi-publish@v1.8.10 - name: sign uses: sigstore/gh-action-sigstore-python@v2.0.0 From 81c0c8cd88a437f39fa6aece06470f7e8c1b1a31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 22:22:13 +0000 Subject: [PATCH 8/8] Bump sigstore/gh-action-sigstore-python from 2.0.0 to 2.0.1 Bumps [sigstore/gh-action-sigstore-python](https://github.com/sigstore/gh-action-sigstore-python) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/sigstore/gh-action-sigstore-python/releases) - [Commits](https://github.com/sigstore/gh-action-sigstore-python/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: sigstore/gh-action-sigstore-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 977a92ab2..cd6feacce 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,7 +47,7 @@ jobs: uses: pypa/gh-action-pypi-publish@v1.8.8 - name: sign - uses: sigstore/gh-action-sigstore-python@v2.0.0 + uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: ./dist/*.tar.gz ./dist/*.whl release-signing-artifacts: true