diff options
author | chriseth <chris@ethereum.org> | 2018-10-16 23:58:17 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-10-22 21:52:26 +0800 |
commit | 19be6cd818e4bb1a49325d8bfea7f7727d85c933 (patch) | |
tree | fae4f0c8bb4ca4c32ede677466a6a8cfc2965fee | |
parent | c13b5280c1b44f18a2a1fb61ef5556e91c5678e7 (diff) | |
download | dexon-solidity-19be6cd818e4bb1a49325d8bfea7f7727d85c933.tar.gz dexon-solidity-19be6cd818e4bb1a49325d8bfea7f7727d85c933.tar.zst dexon-solidity-19be6cd818e4bb1a49325d8bfea7f7727d85c933.zip |
Some well-formedness checks for the Yul AST.
-rw-r--r-- | libdevcore/CommonData.cpp | 23 | ||||
-rw-r--r-- | libdevcore/CommonData.h | 3 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmPrinter.cpp | 27 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmPrinter.h | 1 | ||||
-rw-r--r-- | libyul/optimiser/SimplificationRules.cpp | 1 |
5 files changed, 51 insertions, 4 deletions
diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 6d7c74d7..fa1a5353 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -110,3 +110,26 @@ string dev::getChecksummedAddress(string const& _addr) } return ret; } + +bool dev::isValidHex(string const& _string) +{ + if (_string.substr(0, 2) != "0x") + return false; + if (_string.find_first_not_of("0123456789abcdefABCDEF", 2) != string::npos) + return false; + return true; +} + +bool dev::isValidDecimal(string const& _string) +{ + if (_string.empty()) + return false; + if (_string == "0") + return true; + // No leading zeros + if (_string.front() == '0') + return false; + if (_string.find_first_not_of("0123456789") != string::npos) + return false; + return true; +} diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index f208c425..0782fabc 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -272,4 +272,7 @@ bool passesAddressChecksum(std::string const& _str, bool _strict); /// @param hex strings that look like an address std::string getChecksummedAddress(std::string const& _addr); +bool isValidHex(std::string const& _string); +bool isValidDecimal(std::string const& _string); + } diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp index 1a15d7eb..4b8c9538 100644 --- a/libsolidity/inlineasm/AsmPrinter.cpp +++ b/libsolidity/inlineasm/AsmPrinter.cpp @@ -24,6 +24,8 @@ #include <libsolidity/inlineasm/AsmData.h> #include <libsolidity/interface/Exceptions.h> +#include <libdevcore/CommonData.h> + #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/replace.hpp> #include <boost/range/adaptor/transformed.hpp> @@ -41,6 +43,7 @@ using namespace dev::solidity::assembly; string AsmPrinter::operator()(assembly::Instruction const& _instruction) { solAssert(!m_yul, ""); + solAssert(isValidInstruction(_instruction.instruction), "Invalid instruction"); return boost::to_lower_copy(instructionInfo(_instruction.instruction).name); } @@ -49,8 +52,10 @@ string AsmPrinter::operator()(assembly::Literal const& _literal) switch (_literal.kind) { case LiteralKind::Number: + solAssert(isValidDecimal(_literal.value) || isValidHex(_literal.value), "Invalid number literal"); return _literal.value + appendTypeName(_literal.type); case LiteralKind::Boolean: + solAssert(_literal.value == "true" || _literal.value == "false", "Invalid bool literal."); return ((_literal.value == "true") ? "true" : "false") + appendTypeName(_literal.type); case LiteralKind::String: break; @@ -87,18 +92,20 @@ string AsmPrinter::operator()(assembly::Literal const& _literal) string AsmPrinter::operator()(assembly::Identifier const& _identifier) { + solAssert(!_identifier.name.empty(), "Invalid identifier."); return _identifier.name; } string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functionalInstruction) { solAssert(!m_yul, ""); + solAssert(isValidInstruction(_functionalInstruction.instruction), "Invalid instruction"); return boost::to_lower_copy(instructionInfo(_functionalInstruction.instruction).name) + "(" + boost::algorithm::join( _functionalInstruction.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)), - ", " ) + + ", ") + ")"; } @@ -110,12 +117,14 @@ string AsmPrinter::operator()(ExpressionStatement const& _statement) string AsmPrinter::operator()(assembly::Label const& _label) { solAssert(!m_yul, ""); + solAssert(!_label.name.empty(), "Invalid label."); return _label.name + ":"; } string AsmPrinter::operator()(assembly::StackAssignment const& _assignment) { solAssert(!m_yul, ""); + solAssert(!_assignment.variableName.name.empty(), "Invalid variable name."); return "=: " + (*this)(_assignment.variableName); } @@ -133,7 +142,7 @@ string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDecl string out = "let "; out += boost::algorithm::join( _variableDeclaration.variables | boost::adaptors::transformed( - [this](TypedName variable) { return variable.name + appendTypeName(variable.type); } + [this](TypedName argument) { return formatTypedName(argument); } ), ", " ); @@ -147,10 +156,11 @@ string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDecl string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefinition) { + solAssert(!_functionDefinition.name.empty(), "Invalid function name."); string out = "function " + _functionDefinition.name + "("; out += boost::algorithm::join( _functionDefinition.parameters | boost::adaptors::transformed( - [this](TypedName argument) { return argument.name + appendTypeName(argument.type); } + [this](TypedName argument) { return formatTypedName(argument); } ), ", " ); @@ -160,7 +170,7 @@ string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefin out += " -> "; out += boost::algorithm::join( _functionDefinition.returnVariables | boost::adaptors::transformed( - [this](TypedName argument) { return argument.name + appendTypeName(argument.type); } + [this](TypedName argument) { return formatTypedName(argument); } ), ", " ); @@ -181,11 +191,13 @@ string AsmPrinter::operator()(assembly::FunctionCall const& _functionCall) string AsmPrinter::operator()(If const& _if) { + solAssert(_if.condition, "Invalid if condition."); return "if " + boost::apply_visitor(*this, *_if.condition) + "\n" + (*this)(_if.body); } string AsmPrinter::operator()(Switch const& _switch) { + solAssert(_switch.expression, "Invalid expression pointer."); string out = "switch " + boost::apply_visitor(*this, *_switch.expression); for (auto const& _case: _switch.cases) { @@ -200,6 +212,7 @@ string AsmPrinter::operator()(Switch const& _switch) string AsmPrinter::operator()(assembly::ForLoop const& _forLoop) { + solAssert(_forLoop.condition, "Invalid for loop condition."); string out = "for "; out += (*this)(_forLoop.pre); out += "\n"; @@ -223,6 +236,12 @@ string AsmPrinter::operator()(Block const& _block) return "{\n " + body + "\n}"; } +string AsmPrinter::formatTypedName(TypedName _variable) const +{ + solAssert(!_variable.name.empty(), "Invalid variable name."); + return _variable.name + appendTypeName(_variable.type); +} + string AsmPrinter::appendTypeName(std::string const& _type) const { if (m_yul) diff --git a/libsolidity/inlineasm/AsmPrinter.h b/libsolidity/inlineasm/AsmPrinter.h index 9f2b842a..971822bf 100644 --- a/libsolidity/inlineasm/AsmPrinter.h +++ b/libsolidity/inlineasm/AsmPrinter.h @@ -55,6 +55,7 @@ public: std::string operator()(assembly::Block const& _block); private: + std::string formatTypedName(TypedName _variable) const; std::string appendTypeName(std::string const& _type) const; bool m_yul = false; diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 4d0468c7..aca943b0 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -209,6 +209,7 @@ u256 Pattern::d() const { Literal const& literal = boost::get<Literal>(matchGroupValue()); assertThrow(literal.kind == assembly::LiteralKind::Number, OptimizerException, ""); + assertThrow(isValidDecimal(literal.value) || isValidHex(literal.value), OptimizerException, ""); return u256(literal.value); } |