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

fix declaration and evm printer #1765

Merged
merged 4 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
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
13 changes: 11 additions & 2 deletions scripts/ci_test_printers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
cd tests/ast-parsing/compile || exit

# Do not test the evm printer,as it needs a refactoring
ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,human-summary,inheritance,inheritance-graph,slithir,slithir-ssa,vars-and-auth,require,variable-order"
ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,human-summary,inheritance,inheritance-graph,slithir,slithir-ssa,vars-and-auth,require,variable-order,declaration"

# Only test 0.5.17 to limit test time
for file in *0.5.17-compact.zip; do
if ! slither "$file" --print "$ALL_PRINTERS" > /dev/null 2>&1 ; then
if ! slither "$file" --print "$ALL_PRINTERS" ; then
echo "Printer failed"
echo "$file"
exit 1
fi
done

# Only test 0.8.12 to limit test time
for file in *0.8.12-compact.zip; do
if ! slither "$file" --print "declaration" ; then
echo "Printer failed"
echo "$file"
exit 1
Expand Down
31 changes: 11 additions & 20 deletions slither/core/source_mapping/source_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

# pylint: disable=too-many-instance-attributes
class Source:
def __init__(self) -> None:
def __init__(self, compilation_unit: "SlitherCompilationUnit") -> None:
self.start: int = 0
self.length: int = 0
self.filename: Filename = Filename("", "", "", "")
Expand All @@ -27,7 +27,7 @@ def __init__(self) -> None:
self.starting_column: int = 0
self.ending_column: int = 0
self.end: int = 0
self.compilation_unit: Optional["SlitherCompilationUnit"] = None
self.compilation_unit = compilation_unit

