Exemple #1
0
def compile_cached(path_src):
    grammar = get_solidity_grammar_instance()

    path_src = Path(path_src)
    path_cache = path_src.parent / "cache"

    if not path_cache.exists():
        path_cache.mkdir()

    path_ast_json = path_cache / (path_src.name + ".ast_json")
    path_ast = path_cache / (path_src.name + ".ast")

    if not path_ast_json.exists() or not path_ast.exists():
        ast_json = compile_ast(str(path_src))
        ast = DictTransformer(grammar=grammar,
                              implicit_terminals=True).transform(ast_json)

        print(f"Precompiled AST not found. Compiling AST... [{path_src}]")
        with open(path_ast_json, 'w') as file:
            ast_json["_solc_version"] = str(ast_json["_solc_version"])
            json.dump(ast_json, file)

        with open(path_ast, 'wb') as file:
            pickle.dump(ast, file)

    with open(path_ast, 'rb') as file:
        ast = pickle.load(file)

    ast = DefaultEvaluator(grammar).for_tree(ast)

    return CompileOutput(ast.cfg, ast, None, None, None)
Exemple #2
0
def main():

    args = parse_arguments()

    prepare_env(binary=args.solidity)

    sys.setrecursionlimit(args.stack_limit)

    contract = args.contract

    if args.from_blockchain:
        contract = get_contract_from_blockchain(args.contract, args.key)

    if not args.ignore_pragma:
        contract = fix_pragma(contract)

    souffle_config = dict(use_interpreter=args.interpreter,
                          force_recompilation=args.recompile,
                          library_dir=args.library_dir)

    config = AnalysisConfiguration(
        # TODO: this returns only the dict ast, but should return the object representation
        ast_compiler=lambda t: solidity_ast_compiler.compile_ast(t.source_file
                                                                 ),
        cfg_compiler=lambda t: solidity_cfg_compiler.compile_cfg(t.ast).cfg,
        static_analysis=lambda t: static_analysis.analyze_cfg(
            t.cfg, **souffle_config),
    )

    context = AnalysisContext(config=config, source_file=contract)

    if args.visualize:
        cfg = context.cfg
        facts, _ = encode(cfg)
        visualize(facts).render("out/dl", format="svg", cleanup=True)

    patterns = get_list_of_patterns(context=context,
                                    patterns=args.use_patterns,
                                    exclude_patterns=args.exclude_patterns,
                                    severity_inc=args.include_severity,
                                    severity_exc=args.exclude_severity)

    matches = []

    for pattern in patterns:
        matches.extend(pattern.find_matches())

    skip_compliant = not args.show_compliants
    print_pattern_matches(context,
                          matches,
                          skip_compliant=skip_compliant,
                          include_contracts=args.include_contracts,
                          exclude_contracts=args.exclude_contracts)
Exemple #3
0
    def test_robustness(self):

        contract = get_contract_from_blockchain(contract_address,
                                                "../../../api_key.txt")
        contract = fix_pragma(contract)

        config = AnalysisConfiguration(
            # TODO: this returns only the dict ast, but should return the object representation
            ast_compiler=lambda t: solidity_ast_compiler.compile_ast(
                t.source_file),
            cfg_compiler=lambda t: solidity_cfg_compiler.compile_cfg(t.ast).
            cfg,
        )

        context = AnalysisContext(config=config, source_file=contract)

        cfg = context.cfg
        assert (cfg)
