diff options
author | chriseth <chris@ethereum.org> | 2017-04-24 22:15:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-24 22:15:32 +0800 |
commit | 2c3fea55df4e7eff6df515c19f5f80737e829bcf (patch) | |
tree | 4aa2b24b46858325681d05b1603cbb5c2ecf70f5 /libsolidity | |
parent | 388486bb9d83805a0a8f1fa872feaad7dd20475d (diff) | |
parent | 4a9ba5b9528a704392dca52c6b146d3baa0cce7d (diff) | |
download | dexon-solidity-2c3fea55df4e7eff6df515c19f5f80737e829bcf.tar.gz dexon-solidity-2c3fea55df4e7eff6df515c19f5f80737e829bcf.tar.zst dexon-solidity-2c3fea55df4e7eff6df515c19f5f80737e829bcf.zip |
Merge pull request #2159 from ethereum/jsonio-source-verify
Verify supplied hash in JSON I/O
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/interface/StandardCompiler.cpp | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 4a8787b3..582765e7 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -25,6 +25,7 @@ #include <libsolidity/ast/ASTJsonConverter.h> #include <libevmasm/Instruction.h> #include <libdevcore/JSON.h> +#include <libdevcore/SHA3.h> using namespace std; using namespace dev; @@ -91,6 +92,19 @@ Json::Value formatErrorWithException( return formatError(_warning, _type, _component, message, formattedMessage, location); } +/// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content. +bool hashMatchesContent(string const& _hash, string const& _content) +{ + try + { + return dev::h256(_hash) == dev::keccak256(_content); + } + catch (dev::BadHexCharacter) + { + return false; + } +} + StringMap createSourceList(Json::Value const& _input) { StringMap sources; @@ -165,8 +179,24 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value errors = Json::arrayValue; for (auto const& sourceName: sources.getMemberNames()) + { + string hash; + if (sources[sourceName]["keccak256"].isString()) + hash = sources[sourceName]["keccak256"].asString(); + if (sources[sourceName]["content"].isString()) - m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); + { + string content = sources[sourceName]["content"].asString(); + if (!hash.empty() && !hashMatchesContent(hash, content)) + errors.append(formatError( + false, + "IOError", + "general", + "Mismatch between content and supplied hash for \"" + sourceName + "\"" + )); + else + m_compilerStack.addSource(sourceName, content); + } else if (sources[sourceName]["urls"].isArray()) { if (!m_readFile) @@ -180,9 +210,19 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) ReadFile::Result result = m_readFile(url.asString()); if (result.success) { - m_compilerStack.addSource(sourceName, result.contentsOrErrorMessage); - found = true; - break; + if (!hash.empty() && !hashMatchesContent(hash, result.contentsOrErrorMessage)) + errors.append(formatError( + false, + "IOError", + "general", + "Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.asString() + "\"" + )); + else + { + m_compilerStack.addSource(sourceName, result.contentsOrErrorMessage); + found = true; + break; + } } else failures.push_back("Cannot import url (\"" + url.asString() + "\"): " + result.contentsOrErrorMessage); @@ -201,6 +241,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) } else return formatFatalError("JSONError", "Invalid input source specified."); + } Json::Value const& settings = _input.get("settings", Json::Value()); |