aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md5
-rw-r--r--libdevcore/UTF8.h2
-rw-r--r--libsolidity/ast/Types.cpp9
-rw-r--r--libsolidity/ast/Types.h2
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp20
5 files changed, 36 insertions, 2 deletions
diff --git a/Changelog.md b/Changelog.md
index 468518d2..0b10cd0c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,8 @@
+### 0.4.7 (unreleased)
+
+Bugfixes:
+ * Type checker: string literals that are not valid UTF-8 cannot be converted to string type
+
### 0.4.6 (2016-11-22)
Bugfixes:
diff --git a/libdevcore/UTF8.h b/libdevcore/UTF8.h
index 3e39273c..9bdc2b4f 100644
--- a/libdevcore/UTF8.h
+++ b/libdevcore/UTF8.h
@@ -29,7 +29,7 @@ namespace dev
{
/// Validate an input for UTF8 encoding
-/// @returns true if it is invalid and the first invalid position in invalidPosition
+/// @returns false if it is invalid and the first invalid position in invalidPosition
bool validate(std::string const& _input, size_t& _invalidPosition);
}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index b7de3646..b22f3c08 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -879,7 +879,8 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
else if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo))
return
arrayType->isByteArray() &&
- !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer());
+ !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()) &&
+ !(arrayType->isString() && !isValidUTF8());
else
return false;
}
@@ -906,6 +907,12 @@ TypePointer StringLiteralType::mobileType() const
return make_shared<ArrayType>(DataLocation::Memory, true);
}
+bool StringLiteralType::isValidUTF8() const
+{
+ size_t dontCare {};
+ return dev::validate(m_value, dontCare);
+}
+
shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
{
if (_literal.length() <= 32)
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index b713a7c0..72640a1c 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -425,6 +425,8 @@ public:
virtual std::string toString(bool) const override;
virtual TypePointer mobileType() const override;
+ bool isValidUTF8() const;
+
std::string const& value() const { return m_value; }
private:
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 6dc7ac8c..7a132068 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2038,6 +2038,26 @@ BOOST_AUTO_TEST_CASE(string)
BOOST_CHECK_NO_THROW(parseAndAnalyse(sourceCode));
}
+BOOST_AUTO_TEST_CASE(invalid_utf8_implicit)
+{
+ char const* sourceCode = R"(
+ contract C {
+ string s = "\xa0\x00";
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "invalid UTF-8");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_utf8_explicit)
+{
+ char const* sourceCode = R"(
+ contract C {
+ string s = string("\xa0\x00");
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed");
+}
+
BOOST_AUTO_TEST_CASE(string_index)
{
char const* sourceCode = R"(