Merge pull request #1604 from bart1e/missing_references_fix

Missing references fix
pull/1691/head
Feist Josselin 2 years ago committed by GitHub
commit 04a6b0f8d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      slither/solc_parsing/expressions/expression_parsing.py
  2. 7
      slither/solc_parsing/solidity_types/type_parsing.py
  3. 19
      tests/src_mapping/ReferencesUserDefinedAliases.sol
  4. 19
      tests/src_mapping/ReferencesUserDefinedTypesCasting.sol
  5. 50
      tests/test_source_mapping.py

@ -35,6 +35,7 @@ from slither.core.expressions import (
from slither.core.solidity_types import ( from slither.core.solidity_types import (
ArrayType, ArrayType,
ElementaryType, ElementaryType,
UserDefinedType,
) )
from slither.solc_parsing.declarations.caller_context import CallerContextExpression from slither.solc_parsing.declarations.caller_context import CallerContextExpression
from slither.solc_parsing.exceptions import ParsingError, VariableNotFound from slither.solc_parsing.exceptions import ParsingError, VariableNotFound
@ -112,7 +113,6 @@ def parse_call(expression: Dict, caller_context): # pylint: disable=too-many-st
if type_conversion: if type_conversion:
type_call = parse_type(UnknownType(type_return), caller_context) type_call = parse_type(UnknownType(type_return), caller_context)
if caller_context.is_compact_ast: if caller_context.is_compact_ast:
assert len(expression["arguments"]) == 1 assert len(expression["arguments"]) == 1
expression_to_parse = expression["arguments"][0] expression_to_parse = expression["arguments"][0]
@ -133,6 +133,8 @@ def parse_call(expression: Dict, caller_context): # pylint: disable=too-many-st
expression = parse_expression(expression_to_parse, caller_context) expression = parse_expression(expression_to_parse, caller_context)
t = TypeConversion(expression, type_call) t = TypeConversion(expression, type_call)
t.set_offset(src, caller_context.compilation_unit) t.set_offset(src, caller_context.compilation_unit)
if isinstance(type_call, UserDefinedType):
type_call.type.references.append(t.source_mapping)
return t return t
call_gas = None call_gas = None

@ -6,7 +6,7 @@ from slither.core.declarations.custom_error_contract import CustomErrorContract
from slither.core.declarations.custom_error_top_level import CustomErrorTopLevel from slither.core.declarations.custom_error_top_level import CustomErrorTopLevel
from slither.core.declarations.function_contract import FunctionContract from slither.core.declarations.function_contract import FunctionContract
from slither.core.expressions.literal import Literal from slither.core.expressions.literal import Literal
from slither.core.solidity_types import TypeAlias from slither.core.solidity_types import TypeAlias, TypeAliasTopLevel, TypeAliasContract
from slither.core.solidity_types.array_type import ArrayType from slither.core.solidity_types.array_type import ArrayType
from slither.core.solidity_types.elementary_type import ( from slither.core.solidity_types.elementary_type import (
ElementaryType, ElementaryType,
@ -199,6 +199,9 @@ def _add_type_references(type_found: Type, src: str, sl: "SlitherCompilationUnit
if isinstance(type_found, UserDefinedType): if isinstance(type_found, UserDefinedType):
type_found.type.add_reference_from_raw_source(src, sl) type_found.type.add_reference_from_raw_source(src, sl)
elif isinstance(type_found, (TypeAliasTopLevel, TypeAliasContract)):
type_found.type.add_reference_from_raw_source(src, sl)
type_found.add_reference_from_raw_source(src, sl)
# TODO: since the add of FileScope, we can probably refactor this function and makes it a lot simpler # TODO: since the add of FileScope, we can probably refactor this function and makes it a lot simpler
@ -362,6 +365,7 @@ def parse_type(
if name in renaming: if name in renaming:
name = renaming[name] name = renaming[name]
if name in user_defined_types: if name in user_defined_types:
_add_type_references(user_defined_types[name], t["src"], sl)
return user_defined_types[name] return user_defined_types[name]
type_found = _find_from_type_name( type_found = _find_from_type_name(
name, name,
@ -382,6 +386,7 @@ def parse_type(
if name in renaming: if name in renaming:
name = renaming[name] name = renaming[name]
if name in user_defined_types: if name in user_defined_types:
_add_type_references(user_defined_types[name], t["src"], sl)
return user_defined_types[name] return user_defined_types[name]
type_found = _find_from_type_name( type_found = _find_from_type_name(
name, name,

@ -0,0 +1,19 @@
pragma solidity 0.8.16;
type aliasTopLevel is uint;
contract C
{
type aliasContractLevel is uint;
}
contract Test
{
aliasTopLevel a;
C.aliasContractLevel b;
}
function f(aliasTopLevel, C.aliasContractLevel)
{
}

@ -0,0 +1,19 @@
pragma solidity 0.8.16;
interface A
{
function a() external;
}
contract C
{
function g(address _address) private
{
A(_address).a();
}
}
function f(address _address)
{
A(_address).a();
}

@ -81,3 +81,53 @@ def test_source_mapping():
(x.start, x.end) (x.start, x.end)
for x in slither.offset_to_implementations("tests/src_mapping/inheritance.sol", 93) for x in slither.offset_to_implementations("tests/src_mapping/inheritance.sol", 93)
} == {(17, 53), (193, 230), (129, 166)} } == {(17, 53), (193, 230), (129, 166)}
def _sort_references_lines(refs: list) -> list:
return sorted([ref.lines[0] for ref in refs])
def _test_references_user_defined_aliases():
"""
Tests if references are filled correctly for user defined aliases (declared using "type [...] is [...]" statement).
"""
solc_select.switch_global_version("0.8.16", always_install=True)
slither = Slither("tests/src_mapping/ReferencesUserDefinedAliases.sol")
alias_top_level = slither.compilation_units[0].user_defined_value_types["aliasTopLevel"]
assert len(alias_top_level.references) == 2
lines = _sort_references_lines(alias_top_level.references)
assert lines == [12, 16]
alias_contract_level = (
slither.compilation_units[0]
.contracts[0]
.file_scope.user_defined_types["C.aliasContractLevel"]
)
assert len(alias_contract_level.references) == 2
lines = _sort_references_lines(alias_contract_level.references)
assert lines == [13, 16]
def _test_references_user_defined_types_when_casting():
"""
Tests if references are filled correctly for user defined types in case of casting.
"""
solc_select.switch_global_version("0.8.16", always_install=True)
slither = Slither("tests/src_mapping/ReferencesUserDefinedTypesCasting.sol")
contracts = slither.compilation_units[0].contracts
a = contracts[0] if contracts[0].is_interface else contracts[1]
assert len(a.references) == 2
lines = _sort_references_lines(a.references)
assert lines == [12, 18]
def test_references():
"""
Tests if references list is filled correctly in the following cases:
- user defined aliases (declared using "type [...] is [...]" statement)
- user defined types in case of casting (TypeConversion expressions)
"""
_test_references_user_defined_aliases()
_test_references_user_defined_types_when_casting()

Loading…
Cancel
Save