Disallow packed encoding of literals.

This commit is contained in:
chriseth 2018-06-29 17:41:59 +02:00
parent 4649f9202a
commit f7a9c4203e
6 changed files with 20 additions and 32 deletions

View File

@ -27,6 +27,7 @@ Breaking Changes:
* Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence. * Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence.
* Parser: Disallow trailing dots that are not followed by a number. * Parser: Disallow trailing dots that are not followed by a number.
* Type Checker: Disallow arithmetic operations for boolean variables. * Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``. * Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
* Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible. * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.

View File

@ -1702,8 +1702,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
else else
_functionCall.annotation().type = make_shared<TupleType>(returnTypes); _functionCall.annotation().type = make_shared<TupleType>(returnTypes);
bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression())) if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression()))
{ {
if (functionName->name() == "sha3" && functionType->kind() == FunctionType::Kind::SHA3) if (functionName->name() == "sha3" && functionType->kind() == FunctionType::Kind::SHA3)
@ -1723,23 +1721,15 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
auto const& argType = type(*arguments[i]); auto const& argType = type(*arguments[i]);
if (auto literal = dynamic_cast<RationalNumberType const*>(argType.get())) if (auto literal = dynamic_cast<RationalNumberType const*>(argType.get()))
{ {
/* If no mobile type is available an error will be raised elsewhere. */
if (literal->mobileType()) if (literal->mobileType())
m_errorReporter.typeError(
arguments[i]->location(),
"Cannot perform packed encoding for a literal. Please convert it to an explicit type first."
);
else
{ {
if (v050) /* If no mobile type is available an error will be raised elsewhere. */
m_errorReporter.typeError( solAssert(m_errorReporter.hasErrors(), "");
arguments[i]->location(),
"Cannot perform packed encoding for a literal. Please convert it to an explicit type first."
);
else
m_errorReporter.warning(
arguments[i]->location(),
"The type of \"" +
argType->toString() +
"\" was inferred as " +
literal->mobileType()->toString() +
". This is probably not desired. Use an explicit type to silence this warning."
);
} }
} }
} }

View File

@ -92,6 +92,12 @@ public:
void clear(); void clear();
/// @returns true iff there is any error (ignores warnings).
bool hasErrors() const
{
return m_errorCount > 0;
}
private: private:
void error(Error::Type _type, void error(Error::Type _type,
SourceLocation const& _location, SourceLocation const& _location,

View File

@ -2082,7 +2082,7 @@ BOOST_AUTO_TEST_CASE(packed_keccak256)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
uint24 b = 65536; uint24 b = 65536;
uint c = 256; uint c = 256;
return keccak256(abi.encodePacked(8, input, b, input, c)); return keccak256(abi.encodePacked(uint8(8), input, b, input, c));
} }
} }
)"; )";
@ -2134,7 +2134,7 @@ BOOST_AUTO_TEST_CASE(packed_sha256)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
uint24 b = 65536; uint24 b = 65536;
uint c = 256; uint c = 256;
return sha256(abi.encodePacked(8, input, b, input, c)); return sha256(abi.encodePacked(uint8(8), input, b, input, c));
} }
} }
)"; )";
@ -2161,7 +2161,7 @@ BOOST_AUTO_TEST_CASE(packed_ripemd160)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
uint24 b = 65536; uint24 b = 65536;
uint c = 256; uint c = 256;
return ripemd160(abi.encodePacked(8, input, b, input, c)); return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));
} }
} }
)"; )";
@ -3578,7 +3578,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_numeric_literals)
contract c { contract c {
function foo(uint a, uint16 b) returns (bytes32 d) function foo(uint a, uint16 b) returns (bytes32 d)
{ {
d = keccak256(abi.encodePacked(a, b, 145)); d = keccak256(abi.encodePacked(a, b, uint8(145)));
} }
} }
)"; )";
@ -3603,7 +3603,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_string_literals)
} }
function bar(uint a, uint16 b) returns (bytes32 d) function bar(uint a, uint16 b) returns (bytes32 d)
{ {
d = keccak256(abi.encodePacked(a, b, 145, "foo")); d = keccak256(abi.encodePacked(a, b, uint8(145), "foo"));
} }
} }
)"; )";

View File

@ -5,4 +5,4 @@ contract C {
} }
// ---- // ----
// Warning: (92-93): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning. // TypeError: (92-93): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.

View File

@ -1,9 +0,0 @@
pragma experimental "v0.5.0";
contract C {
function k() pure public returns (bytes) {
return abi.encodePacked(1);
}
}
// ----
// TypeError: (122-123): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.