aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/types.rst2
-rw-r--r--libdevcore/UTF8.cpp2
-rw-r--r--libsolidity/parsing/Parser.cpp35
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp10
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"(