aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-08-21 22:34:59 +0800
committerGitHub <noreply@github.com>2017-08-21 22:34:59 +0800
commit01b4bba0ed7544ed6f54f97dd5d5a3b0d397fbfa (patch)
tree577b2d76fbc0388954f69b750a50796f2ba17b63
parentfe25bcf350bfb65ddb69bc5e7d3f65dfa6d23fa7 (diff)
parent1be713acc7abc2f1d21d962e840b1e369d1d8ff6 (diff)
downloaddexon-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.md1
-rw-r--r--docs/grammar.txt7
-rw-r--r--docs/types.rst2
-rw-r--r--docs/utils/SolidityLexer.py4
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp21
-rw-r--r--libsolidity/inlineasm/AsmParser.h2
-rw-r--r--test/libjulia/Parser.cpp8
-rw-r--r--test/libsolidity/InlineAssembly.cpp8
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 { } }"));