diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-04-22 21:43:10 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-04-24 21:34:29 +0800 |
commit | 4a9ba5b9528a704392dca52c6b146d3baa0cce7d (patch) | |
tree | 40bebfc46ab9a2b8b2c9c3eec896f6b95a692c8a /libsolidity | |
parent | aa441668db9ea5ec68b8988209c3ed7c82659876 (diff) | |
download | dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar.gz dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar.bz2 dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar.lz dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar.xz dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.tar.zst dexon-solidity-4a9ba5b9528a704392dca52c6b146d3baa0cce7d.zip |
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()); |