diff options
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/types.rst | 2 | ||||
-rw-r--r-- | libdevcore/UTF8.cpp | 2 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 35 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 10 |
5 files changed, 35 insertions, 15 deletions
diff --git a/Changelog.md b/Changelog.md index bed7d09f..0fb2fe5c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Features: * Inline Assembly: function definitions and function calls. Bugfixes: + * Type Checker: Make UTF8-validation a bit more sloppy to include more valid sequences. * Fixed crash concerning non-callable types. * Unused variable warnings no longer issued for variables used inside inline assembly. * Inline Assembly: Enforce function arguments when parsing functional instructions. diff --git a/docs/types.rst b/docs/types.rst index b2175262..0a0bffea 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -54,7 +54,7 @@ Operators: * Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation) * Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation), ``<<`` (left shift), ``>>`` (right shift) -Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both +Division always truncates (it just is compiled to the DIV opcode of the EVM), but it does not truncate if both operators are :ref:`literals<rational_literals>` (or literal expressions). Division by zero and modulus with zero throws a runtime exception. diff --git a/libdevcore/UTF8.cpp b/libdevcore/UTF8.cpp index 9fbf4b45..449ccc5d 100644 --- a/libdevcore/UTF8.cpp +++ b/libdevcore/UTF8.cpp @@ -40,7 +40,7 @@ bool validateUTF8(std::string const& _input, size_t& _invalidPosition) continue; size_t count = 0; - switch(_input[i] & 0xe0) { + switch(_input[i] & 0xf0) { case 0xc0: count = 1; break; case 0xe0: count = 2; break; case 0xf0: count = 3; break; diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 7c439211..88b41f20 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -347,8 +347,12 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN else if (Token::isVisibilitySpecifier(token)) { if (result.visibility != Declaration::Visibility::Default) - fatalParserError(string("Multiple visibility specifiers.")); - result.visibility = parseVisibilitySpecifier(token); + { + parserError(string("Multiple visibility specifiers.")); + m_scanner->next(); + } + else + result.visibility = parseVisibilitySpecifier(token); } else break; @@ -501,8 +505,12 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token)) { if (visibility != Declaration::Visibility::Default) - fatalParserError(string("Visibility already specified.")); - visibility = parseVisibilitySpecifier(token); + { + parserError(string("Visibility already specified.")); + m_scanner->next(); + } + else + visibility = parseVisibilitySpecifier(token); } else { @@ -513,14 +521,15 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token)) { if (location != VariableDeclaration::Location::Default) - fatalParserError(string("Location already specified.")); - if (!type) - fatalParserError(string("Location specifier needs explicit type name.")); - location = ( - token == Token::Memory ? - VariableDeclaration::Location::Memory : - VariableDeclaration::Location::Storage - ); + parserError(string("Location already specified.")); + else if (!type) + parserError(string("Location specifier needs explicit type name.")); + else + location = ( + token == Token::Memory ? + VariableDeclaration::Location::Memory : + VariableDeclaration::Location::Storage + ); } else break; @@ -702,7 +711,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) else if (token == Token::Var) { if (!_allowVar) - fatalParserError(string("Expected explicit type name.")); + parserError(string("Expected explicit type name.")); m_scanner->next(); } else if (token == Token::Function) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 70934543..0b3cb481 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2422,6 +2422,16 @@ BOOST_AUTO_TEST_CASE(invalid_utf8_explicit) CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed"); } +BOOST_AUTO_TEST_CASE(large_utf8_codepoint) +{ + char const* sourceCode = R"( + contract C { + string s = "\xf0\x9f\xa6\x84"; + } + )"; + CHECK_SUCCESS(sourceCode); +} + BOOST_AUTO_TEST_CASE(string_index) { char const* sourceCode = R"( |