aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-01-14 17:16:58 +0800
committerChristian <c@ethdev.com>2015-01-14 17:16:58 +0800
commit6e16107870494878635da347146b076a7d75dea0 (patch)
treeb797f8b57a875198b634d0e9ee145f8306c86d62
parent80eec8b308e8af3b742e3da47ded927e4e4b388d (diff)
downloaddexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar.gz
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar.bz2
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar.lz
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar.xz
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.tar.zst
dexon-solidity-6e16107870494878635da347146b076a7d75dea0.zip
Check for hash collisions already before compiling.
-rw-r--r--AST.cpp38
-rwxr-xr-xAST.h2
2 files changed, 32 insertions, 8 deletions
diff --git a/AST.cpp b/AST.cpp
index d171006a..ea8ecdb7 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -50,18 +50,27 @@ void ContractDefinition::checkTypeRequirements()
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
function->checkTypeRequirements();
+
+ // check for hash collisions in function signatures
+ vector<pair<FixedHash<4>, FunctionDefinition const*>> exportedFunctionList = getInterfaceFunctionList();
+ set<FixedHash<4>> hashes;
+ for (auto const& hashAndFunction: getInterfaceFunctionList())
+ {
+ FixedHash<4> const& hash = hashAndFunction.first;
+ if (hashes.count(hash))
+ BOOST_THROW_EXCEPTION(createTypeError("Function signature hash collision for " +
+ hashAndFunction.second->getCanonicalSignature()));
+ hashes.insert(hash);
+ }
}
map<FixedHash<4>, FunctionDefinition const*> ContractDefinition::getInterfaceFunctions() const
{
- map<FixedHash<4>, FunctionDefinition const*> exportedFunctions;
- for (ASTPointer<FunctionDefinition> const& f: m_definedFunctions)
- if (f->isPublic() && f->getName() != getName())
- {
- FixedHash<4> hash(dev::sha3(f->getCanonicalSignature()));
- auto res = exportedFunctions.insert(std::make_pair(hash,f.get()));
- solAssert(res.second, "Hash collision at Function Definition Hash calculation");
- }
+ vector<pair<FixedHash<4>, FunctionDefinition const*>> exportedFunctionList = getInterfaceFunctionList();
+ map<FixedHash<4>, FunctionDefinition const*> exportedFunctions(exportedFunctionList.begin(),
+ exportedFunctionList.end());
+ solAssert(exportedFunctionList.size() == exportedFunctions.size(),
+ "Hash collision at Function Definition Hash calculation");
return exportedFunctions;
}
@@ -74,6 +83,19 @@ FunctionDefinition const* ContractDefinition::getConstructor() const
return nullptr;
}
+vector<pair<FixedHash<4>, FunctionDefinition const*>> ContractDefinition::getInterfaceFunctionList() const
+{
+ vector<pair<FixedHash<4>, FunctionDefinition const*>> exportedFunctions;
+ for (ASTPointer<FunctionDefinition> const& f: m_definedFunctions)
+ if (f->isPublic() && f->getName() != getName())
+ {
+ FixedHash<4> hash(dev::sha3(f->getCanonicalSignature()));
+ exportedFunctions.push_back(make_pair(hash, f.get()));
+ }
+
+ return exportedFunctions;
+}
+
void StructDefinition::checkMemberTypes() const
{
for (ASTPointer<VariableDeclaration> const& member: getMembers())
diff --git a/AST.h b/AST.h
index 95121d4c..28fb7f0a 100755
--- a/AST.h
+++ b/AST.h
@@ -191,6 +191,8 @@ public:
FunctionDefinition const* getConstructor() const;
private:
+ std::vector<std::pair<FixedHash<4>, FunctionDefinition const*>> getInterfaceFunctionList() const;
+
std::vector<ASTPointer<StructDefinition>> m_definedStructs;
std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;