diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 3ea9caa7d..798092fcd 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -210,6 +210,8 @@ TypePointer Type::forLiteral(Literal const& _literal) case Token::FalseLiteral: return make_shared(); case Token::Number: + if (!IntegerConstantType::isValidLiteral(_literal)) + return TypePointer(); return make_shared(_literal); case Token::StringLiteral: return make_shared(_literal); @@ -321,6 +323,19 @@ const MemberList IntegerType::AddressMemberList({ {"send", make_shared(strings{"uint"}, strings{"bool"}, FunctionType::Location::Send)} }); +bool IntegerConstantType::isValidLiteral(const Literal& _literal) +{ + try + { + bigint x(_literal.getValue()); + } + catch (...) + { + return false; + } + return true; +} + IntegerConstantType::IntegerConstantType(Literal const& _literal) { m_value = bigint(_literal.getValue()); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index e17a262c6..8af5b2dc5 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -286,6 +286,9 @@ class IntegerConstantType: public Type public: virtual Category getCategory() const override { return Category::IntegerConstant; } + /// @returns true if the literal is a valid integer. + static bool isValidLiteral(Literal const& _literal); + explicit IntegerConstantType(Literal const& _literal); explicit IntegerConstantType(bigint _value): m_value(_value) {} diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 1e40ee4f6..0f5e4800f 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2110,6 +2110,30 @@ BOOST_AUTO_TEST_CASE(literal_strings) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(invalid_integer_literal_fraction) +{ + char const* text = R"( + contract Foo { + function f() { + var x = 1.20; + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp) +{ + char const* text = R"( + contract Foo { + function f() { + var x = 1e2; + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() }