Check for hash collisions already before compiling.

This commit is contained in:
Christian 2015-01-14 10:16:58 +01:00
parent 80eec8b308
commit 6e16107870
2 changed files with 32 additions and 8 deletions

38
AST.cpp
View File

@ -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())

2
AST.h
View File

@ -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;