From 888909bee79f003a1936e28b4bf4c6fd50d4c124 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 6 Aug 2015 15:33:06 +0200 Subject: [PATCH 1/2] Do not allow boolean operators for integers. Fixes #2496 --- libsolidity/Token.h | 1 + libsolidity/Types.cpp | 2 ++ .../SolidityNameAndTypeResolution.cpp | 16 ++++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 43a5b90b9..7c7b1c7ff 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -366,6 +366,7 @@ public: } static bool isBitOp(Value op) { return (BitOr <= op && op <= SHR) || op == BitNot; } + static bool isBooleanOp(Value op) { return (Or <= op && op <= And) || op == Not; } static bool isUnaryOp(Value op) { return (Not <= op && op <= Delete) || op == Add || op == Sub || op == After; } static bool isCountOp(Value op) { return op == Inc || op == Dec; } static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 744362fb7..3abb0b052 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -311,6 +311,8 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe // All integer types can be compared if (Token::isCompareOp(_operator)) return commonType; + if (Token::isBooleanOp(_operator)) + return TypePointer(); // Nothing else can be done with addresses if (commonType->isAddress()) return TypePointer(); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 6b116f251..e59217bf5 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1883,6 +1883,22 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(integer_boolean_operators) +{ + char const* sourceCode1 = R"( + contract test { function() { uint x = 1; uint y = 2; x || y; } } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode1), TypeError); + char const* sourceCode2 = R"( + contract test { function() { uint x = 1; uint y = 2; x && y; } } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode2), TypeError); + char const* sourceCode3 = R"( + contract test { function() { uint x = 1; !x; } } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode3), TypeError); +} + BOOST_AUTO_TEST_CASE(overwrite_memory_location_external) { char const* sourceCode = R"( From 4661d4773d37d68f1e770758b95b7fa14e303c22 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 6 Aug 2015 15:39:42 +0200 Subject: [PATCH 2/2] Disallow comparison for reference types. Fixes #2690 --- libsolidity/Types.h | 4 ++++ test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/libsolidity/Types.h b/libsolidity/Types.h index bc499d595..c4992cfdf 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -409,6 +409,10 @@ public: DataLocation location() const { return m_location; } virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; + virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override + { + return TypePointer(); + } virtual unsigned memoryHeadSize() const override { return 32; } /// @returns a copy of this type with location (recursively) changed to @a _location, diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index e59217bf5..ba5a5a60f 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1899,6 +1899,18 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode3), TypeError); } +BOOST_AUTO_TEST_CASE(reference_compare_operators) +{ + char const* sourceCode1 = R"( + contract test { bytes a; bytes b; function() { a == b; } } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode1), TypeError); + char const* sourceCode2 = R"( + contract test { struct s {uint a;}; s x; s y; function() { x == y; } } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode2), TypeError); +} + BOOST_AUTO_TEST_CASE(overwrite_memory_location_external) { char const* sourceCode = R"(