diff options
author | chriseth <c@ethdev.com> | 2017-01-25 00:38:06 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2017-01-25 06:37:48 +0800 |
commit | 1316bb75651ea365c5246277d2dfd3d366be9070 (patch) | |
tree | 8c46bf1a45ca85bcd1da2d8ef8b2556e22cf5634 /libsolidity/ast | |
parent | ba9a04500217e301bec63cab4e0c0f1d9322646d (diff) | |
download | dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar.gz dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar.bz2 dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar.lz dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar.xz dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.tar.zst dexon-solidity-1316bb75651ea365c5246277d2dfd3d366be9070.zip |
Warn about invalid checksums of addresses.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.cpp | 43 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 5 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 8 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 2 |
4 files changed, 56 insertions, 2 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 8a43c3f7..e2b50dd7 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -20,8 +20,6 @@ * Solidity abstract syntax tree. */ -#include <algorithm> -#include <functional> #include <libsolidity/interface/Utils.h> #include <libsolidity/ast/AST.h> #include <libsolidity/ast/ASTVisitor.h> @@ -30,6 +28,11 @@ #include <libdevcore/SHA3.h> +#include <boost/algorithm/string.hpp> + +#include <algorithm> +#include <functional> + using namespace std; using namespace dev; using namespace dev::solidity; @@ -522,3 +525,39 @@ IdentifierAnnotation& Identifier::annotation() const m_annotation = new IdentifierAnnotation(); return static_cast<IdentifierAnnotation&>(*m_annotation); } + +bool Literal::looksLikeAddress() const +{ + if (subDenomination() != SubDenomination::None) + return false; + + string lit = value(); + return lit.substr(0, 2) == "0x" && abs(int(lit.length()) - 42) <= 1; +} + +bool Literal::passesAddressChecksum() const +{ + string lit = value(); + solAssert(lit.substr(0, 2) == "0x", "Expected hex prefix"); + lit = lit.substr(2); + + if (lit.length() != 40) + return false; + + h256 hash = keccak256(boost::algorithm::to_lower_copy(lit, std::locale::classic())); + for (size_t i = 0; i < 40; ++i) + { + char addressCharacter = lit[i]; + bool lowerCase; + if ('a' <= addressCharacter && addressCharacter <= 'f') + lowerCase = true; + else if ('A' <= addressCharacter && addressCharacter <= 'F') + lowerCase = false; + else + continue; + unsigned nibble = (unsigned(hash[i / 2]) >> (4 * (1 - (i % 2)))) & 0xf; + if ((nibble >= 8) == lowerCase) + return false; + } + return true; +} diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 4c75f7ea..743fdaa1 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1584,6 +1584,11 @@ public: SubDenomination subDenomination() const { return m_subDenomination; } + /// @returns true if this looks like a checksummed address. + bool looksLikeAddress() const; + /// @returns true if it passes the address checksum test. + bool passesAddressChecksum() const; + private: Token::Value m_token; ASTPointer<ASTString> m_value; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index cefd0603..971e1f18 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -405,6 +405,14 @@ string IntegerType::toString(bool) const return prefix + dev::toString(m_bits); } +u256 IntegerType::literalValue(Literal const* _literal) const +{ + solAssert(m_modifier == Modifier::Address, ""); + solAssert(_literal, ""); + solAssert(_literal->value().substr(0, 2) == "0x", ""); + return u256(_literal->value()); +} + TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const { if ( diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 1e94631e..770cbb30 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -314,6 +314,8 @@ public: virtual std::string toString(bool _short) const override; + virtual u256 literalValue(Literal const* _literal) const override; + virtual TypePointer encodingType() const override { return shared_from_this(); } virtual TypePointer interfaceType(bool) const override { return shared_from_this(); } |