diff options
author | chriseth <chris@ethereum.org> | 2017-08-21 22:34:59 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 22:34:59 +0800 |
commit | 01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa (patch) | |
tree | 577b2d76fbc0388954f69b750a50796f2ba17b63 | |
parent | fe25bcf350bfb65ddb69bc5e7d3f65dfa6d23fa7 (diff) | |
parent | 1be713acc7abc2f1d21d962e840b1e369d1d8ff6 (diff) | |
download | dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar.gz dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar.bz2 dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar.lz dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar.xz dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.tar.zst dexon-solidity-01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa.zip |
Merge branch 'develop' into library-constructor
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/grammar.txt | 7 | ||||
-rw-r--r-- | docs/types.rst | 2 | ||||
-rw-r--r-- | docs/utils/SolidityLexer.py | 4 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 21 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.h | 2 | ||||
-rw-r--r-- | test/libjulia/Parser.cpp | 8 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 8 |
8 files changed, 47 insertions, 6 deletions
diff --git a/Changelog.md b/Changelog.md index f1046032..49d92eb5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Features: * Type Checker: Warn about shifting a literal. Bugfixes: + * Assembly Parser: Be more strict about number literals. * Parser: Enforce commas between array and tuple elements. * Parser: Limit maximum recursion depth. * Type Checker: Disallow constructors in libraries. diff --git a/docs/grammar.txt b/docs/grammar.txt index a9838ccb..76827a77 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -16,7 +16,7 @@ ContractPart = StateVariableDeclaration | UsingForDeclaration InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* ')' )? -StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' )? Identifier ('=' Expression)? ';' +StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';' UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';' StructDefinition = 'struct' Identifier '{' ( VariableDeclaration ';' (VariableDeclaration ';')* )? '}' @@ -25,7 +25,7 @@ ModifierDefinition = 'modifier' Identifier ParameterList? Block ModifierInvocation = Identifier ( '(' ExpressionList? ')' )? FunctionDefinition = 'function' Identifier? ParameterList - ( ModifierInvocation | 'constant' | 'payable' | 'external' | 'public' | 'internal' | 'private' )* + ( ModifierInvocation | StateMutability | 'external' | 'public' | 'internal' | 'private' )* ( 'returns' ParameterList )? ( ';' | Block ) EventDefinition = 'event' Identifier IndexedParameterList 'anonymous'? ';' @@ -50,9 +50,10 @@ UserDefinedTypeName = Identifier ( '.' Identifier )* Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')' ArrayTypeName = TypeName '[' Expression? ']' -FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | 'constant' | 'payable' )* +FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | StateMutability )* ( 'returns' TypeNameList )? StorageLocation = 'memory' | 'storage' +StateMutability = 'constant' | 'payable' Block = '{' Statement* '}' Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement | diff --git a/docs/types.rst b/docs/types.rst index abf8bb17..13c848c2 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -337,7 +337,7 @@ be passed via and returned from external function calls. Function types are notated as follows:: - function (<parameter types>) {internal|external} [constant] [payable] [returns (<return types>)] + function (<parameter types>) {internal|external} [constant|payable] [returns (<return types>)] In contrast to the parameter types, the return types cannot be empty - if the function type should not return anything, the whole ``returns (<return types>)`` diff --git a/docs/utils/SolidityLexer.py b/docs/utils/SolidityLexer.py index ef55c6a2..a828146f 100644 --- a/docs/utils/SolidityLexer.py +++ b/docs/utils/SolidityLexer.py @@ -57,7 +57,7 @@ class SolidityLexer(RegexLexer): (r'(anonymous|as|assembly|break|constant|continue|do|delete|else|external|for|hex|if|' r'indexed|internal|import|is|mapping|memory|new|payable|public|pragma|' r'private|return|returns|storage|super|this|throw|using|while)\b', Keyword, 'slashstartsregex'), - (r'(var|function|event|modifier|struct|enum|contract|library)\b', Keyword.Declaration, 'slashstartsregex'), + (r'(var|function|event|modifier|struct|enum|contract|library|interface)\b', Keyword.Declaration, 'slashstartsregex'), (r'(bytes|string|address|uint|int|bool|byte|' + '|'.join( ['uint%d' % (i + 8) for i in range(0, 256, 8)] + @@ -71,7 +71,7 @@ class SolidityLexer(RegexLexer): r'null|of|pure|relocatable|static|switch|try|type|typeof|view)\b', Keyword.Reserved), (r'(true|false)\b', Keyword.Constant), (r'(block|msg|tx|now|suicide|selfdestruct|addmod|mulmod|sha3|keccak256|log[0-4]|' - r'sha256|ecrecover|ripemd160|assert|revert)', Name.Builtin), + r'sha256|ecrecover|ripemd160|assert|revert|require)', Name.Builtin), (r'[$a-zA-Z_][a-zA-Z0-9_]*', Name.Other), (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), (r'0x[0-9a-fA-F]+', Number.Hex), diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 133f70b1..1dcc42b8 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -23,6 +23,9 @@ #include <libsolidity/inlineasm/AsmParser.h> #include <libsolidity/parsing/Scanner.h> #include <libsolidity/interface/ErrorReporter.h> + +#include <boost/algorithm/string.hpp> + #include <ctype.h> #include <algorithm> @@ -297,6 +300,8 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) kind = LiteralKind::String; break; case Token::Number: + if (!isValidNumberLiteral(currentLiteral())) + fatalParserError("Invalid number literal."); kind = LiteralKind::Number; break; case Token::TrueLiteral: @@ -501,3 +506,19 @@ string Parser::expectAsmIdentifier() expectToken(Token::Identifier); return name; } + +bool Parser::isValidNumberLiteral(string const& _literal) +{ + try + { + u256(_literal); + } + catch (...) + { + return false; + } + if (boost::starts_with(_literal, "0x")) + return true; + else + return _literal.find_first_not_of("0123456789") == string::npos; +} diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h index 45708afd..a48a3393 100644 --- a/libsolidity/inlineasm/AsmParser.h +++ b/libsolidity/inlineasm/AsmParser.h @@ -75,6 +75,8 @@ protected: TypedName parseTypedName(); std::string expectAsmIdentifier(); + static bool isValidNumberLiteral(std::string const& _literal); + private: bool m_julia = false; }; diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp index dd6f3d94..e1bf5a3a 100644 --- a/test/libjulia/Parser.cpp +++ b/test/libjulia/Parser.cpp @@ -214,6 +214,14 @@ BOOST_AUTO_TEST_CASE(invalid_types) CHECK_ERROR("{ function f(a:invalid) {} }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported)."); } +BOOST_AUTO_TEST_CASE(number_literals) +{ + BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }")); + CHECK_ERROR("{ let x:u256 := .1:u256 }", ParserError, "Invalid number literal."); + CHECK_ERROR("{ let x:u256 := 1e5:u256 }", ParserError, "Invalid number literal."); + CHECK_ERROR("{ let x:u256 := 67.235:u256 }", ParserError, "Invalid number literal."); +} + BOOST_AUTO_TEST_CASE(builtin_types) { BOOST_CHECK(successParse("{ let x:bool := true:bool }")); diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 4bf4eb48..8e1c304a 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -339,6 +339,14 @@ BOOST_AUTO_TEST_CASE(blocks) BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }")); } +BOOST_AUTO_TEST_CASE(number_literals) +{ + BOOST_CHECK(successParse("{ let x := 1 }")); + CHECK_PARSE_ERROR("{ let x := .1 }", ParserError, "Invalid number literal."); + CHECK_PARSE_ERROR("{ let x := 1e5 }", ParserError, "Invalid number literal."); + CHECK_PARSE_ERROR("{ let x := 67.235 }", ParserError, "Invalid number literal."); +} + BOOST_AUTO_TEST_CASE(function_definitions) { BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }")); |