Merge pull request #1439 from ethereum/utf

Disallow conversion of string literal into strings when the literal is not a valid UTF-8
This commit is contained in:
chriseth 2016-11-25 15:59:35 +01:00 committed by GitHub
commit 721b6a9696
5 changed files with 36 additions and 2 deletions

View File

@ -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) ### 0.4.6 (2016-11-22)
Bugfixes: Bugfixes:

View File

@ -29,7 +29,7 @@ namespace dev
{ {
/// Validate an input for UTF8 encoding /// 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); bool validate(std::string const& _input, size_t& _invalidPosition);
} }

View File

@ -879,7 +879,8 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
else if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo)) else if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo))
return return
arrayType->isByteArray() && arrayType->isByteArray() &&
!(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()); !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()) &&
!(arrayType->isString() && !isValidUTF8());
else else
return false; return false;
} }
@ -906,6 +907,12 @@ TypePointer StringLiteralType::mobileType() const
return make_shared<ArrayType>(DataLocation::Memory, true); 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) shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
{ {
if (_literal.length() <= 32) if (_literal.length() <= 32)

View File

@ -425,6 +425,8 @@ public:
virtual std::string toString(bool) const override; virtual std::string toString(bool) const override;
virtual TypePointer mobileType() const override; virtual TypePointer mobileType() const override;
bool isValidUTF8() const;
std::string const& value() const { return m_value; } std::string const& value() const { return m_value; }
private: private:

View File

@ -2038,6 +2038,26 @@ BOOST_AUTO_TEST_CASE(string)
BOOST_CHECK_NO_THROW(parseAndAnalyse(sourceCode)); 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) BOOST_AUTO_TEST_CASE(string_index)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(