diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 5ad15590..f14c9631 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -1,14 +1,15 @@ import hashlib import json +from jinja2 import PackageLoader, Environment class Issue: - def __init__(self, contract, function, pc, title, _type="Informational", description="", debug=""): + def __init__(self, contract, function, address, title, _type="Informational", description="", debug=""): self.title = title self.contract = contract self.function = function - self.pc = pc + self.address = address self.description = description self.type = _type self.debug = debug @@ -18,7 +19,7 @@ class Issue: def as_dict(self): - issue = {'title': self.title, 'description':self.description, 'function': self.function, 'type': self.type, 'address': self.pc, 'debug': self.debug} + issue = {'title': self.title, 'description':self.description, 'function': self.function, 'type': self.type, 'address': self.address, 'debug': self.debug} if self.filename and self.lineno: issue['filename'] = self.filename @@ -30,13 +31,14 @@ class Issue: return issue def add_code_info(self, contract): - if self.pc: - codeinfo = contract.get_source_info(self.pc) + if self.address: + codeinfo = contract.get_source_info(self.address) self.filename = codeinfo.filename self.code = codeinfo.code self.lineno = codeinfo.lineno class Report: + environment = Environment(loader=PackageLoader('mythril.analysis')) def __init__(self, verbose=False): self.issues = {} @@ -45,44 +47,16 @@ class Report: def append_issue(self, issue): m = hashlib.md5() - m.update((issue.contract + str(issue.pc) + issue.title).encode('utf-8')) + m.update((issue.contract + str(issue.address) + issue.title).encode('utf-8')) self.issues[m.digest()] = issue def as_text(self): - text = "" - - for key, issue in self.issues.items(): - - text += "==== " + issue.title + " ====\n" - text += "Type: " + issue.type + "\n" - - if len(issue.contract): - text += "Contract: " + issue.contract + "\n" - else: - text += "Contract: Unknown\n" - - text += "Function name: " + issue.function + "\n" - text += "PC address: " + str(issue.pc) + "\n" - - text += issue.description + "\n--------------------\n" - - if issue.filename and issue.lineno: - text += "In file: " + issue.filename + ":" + str(issue.lineno) - - if issue.code: - text += "\n\n" + issue.code + "\n\n--------------------\n" - - if self.verbose and issue.debug: - text += "\nDEBUGGING INFORMATION:\n\n" + issue.debug + "\n--------------------\n" - - text += "\n" - - return text + filename = list(self.issues.values())[0].filename + template = Report.environment.get_template('report_as_text.jinja2') + return template.render(filename=filename, issues=self.issues, verbose=self.verbose) def as_json(self): - issues = [] - for key, issue in self.issues.items(): - issues.append(issue.as_dict()) + issues = [issue.as_dict() for key, issue in self.issues.items()] result = {'success': True, 'error': None, 'issues': issues} return json.dumps(result) @@ -104,7 +78,7 @@ class Report: text += "- Contract: Unknown\n" text += "- Function name: `" + issue.function + "`\n" - text += "- PC address: " + str(issue.pc) + "\n\n" + text += "- PC address: " + str(issue.address) + "\n\n" text += "### Description\n\n" + issue.description diff --git a/mythril/analysis/templates/report_as_text.jinja2 b/mythril/analysis/templates/report_as_text.jinja2 new file mode 100644 index 00000000..be21ab6b --- /dev/null +++ b/mythril/analysis/templates/report_as_text.jinja2 @@ -0,0 +1,27 @@ +{%- if issues -%} +{% for key, issue in issues.items() -%} +==== {{ issue.title }} ==== +Type: {{ issue.type }} +Contract: {{ issue.contract | default("Unknown") }} +Function name: {{ issue.function }} +PC address: {{ issue.address }} +{{ issue.description }} +-------------------- +{% if issue.filename and issue.lineno -%} +In file: {{ issue.filename }}:{{ issue.lineno }} +{%- endif %} +{% if issue.code -%} +-------------------- +{{ issue.code }} +{%- endif -%} +{% if verbose and issue.debug -%} +-------------------- +DEBUGGING INFORMATION: + +{{ issue.debug }} +{%- endif %} + +{% endfor -%} +{%- else -%} +The analysis was completed successfully. No issues were detected. +{%- endif -%}