eth-sri / securify

[DEPRECATED] Security Scanner for Ethereum Smart Contracts
Apache License 2.0
215 stars 50 forks source link

Print solc Stacktrace when solc fails #24

Closed EnergyFusion closed 5 years ago

EnergyFusion commented 5 years ago

I have checked the following

============================================================================
souffle -- A datalog engine.
Usage: souffle [OPTION] FILE.
----------------------------------------------------------------------------
Options:
        -F<DIR>                 --fact-dir=<DIR>                        Specify directory for fact files.
        -I<DIR>                 --include-dir=<DIR>                     Specify directory for include files.
        -D<DIR>                 --output-dir=<DIR>                      Specify directory for output files (if <DIR> is -, stdout is used).
        -j<N>                   --jobs=<N>                              Run interpreter/compiler in parallel using N threads, N=auto for system default.
        -c                      --compile                               Generate C++ source code, compile to a binary executable, then run this executable.
        -g<FILE>                --generate=<FILE>                       Generate C++ source code for the given Datalog program and write it to <FILE>.
        -w                      --no-warn                               Disable warnings.
        -m<RELATIONS>           --magic-transform=<RELATIONS>           Enable magic set transformation changes on the given relations, use '*' for all.
        -z<TRANSFORMERS>        --disable-transformers=<TRANSFORMERS>   Disable the given AST transformers.
        -o<FILE>                --dl-program=<FILE>                     Generate C++ source code, written to <FILE>, and compile this to a binary executable (without executing it).
        -l                      --live-profile                          Enable live profiling.
        -p<FILE>                --profile=<FILE>                        Enable profiling, and write profile data to <FILE>.
        -r<FILE>                --debug-report=<FILE>                   Write HTML debug report to <FILE>.
        -t<EXPLAIN>             --provenance=<EXPLAIN>                  Enable provenance information via guided SLD.
        -d<type>                --data-structure=<type>                 Specify data structure (brie/btree/eqrel/rbtset/hashset).
        -e<[ file | mpi ]>      --engine=<[ file | mpi ]>               Specify communication engine for distributed execution.
                                --hostfile=<FILE>                       Specify --hostfile option for call to mpiexec when using mpi as execution engine.
        -v                      --verbose                               Verbose output.
        -h                      --help                                  Display this help message.
----------------------------------------------------------------------------
Version: 1.4.0-174-geb5857a
----------------------------------------------------------------------------
Copyright (c) 2016-18 The Souffle Developers.
Copyright (c) 2013-16 Oracle and/or its affiliates.
All rights reserved.
============================================================================
solc, the solidity compiler commandline interface
Version: 0.4.25+commit.59dbf8f1.Linux.g++
src/test/resources/solidity/transaction-reordering.sol:1:1: Error: Source file requires different compiler version (current compiler is 0.4.25+commit.59dbf8f1.Linux.g++ - note that nightly builds are considered to be strictly less than the released version
pragma solidity 0.4.24;
^---------------------^
src/test/resources/solidity/transaction-reordering.sol:5:9: Warning: Failure condition of 'send' ignored. Consider using 'transfer' instead.
        msg.sender.send(x);
        ^----------------^
src/test/resources/solidity/transaction-reordering.sol:11:9: Warning: Failure condition of 'send' ignored. Consider using 'transfer' instead.
        msg.sender.send(y);
        ^----------------^
src/test/resources/solidity/transaction-reordering.sol:15:18: Warning: Using contract member "balance" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).balance" instead.
        uint x = this.balance;
                 ^----------^
src/test/resources/solidity/transaction-reordering.sol:16:9: Warning: Failure condition of 'send' ignored. Consider using 'transfer' instead.
        msg.sender.send(x);
        ^----------------^

NA

Steps to reproduce

  1. Run java -jar build/libs/securify-0.1.jar -fs src/test/resources/solidity/transaction-reordering.sol with the wrong version of solc installed.
  2. Receive the following unhelpful output:
    Exception in thread "main" java.io.IOException
        at ch.securify.CompilationHelpers.compileContracts(CompilationHelpers.java:97)
        at ch.securify.Main.processSolidityFile(Main.java:91)
        at ch.securify.Main.main(Main.java:186)

Proposed solution

Modify CompilationHelpers.compileContracts to the following:

ProcessBuilder p = new ProcessBuilder("solc", "--combined-json", "abi,ast,bin-runtime,srcmap-runtime", filesol);

        File f = File.createTempFile("securify_compilation_", ".json");
        f.deleteOnExit();

        final Process process = p.redirectOutput(f).start();

        Thread t = new Thread(){
            public void run(){
                try {
                    InputStreamReader isr = new InputStreamReader(process.getErrorStream());
                    BufferedReader br = new BufferedReader(isr);
                    String line = br.readLine();
                    if (!line.contains("Error")) {
                        return;
                    }
                    String stacktrace = line + "\n";
                    while ( (line = br.readLine()) != null) {
                        stacktrace += line + "\n";
                    }
                    System.err.println(stacktrace);
                } catch (IOException ioe) {
                    ioe.printStackTrace();  
                }
            }
        };
        t.start();

        process.waitFor();
        int exitValue = process.exitValue();
        if(exitValue != 0){            
            throw new RuntimeException();
        }

        JsonObject jsonObject = new JsonParser().parse(readFile(f.getPath())).getAsJsonObject();

        return jsonObject.get("contracts").getAsJsonObject();

and add the following imports:

import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.Thread;
import java.lang.RuntimeException;

Use of RuntimeException is suggested over use of IOException

hiqua commented 5 years ago

I understand that it's your PR, feel free to reopen this issue if that's not the case.