diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 10 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 23 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 5 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 8 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 2 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 1 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 16 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.h | 1 | ||||
-rw-r--r-- | libsolidity/interface/CompilerStack.cpp | 13 | ||||
-rw-r--r-- | libsolidity/interface/CompilerStack.h | 2 |
10 files changed, 72 insertions, 9 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index adb3d54f..533c787b 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1565,6 +1565,16 @@ void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) void TypeChecker::endVisit(Literal const& _literal) { + if (_literal.looksLikeAddress()) + { + if (_literal.passesAddressChecksum()) + { + _literal.annotation().type = make_shared<IntegerType>(0, IntegerType::Modifier::Address); + return; + } + else + warning(_literal.location(), "This looks like an address but has an invalid checksum."); + } _literal.annotation().type = Type::forLiteral(_literal); if (!_literal.annotation().type) fatalTypeError(_literal.location(), "Invalid literal value."); diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 8a43c3f7..616de54e 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,19 @@ 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"); + return dev::passesAddressChecksum(lit, 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(); } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index fe0eeb1c..bda4e04d 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1308,6 +1308,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal) { case Type::Category::RationalNumber: case Type::Category::Bool: + case Type::Category::Integer: m_context << type->literalValue(&_literal); break; case Type::Category::StringLiteral: diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index ef3da255..fcc92dbb 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -71,6 +71,8 @@ assembly::Statement Parser::parseStatement() expectToken(Token::Colon); assignment.variableName.location = location(); assignment.variableName.name = m_scanner->currentLiteral(); + if (instructions().count(assignment.variableName.name)) + fatalParserError("Identifier expected, got instruction name."); assignment.location.end = endPosition(); expectToken(Token::Identifier); return assignment; @@ -101,6 +103,8 @@ assembly::Statement Parser::parseStatement() { // functional assignment FunctionalAssignment funAss = createWithLocation<FunctionalAssignment>(identifier.location); + if (instructions().count(identifier.name)) + fatalParserError("Cannot use instruction names for identifier names."); m_scanner->next(); funAss.variableName = identifier; funAss.value.reset(new Statement(parseExpression())); @@ -130,7 +134,7 @@ assembly::Statement Parser::parseExpression() return operation; } -assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) +std::map<string, dev::solidity::Instruction> const& Parser::instructions() { // Allowed instructions, lowercase names. static map<string, dev::solidity::Instruction> s_instructions; @@ -151,7 +155,11 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) // add alias for selfdestruct s_instructions["selfdestruct"] = solidity::Instruction::SUICIDE; } + return s_instructions; +} +assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) +{ Statement ret; switch (m_scanner->currentToken()) { @@ -170,9 +178,9 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) else literal = m_scanner->currentLiteral(); // first search the set of instructions. - if (s_instructions.count(literal)) + if (instructions().count(literal)) { - dev::solidity::Instruction const& instr = s_instructions[literal]; + dev::solidity::Instruction const& instr = instructions().at(literal); if (_onlySinglePusher) { InstructionInfo info = dev::solidity::instructionInfo(instr); @@ -207,6 +215,8 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration() VariableDeclaration varDecl = createWithLocation<VariableDeclaration>(); expectToken(Token::Let); varDecl.name = m_scanner->currentLiteral(); + if (instructions().count(varDecl.name)) + fatalParserError("Cannot use instruction names for identifier names."); expectToken(Token::Identifier); expectToken(Token::Colon); expectToken(Token::Assign); diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h index 8b56ab90..643548dd 100644 --- a/libsolidity/inlineasm/AsmParser.h +++ b/libsolidity/inlineasm/AsmParser.h @@ -64,6 +64,7 @@ protected: Statement parseStatement(); /// Parses a functional expression that has to push exactly one stack element Statement parseExpression(); + std::map<std::string, dev::solidity::Instruction> const& instructions(); Statement parseElementaryOperation(bool _onlySinglePusher = false); VariableDeclaration parseVariableDeclaration(); FunctionalInstruction parseFunctionalInstruction(Statement&& _instruction); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index b26bd501..3335c40e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -726,10 +726,15 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const solAssert(s.second.scanner, "Scanner not available"); meta["sources"][s.first]["keccak256"] = "0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes()); - meta["sources"][s.first]["urls"] = Json::arrayValue; - meta["sources"][s.first]["urls"].append( - "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()) - ); + if (m_metadataLiteralSources) + meta["sources"][s.first]["content"] = s.second.scanner->source(); + else + { + meta["sources"][s.first]["urls"] = Json::arrayValue; + meta["sources"][s.first]["urls"].append( + "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()) + ); + } } meta["settings"]["optimizer"]["enabled"] = m_optimize; meta["settings"]["optimizer"]["runs"] = m_optimizeRuns; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 61edc284..9ee70215 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -177,6 +177,7 @@ public: /// Can be one of 4 types defined at @c DocumentationType Json::Value const& metadata(std::string const& _contractName, DocumentationType _type) const; std::string const& onChainMetadata(std::string const& _contractName) const; + void useMetadataLiteralSources(bool _metadataLiteralSources) { m_metadataLiteralSources = _metadataLiteralSources; } /// @returns the previously used scanner, useful for counting lines during error reporting. Scanner const& scanner(std::string const& _sourceName = "") const; @@ -274,6 +275,7 @@ private: std::map<std::string const, Contract> m_contracts; std::string m_formalTranslation; ErrorList m_errors; + bool m_metadataLiteralSources = false; }; } |