Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slither-flat: Improve utf8 support and mapping/array lookup #494

Merged
merged 1 commit into from
Jun 5, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions slither/tools/flattening/flattening.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from collections import namedtuple

from slither.core.declarations import SolidityFunction
from slither.core.solidity_types import MappingType, ArrayType
from slither.exceptions import SlitherException
from slither.core.solidity_types.user_defined_type import UserDefinedType
from slither.core.declarations.structure import Structure
Expand All @@ -20,6 +21,7 @@
# - line_removal: remove the line (remove-assert)
Patch = namedtuple('PatchExternal', ['index', 'patch_type'])


class Flattening:
DEFAULT_EXPORT_PATH = Path('crytic-export/flattening')

Expand All @@ -44,7 +46,7 @@ def _check_abi_encoder_v2(self):

def _get_source_code(self, contract):
src_mapping = contract.source_mapping
content = self._slither.source_code[src_mapping['filename_absolute']]
content = self._slither.source_code[src_mapping['filename_absolute']].encode('utf8')
start = src_mapping['start']
end = src_mapping['start'] + src_mapping['length']

Expand Down Expand Up @@ -112,17 +114,22 @@ def _get_source_code(self, contract):
assert patch_type == 'line_removal'
content = content[:index] + ' // ' + content[index:]

self._source_codes[contract] = content
self._source_codes[contract] = content.decode('utf8')

def _export_from_type(self, t, contract, exported, list_contract):
if isinstance(t, UserDefinedType):
if isinstance(t.type, (Enum, Structure)):
if t.type.contract != contract and not t.type.contract in exported:
if t.type.contract != contract and t.type.contract not in exported:
self._export_contract(t.type.contract, exported, list_contract)
else:
assert isinstance(t.type, Contract)
if t.type != contract and not t.type in exported:
if t.type != contract and t.type not in exported:
self._export_contract(t.type, exported, list_contract)
elif isinstance(t, MappingType):
self._export_from_type(t.type_from, contract, exported, list_contract)
self._export_from_type(t.type_to, contract, exported, list_contract)
elif isinstance(t, ArrayType):
self._export_from_type(t.type, contract, exported, list_contract)

def _export_contract(self, contract, exported, list_contract):
if contract.name in exported:
Expand All @@ -148,6 +155,10 @@ def _export_contract(self, contract, exported, list_contract):
for v in contract.variables + local_vars:
self._export_from_type(v.type, contract, exported, list_contract)

for s in contract.structures:
for elem in s.elems.values():
self._export_from_type(elem.type, contract, exported, list_contract)

# Find all convert and "new" operation that can lead to use an external contract
for f in contract.functions_declared:
for ir in f.slithir_operations:
Expand Down