Exemple #4
0
    def test_case(self: unittest.TestCase):
        config = AnalysisConfiguration(
            # TODO: this returns only the dict ast, but should return the object representation
            ast_compiler=lambda t: solidity_ast_compiler.compile_ast(
                t.source_file),
            cfg_compiler=lambda t: solidity_cfg_compiler.compile_cfg(t.ast).
            cfg,
            static_analysis=lambda t: static_analysis.analyze_cfg(t.cfg),
        )

        context = AnalysisContext(config=config, source_file=path_src)

        test_info, annotations = read_test_info()

        patterns = TestPatterns.patterns
        patterns = [p for p in patterns if p.__name__ == test_info["pattern"]]

        assert len(patterns) == 1, len(patterns)

        matches: List[PatternMatch] = []

        for pattern in patterns:
            matches += pattern(context).find_matches()

        self.assertFalse(
            [m for m in matches if not isinstance(m, PatternMatch)],
            "Result must be a PatternMatch")
        self.assertFalse([m for m in matches if m.type == MatchType.CONFLICT],
                         "Conflicts must not happen")

        compliant = [
            next(m.find_info(MatchSourceLocation)).line for m in matches
            if m.type == MatchType.COMPLIANT
        ]
        violation = [
            next(m.find_info(MatchSourceLocation)).line for m in matches
            if m.type == MatchType.VIOLATION
        ]
        warning = [
            next(m.find_info(MatchSourceLocation)).line for m in matches
            if m.type == MatchType.WARNING
        ]

        def compare(expected, actual, e):
            try:
                self.assertSetEqual(set(expected), set(actual), e)
            except AssertionError as e:  # Fix ambiguous error messages
                msg = e.args[0]
                msg = msg.replace("Items in the first set but not the second",
                                  "Items expected but not reported")

                msg = msg.replace("Items in the second set but not the first",
                                  "Items incorrectly reported")

                raise AssertionError(msg) from None

        compare([t[0] for t in annotations["compliant"]], compliant,
                "Compliant")
        compare([t[0] for t in annotations["violation"]], violation,
                "Violation")
        compare([t[0] for t in annotations["warning"]], warning, "Warnings")
Exemple #5
0
def main():

    save_stdout = sys.stdout

    args = parse_arguments()

    # suppress the output when outputting json
    if args.output_json:
        sys.stdout = open('/tmp/securify_suppressed.out', 'w')

    prepare_env(binary=args.solidity)

    sys.setrecursionlimit(args.stack_limit)

    contract = args.contract

    if args.flatten:
        my_module = importlib.import_module("securify.utils.flattener",
                                            package=".")
        contract = my_module.flatten(contract)

    if args.from_blockchain:
        contract = get_contract_from_blockchain(args.contract, args.key)

    if not args.ignore_pragma:
        contract = fix_pragma(contract)

    souffle_config = dict(use_interpreter=args.interpreter,
                          force_recompilation=args.recompile,
                          library_dir=args.library_dir)

    config = AnalysisConfiguration(
        # TODO: this returns only the dict ast, but should return the object representation
        ast_compiler=lambda t: solidity_ast_compiler.compile_ast(t.source_file
                                                                 ),
        cfg_compiler=lambda t: solidity_cfg_compiler.compile_cfg(t.ast).cfg,
        static_analysis=lambda t: static_analysis.analyze_cfg(
            t.cfg, **souffle_config),
    )

    context = AnalysisContext(config=config, source_file=contract)

    if args.visualize:
        cfg = context.cfg
        facts, _ = encode(cfg)
        visualize(facts).render("out/dl", format="svg", cleanup=True)

    patterns = get_list_of_patterns(context=context,
                                    patterns=args.use_patterns,
                                    exclude_patterns=args.exclude_patterns,
                                    severity_inc=args.include_severity,
                                    severity_exc=args.exclude_severity)

    matches = []

    for pattern in patterns:
        matches.extend(pattern.find_matches())

    skip_compliant = not args.show_compliants

    sys.stdout = save_stdout
    if args.output_json:
        print_pattern_matches_json(context,
                                   matches,
                                   skip_compliant=skip_compliant,
                                   include_contracts=args.include_contracts,
                                   exclude_contracts=args.exclude_contracts)
    else:
        print_pattern_matches(context,
                              matches,
                              skip_compliant=skip_compliant,
                              include_contracts=args.include_contracts,
                              exclude_contracts=args.exclude_contracts)
Exemple #6
0
    if len(lines) == cnt_lines:
        return "\b"

    #for comment in match.find_info(MatchComment):
    #     lines.append(textwrap.fill(comment.comment,
    #                                initial_indent="Comment: ",
    #                                subsequent_indent="         "))
    lines.append("\n")

    return "\n".join(lines)


if __name__ == '__main__':
    config = AnalysisConfiguration(
        # TODO: this returns only the dict ast, but should return the object representation
        ast_compiler=lambda t: solidity_ast_compiler.compile_ast(t.source_file),
        cfg_compiler=lambda t: solidity_cfg_compiler.compile_cfg(t.ast).cfg,
        static_analysis=lambda t: static_analysis.analyze_cfg(t.cfg),
    )

    context = AnalysisContext(
        config=config,
        source_file="testContract.sol"
    )

    patterns = discover_patterns()

    matches = []
    for pattern in patterns:
        matches.extend(pattern(context).find_matches())