Merge branch 'develop' of github.com:ConsenSys/mythril-classic into dependence

pull/1029/head
Bernhard Mueller 6 years ago
commit c8aad25921
  1. 2
      mythril/ethereum/util.py
  2. 54
      mythril/solidity/soliditycontract.py

@ -33,7 +33,7 @@ def get_solc_json(file, solc_binary="solc", solc_args=None):
:return:
"""
cmd = [solc_binary, "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime"]
cmd = [solc_binary, "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,ast"]
if solc_args:
cmd.extend(solc_args.split())

@ -1,5 +1,7 @@
"""This module contains representation classes for Solidity files, contracts
and source mappings."""
from typing import Dict, Set
import mythril.laser.ethereum.util as helper
from mythril.ethereum.evmcontract import EVMContract
from mythril.ethereum.util import get_solc_json
@ -20,9 +22,16 @@ class SourceMapping:
class SolidityFile:
"""Representation of a file containing Solidity code."""
def __init__(self, filename, data):
def __init__(self, filename: str, data: str, full_contract_source: Set[str]):
"""
Metadata class containing data regarding a specific solidity file
:param filename: The filename of the solidity file
:param data: The code of the solidity file
:param full_contract_source: The set of contract source mappings of all the contracts in the file
"""
self.filename = filename
self.data = data
self.full_contract_source = full_contract_source
class SourceCodeInfo:
@ -69,7 +78,12 @@ class SolidityContract(EVMContract):
for filename in data["sourceList"]:
with open(filename, "r", encoding="utf-8") as file:
code = file.read()
self.solidity_files.append(SolidityFile(filename, code))
full_contract_sources = self.get_full_contract_sources(
data["sources"][filename]["AST"]
)
self.solidity_files.append(
SolidityFile(filename, code, full_contract_sources)
)
has_contract = False
@ -117,6 +131,19 @@ class SolidityContract(EVMContract):
super().__init__(code, creation_code, name=name)
@staticmethod
def get_full_contract_sources(ast: Dict) -> Set[str]:
"""
Takes a solc AST and gets the src mappings for all the contracts defined in the top level of the ast
:param ast: AST of the contract
:return: The source map
"""
source_map = set()
for child in ast["children"]:
if "contractKind" in child["attributes"]:
source_map.add(child["src"])
return source_map
def get_source_info(self, address, constructor=False):
"""
@ -140,6 +167,26 @@ class SolidityContract(EVMContract):
lineno = mappings[index].lineno
return SourceCodeInfo(filename, lineno, code, mappings[index].solc_mapping)
def _is_autogenerated_code(self, offset: int, length: int, file_index: int) -> bool:
"""
Checks whether the code is autogenerated or not
:param offset: offset of the code
:param length: length of the code
:param file_index: file the code corresponds to
:return: True if the code is internally generated, else false
"""
# Handle internal compiler files
if file_index == -1:
return True
# Handle the common code src map for the entire code.
if (
"{}:{}:{}".format(offset, length, file_index)
in self.solidity_files[file_index].full_contract_source
):
return True
return False
def _get_solc_mappings(self, srcmap, constructor=False):
"""
@ -161,7 +208,8 @@ class SolidityContract(EVMContract):
if len(mapping) > 2 and len(mapping[2]) > 0:
idx = int(mapping[2])
if idx == -1:
if self._is_autogenerated_code(offset, length, idx):
lineno = None
else:
lineno = (

Loading…
Cancel
Save