def _step_internal( step: Dict, last_step: Dict, start: Union[str, int], stop: Union[str, int], gas: Tuple[int, int], subcall: Dict = None, ) -> str: if last_step["op"] in {"REVERT", "INVALID"} and _step_compare( step, last_step): contract_color = color("bright red") else: contract_color = color( "bright cyan") if not step["jumpDepth"] else color() key = f"{color('dark white')}{contract_color}{step['fn']} {color('dark white')}" left_bracket = f"{color('dark white')}[" right_bracket = f"{color('dark white')}]" if subcall: key = f"{key}[{color}{subcall['op']}{right_bracket} " key = f"{key}{start}:{stop}{color}" if gas: if gas[0] == gas[1]: gas_str = f"{color('bright yellow')}{gas[0]} gas" else: gas_str = f"{color('bright yellow')}{gas[0]} / {gas[1]} gas" key = f"{key} {left_bracket}{gas_str}{right_bracket}" if last_step["op"] == "SELFDESTRUCT": key = f"{key} {left_bracket}{color('bright red')}SELFDESTRUCT{right_bracket}" return key
def _step_print( step: Dict, last_step: Dict, indent: Optional[str], start: Union[str, int], stop: Union[str, int], gas: Tuple[int, int], ) -> str: print_str = f"\n{color('dark white')}" if indent is not None: print_str += f"{indent}\u2500" if last_step["op"] in {"REVERT", "INVALID"} and _step_compare( step, last_step): contract_color = color("bright red") else: contract_color = color( "bright magenta" if not step["jumpDepth"] else "") print_str += f"{contract_color}{step['fn']} {color('dark white')}{start}:{stop}{color}" if gas[0] == gas[1]: print_str += f" [{color('bright yellow')}{gas[0]} gas{color}]" else: print_str += f" [{color('bright yellow')}{gas[0]} / {gas[1]} gas{color}]" if not step["jumpDepth"]: print_str += ( f" {color('dark white')}({color}{step['address']}{color('dark white')}){color}" ) return print_str
def _dir_color(obj): if type(obj).__name__ == "module": return color("module") if hasattr(obj, "_dir_color"): return color(obj._dir_color) if not callable(obj): return color("value") return color("callable")
def _dir_color(obj): if type(obj).__name__ == "module": return color("brownie blue") if hasattr(obj, "_dir_color"): return color(obj._dir_color) if not callable(obj): return color("bright blue") return color("bright cyan")
def print_console_report(stdout_report) -> None: """Highlight and print a given stdout report to the console. This adds color formatting to the given stdout report and prints a summary of the vulnerabilities MythX has detected. :return: None """ total_issues = sum(x for i in stdout_report.values() for x in i.values()) if not total_issues: notify("SUCCESS", "No issues found!") return # display console report total_high_severity = sum(i.get("HIGH", 0) for i in stdout_report.values()) if total_high_severity: notify( "WARNING", f"Found {total_issues} issues including {total_high_severity} high severity!" ) else: print(f"Found {total_issues} issues:") for name in sorted(stdout_report): print(f"\n contract: {color('bright magenta')}{name}{color}") for key in [ i for i in ("HIGH", "MEDIUM", "LOW") if i in stdout_report[name] ]: c = color("bright red" if key == "HIGH" else "bright yellow") print(f" {key.title()}: {c}{stdout_report[name][key]}{color}")
def _step_print( step: Dict, last_step: Dict, indent: Optional[str], start: Union[str, int], stop: Union[str, int], ) -> str: print_str = f"\n{color['dull']}" if indent is not None: print_str += f"{indent}\u2500" if last_step["op"] in {"REVERT", "INVALID"} and _step_compare( step, last_step): contract_color = color("error") else: contract_color = color( "contract_method" if not step["jumpDepth"] else "") print_str += f"{contract_color}{step['fn']} {color['dull']}{start}:{stop}{color}" if not step["jumpDepth"]: print_str += f" {color['dull']}({color}{step['address']}{color['dull']}){color}" return print_str
def _list(project_path): installed, modified = ethpm.get_installed_packages(project_path) package_list = sorted(installed + modified) if not package_list: print("No packages are currently installed in this project.") return if modified: notify( "WARNING", f"One or more files in {len(modified)} packages have been modified since installation.", ) print("Unlink or reinstall them to silence this warning.") print(f"Modified packages name are highlighted in {color['bright blue']}blue{color}.\n") print(f"Found {color('bright magenta')}{len(package_list)}{color} installed packages:") for name in package_list: u = "\u2514" if name == package_list[-1] else "\u251c" c = color("bright blue") if name in modified else color("bright white") print( f" {color('bright black')}{u}\u2500{c}{name[0]}{color}@" f"{color('bright white')}{name[1]}{color}" )
def generate_highlighting_report(self) -> None: """Generate a Brownie highlighting report from a MythX issue report. This will convert a MythX issue report into a Brownie report that allows issues to be highlighted in the native Brownie GUI. It iterates over the internal :code:`reports` dictionary and fills the :code:`highlight_report` instance variable. :return: None """ source_to_name = { d["sourcePath"]: d["contractName"] for _, d in self.build.items() } for idx, (contract_name, issue_report) in enumerate(self.reports.items()): print("Generating report for {}{}{} ({}/{})".format( color("bright blue"), contract_name, color, idx, len(self.reports))) for report in issue_report.issue_reports: for issue in report: # convert issue locations to report locations # severities are highlighted according to SEVERITY_COLOURS for loc in issue.locations: comp = loc.source_map.components[0] source_list = loc.source_list or report.source_list if source_list and 0 <= comp.file_id < len( source_list): filename = source_list[comp.file_id] if filename not in source_to_name: continue contract_name = source_to_name[filename] severity = issue.severity.name self.highlight_report["highlights"][ "MythX"].setdefault(contract_name, {filename: []}) self.highlight_report["highlights"]["MythX"][ contract_name][filename].append([ comp.offset, comp.offset + comp.length, SEVERITY_COLOURS[severity], "{}: {}\n{}".format( issue.swc_id, issue.description_short, issue.description_long, ), ])
def __init__(self) -> None: brownie.chain.revert() sf.RuleBasedStateMachine.__init__(self) # pytest capturemanager plugin, added when accessed via the state_manager fixture capman = getattr(self, "_capman", None) if capman: with capman.global_and_fixture_disabled(): c = color("red" if self._failed else "yellow") sys.stdout.write(f"{c}{marker[0]}\033[1D") sys.stdout.flush() marker.rotate(1) if hasattr(self, "setup"): self.setup() # type: ignore
def _print_verbose_network_description(network_dict, is_last, indent=0): u = "\u2514" if is_last else "\u251c" v = " " if is_last else "\u2502" if "name" in network_dict: print(f"{color('bright black')} {u}\u2500{color}{network_dict.pop('name')}") obj_keys = sorted(network_dict) if "id" in obj_keys: obj_keys.remove("id") obj_keys.insert(0, "id") for key in obj_keys: value = network_dict[key] u = "\u2514" if key == obj_keys[-1] else "\u251c" if indent: u = (" " * indent) + u c = color("green") if key == "id" else "" print(f"{color('bright black')} {v} {u}\u2500{color}{key}: {c}{value}{color}")
def main(): args = docopt(__doc__) project_path = project.check_for_project(".") if project_path is None: raise ProjectNotFound build_path = project_path.joinpath( _load_project_structure_config(project_path)["build"]) contract_artifact_path = build_path.joinpath("contracts") interface_artifact_path = build_path.joinpath("interfaces") if args["--all"]: shutil.rmtree(contract_artifact_path, ignore_errors=True) shutil.rmtree(interface_artifact_path, ignore_errors=True) elif args["<contract>"]: for name in args["<contract>"]: path = contract_artifact_path.joinpath(f"{name}.json") if path.exists(): path.unlink() proj = project.load() if args["--size"]: print("============ Deployment Bytecode Sizes ============") codesize = [] for contract in proj: bytecode = contract._build["deployedBytecode"] if bytecode: codesize.append((contract._name, len(bytecode) // 2)) indent = max(len(i[0]) for i in codesize) for name, size in sorted(codesize, key=lambda k: k[1], reverse=True): pct = size / 24577 pct_color = color( next((i[1] for i in CODESIZE_COLORS if pct >= i[0]), "")) print( f" {name:<{indent}} - {size:>6,}B ({pct_color}{pct:.2%}{color})" ) print() print( f"Project has been compiled. Build artifacts saved at {contract_artifact_path}" )
def test_call(): assert color("red") != "" assert str(color) == "\x1b[0;m"
def test_bright_dark(): assert color("yellow") != color("dark yellow") != color( "bright yellow") != ""
def test_unknown(): assert color("potato") == color()
def main(): args = docopt(__doc__) _update_argv_from_docopt(args) project_path = project.check_for_project(".") if project_path is None: raise ProjectNotFound build = project.load()._build print("Preparing project data for submission to MythX...") contracts, libraries = get_contract_types(build) job_data = assemble_contract_jobs(build, contracts) job_data = update_contract_jobs_with_dependencies(build, contracts, libraries, job_data) client, authenticated = get_mythx_client() job_uuids = send_to_mythx(job_data, client, authenticated) # exit if user wants an async analysis run if ARGV["async"] and authenticated: print( "\nAll contracts were submitted successfully. Check the dashboard at " "https://dashboard.mythx.io/ for the progress and results of your analyses" ) return print("\nWaiting for results...") wait_for_jobs(job_uuids, client) # assemble report json source_to_name = get_contract_locations(build) highlight_report = {"highlights": {"MythX": {}}} stdout_report = {} for c, uuid in enumerate(job_uuids, start=1): print( f"Generating report for job {color['value']}{uuid}{color} ({c}/{len(job_uuids)})" ) if authenticated: print("You can also check the results at {}{}\n".format( DASHBOARD_BASE_URL, uuid)) update_report(client, uuid, highlight_report, stdout_report, source_to_name) # erase previous report report_path = Path("reports/security.json") if report_path.exists(): report_path.unlink() total_issues = sum(x for i in stdout_report.values() for x in i.values()) if not total_issues: notify("SUCCESS", "No issues found!") return # display console report total_high_severity = sum(i.get("HIGH", 0) for i in stdout_report.values()) if total_high_severity: notify( "WARNING", f"Found {total_issues} issues including {total_high_severity} high severity!" ) else: print(f"Found {total_issues} issues:") for name in sorted(stdout_report): print(f"\n contract: {color['contract']}{name}{color}") for key in [ i for i in ("HIGH", "MEDIUM", "LOW") if i in stdout_report[name] ]: c = color("bright " + SEVERITY_COLOURS[key]) print(f" {key.title()}: {c}{stdout_report[name][key]}{color}") # Write report to Brownie directory with report_path.open("w+") as fp: json.dump(highlight_report, fp, indent=2, sort_keys=True) # Launch GUI if user requested it if ARGV["gui"]: print("Launching the Brownie GUI") Gui = importlib.import_module("brownie._gui").Gui Gui().mainloop()
def test_call_getitem(): assert color("success") == color["success"] != "" assert str(color) == "\x1b[0;m"
def _cov_color(pct): return color(next(i[1] for i in COVERAGE_COLORS if pct <= i[0]))
def test_show_colors_config(config): config.settings["console"]["show_colors"] = False assert color("blue") == ""