def to_json(self) -> Dict:
return {
Expand All @@ -51,17 +51,13 @@ def to_markdown(self, markdown_root: str) -> str:
filename_relative: str = self.filename.relative if self.filename.relative else ""
return f"{markdown_root}{filename_relative}{lines}"

def to_detailled_str(self) -> str:
def to_detailed_str(self) -> str:
lines = self._get_lines_str()
filename_short: str = self.filename.short if self.filename.short else ""
return f"{filename_short}{lines} ({self.starting_column} - {self.ending_column})"

def _get_lines_str(self, line_descr: str = "") -> str:

# If the compilation unit was not initialized, it means that the set_offset was never called
# on the corresponding object, which should not happen
assert self.compilation_unit is not None

line_prefix = self.compilation_unit.core.line_prefix

lines = self.lines
Expand Down Expand Up @@ -129,6 +125,7 @@ def _compute_line(

Not done in an efficient way
"""

start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start
)
Expand All @@ -151,15 +148,15 @@ def _convert_source_mapping(

position = re.findall("([0-9]*):([0-9]*):([-]?[0-9]*)", offset)
if len(position) != 1:
return Source()
return Source(compilation_unit)

s, l, f = position[0]
s = int(s)
l = int(l)
f = int(f)

if f not in sourceUnits:
new_source = Source()
new_source = Source(compilation_unit)
new_source.start = s
new_source.length = l
return new_source
Expand All @@ -173,7 +170,7 @@ def _convert_source_mapping(

(lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l)

new_source = Source()
new_source = Source(compilation_unit)
new_source.start = s
new_source.length = l
new_source.filename = filename
Expand All @@ -182,28 +179,22 @@ def _convert_source_mapping(
new_source.starting_column = starting_column
new_source.ending_column = ending_column
new_source.end = new_source.start + l

return new_source


class SourceMapping(Context, metaclass=ABCMeta):
def __init__(self) -> None:
super().__init__()
# self._source_mapping: Optional[Dict] = None
self.source_mapping: Source = Source()
self.source_mapping: Optional[Source] = None
self.references: List[Source] = []

def set_offset(
self, offset: Union["Source", str], compilation_unit: "SlitherCompilationUnit"
) -> None:
assert compilation_unit
if isinstance(offset, Source):
self.source_mapping.start = offset.start
self.source_mapping.length = offset.length
self.source_mapping.filename = offset.filename
self.source_mapping.is_dependency = offset.is_dependency
self.source_mapping.lines = offset.lines
self.source_mapping.starting_column = offset.starting_column
self.source_mapping.ending_column = offset.ending_column
self.source_mapping.end = offset.end
self.source_mapping = offset
else:
self.source_mapping = _convert_source_mapping(offset, compilation_unit)
self.source_mapping.compilation_unit = compilation_unit
Expand Down
28 changes: 14 additions & 14 deletions slither/printers/summary/declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,37 @@ def output(self, _filename):
txt += "\n# Contracts\n"
for contract in compilation_unit.contracts:
txt += f"# {contract.name}\n"
txt += f"\t- Declaration: {get_definition(contract, compilation_unit.core.crytic_compile).to_detailled_str()}\n"
txt += f"\t- Implementation: {get_implementation(contract).to_detailled_str()}\n"
txt += f"\t- Declaration: {get_definition(contract, compilation_unit.core.crytic_compile).to_detailed_str()}\n"
txt += f"\t- Implementation: {get_implementation(contract).to_detailed_str()}\n"
txt += (
f"\t- References: {[x.to_detailled_str() for x in get_references(contract)]}\n"
f"\t- References: {[x.to_detailed_str() for x in get_references(contract)]}\n"
)

txt += "\n\t## Function\n"

for func in contract.functions:
txt += f"\t\t- {func.canonical_name}\n"
txt += f"\t\t\t- Declaration: {get_definition(func, compilation_unit.core.crytic_compile).to_detailled_str()}\n"
txt += (
f"\t\t\t- Implementation: {get_implementation(func).to_detailled_str()}\n"
)
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(func)]}\n"
txt += f"\t\t\t- Declaration: {get_definition(func, compilation_unit.core.crytic_compile).to_detailed_str()}\n"
txt += f"\t\t\t- Implementation: {get_implementation(func).to_detailed_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(func)]}\n"

txt += "\n\t## State variables\n"

for var in contract.state_variables:
txt += f"\t\t- {var.name}\n"
txt += f"\t\t\t- Declaration: {get_definition(var, compilation_unit.core.crytic_compile).to_detailled_str()}\n"
txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailled_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(var)]}\n"
txt += f"\t\t\t- Declaration: {get_definition(var, compilation_unit.core.crytic_compile).to_detailed_str()}\n"
txt += f"\t\t\t- Implementation: {get_implementation(var).to_detailed_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(var)]}\n"

txt += "\n\t## Structures\n"

for st in contract.structures:
txt += f"\t\t- {st.name}\n"
txt += f"\t\t\t- Declaration: {get_definition(st, compilation_unit.core.crytic_compile).to_detailled_str()}\n"
txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailled_str()}\n"
txt += f"\t\t\t- References: {[x.to_detailled_str() for x in get_references(st)]}\n"
txt += f"\t\t\t- Declaration: {get_definition(st, compilation_unit.core.crytic_compile).txt}\n"
txt += f"\t\t\t- Implementation: {get_implementation(st).to_detailed_str()}\n"
txt += (
f"\t\t\t- References: {[x.to_detailed_str() for x in get_references(st)]}\n"
)

self.info(txt)
res = self.generate_output(txt)
Expand Down
16 changes: 12 additions & 4 deletions slither/printers/summary/evm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ def _extract_evm_info(slither):
CFG = load_evm_cfg_builder()

for contract in slither.contracts_derived:
contract_bytecode_runtime = contract.scope.bytecode_runtime(contract.name)
contract_srcmap_runtime = contract.scope.srcmap_runtime(contract.name)
contract_bytecode_runtime = contract.file_scope.bytecode_runtime(
contract.compilation_unit.crytic_compile_compilation_unit, contract.name
)
contract_srcmap_runtime = contract.file_scope.srcmap_runtime(
contract.compilation_unit.crytic_compile_compilation_unit, contract.name
)
cfg = CFG(contract_bytecode_runtime)
evm_info["cfg", contract.name] = cfg
evm_info["mapping", contract.name] = generate_source_to_evm_ins_mapping(
Expand All @@ -32,8 +36,12 @@ def _extract_evm_info(slither):
contract.source_mapping.filename.absolute,
)

contract_bytecode_init = contract.scope.bytecode_init(contract.name)
contract_srcmap_init = contract.scope.srcmap_init(contract.name)
contract_bytecode_init = contract.file_scope.bytecode_init(
contract.compilation_unit.crytic_compile_compilation_unit, contract.name
)
contract_srcmap_init = contract.file_scope.srcmap_init(
contract.compilation_unit.crytic_compile_compilation_unit, contract.name
)
cfg_init = CFG(contract_bytecode_init)

evm_info["cfg_init", contract.name] = cfg_init
Expand Down
5 changes: 2 additions & 3 deletions slither/utils/source_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Sour
target.source_mapping.filename, target.source_mapping.start + start_offset + len(pattern)
)

s = Source()
s = Source(target.source_mapping.compilation_unit)
s.start = target.source_mapping.start + start_offset
s.length = len(pattern)
s.filename = target.source_mapping.filename
Expand All @@ -44,8 +44,7 @@ def get_definition(target: SourceMapping, crytic_compile: CryticCompile) -> Sour
s.starting_column = starting_column
s.ending_column = ending_column
s.end = s.start + s.length
s.compilation_unit = target.compilation_unit

s.txt = txt
return s


Expand Down