diff options
author | Christian Parpart <christian@parpart.family> | 2018-10-02 21:31:55 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-10-09 20:36:49 +0800 |
commit | 4d5216c2e0bdfb1b0098451215a2e7d12f65055f (patch) | |
tree | 7c30e72285882fe5a0e4ff62efbde280c9f6b612 | |
parent | 547b26d46462663b49631d55cf32dc10094eb4d4 (diff) | |
download | dexon-solidity-4d5216c2e0bdfb1b0098451215a2e7d12f65055f.tar.gz dexon-solidity-4d5216c2e0bdfb1b0098451215a2e7d12f65055f.tar.zst dexon-solidity-4d5216c2e0bdfb1b0098451215a2e7d12f65055f.zip |
Fixes large rational number literals being wrongly interpreted.
Fixes #5052.
-rw-r--r-- | libsolidity/ast/Types.cpp | 12 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/types/rational_number_huge.sol | 10 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/types/rational_number_huge_fail.sol | 8 |
3 files changed, 21 insertions, 9 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index e45fc81d..195b2e2d 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -841,13 +841,8 @@ TypePointer RationalNumberType::forLiteral(Literal const& _literal) TypePointer compatibleBytesType; if (_literal.isHexNumber()) { - size_t digitCount = count_if( - _literal.value().begin() + 2, // skip "0x" - _literal.value().end(), - [](unsigned char _c) -> bool { return isxdigit(_c); } - ); - // require even number of digits - if (!(digitCount & 1)) + size_t const digitCount = _literal.valueWithoutUnderscores().length() - 2; + if (digitCount % 2 == 0 && (digitCount / 2) <= 32) compatibleBytesType = make_shared<FixedBytesType>(digitCount / 2); } @@ -861,8 +856,7 @@ tuple<bool, rational> RationalNumberType::isValidLiteral(Literal const& _literal rational value; try { - ASTString valueString = _literal.value(); - boost::erase_all(valueString, "_");// Remove underscore separators + ASTString valueString = _literal.valueWithoutUnderscores(); auto expPoint = find(valueString.begin(), valueString.end(), 'e'); if (expPoint == valueString.end()) diff --git a/test/libsolidity/syntaxTests/types/rational_number_huge.sol b/test/libsolidity/syntaxTests/types/rational_number_huge.sol new file mode 100644 index 00000000..378de201 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/rational_number_huge.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint y) public pure { + // fits FixedBytes with exactly 32-bytes + y = 0xffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000; // FixedBytes (32) + + // fits exactly into FixedBytes (32), ensures underscored literals won't hurt + y = 0xffffffff00000000ffffffff00000000ffffffff00000000ffffffff_00000000; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/rational_number_huge_fail.sol b/test/libsolidity/syntaxTests/types/rational_number_huge_fail.sol new file mode 100644 index 00000000..08e50656 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/rational_number_huge_fail.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint y) public pure { + // one byte too long for storing in Fixedbytes (would require 33 bytes) + y = 0xffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001; + } +} +// ---- +// TypeError: (142-209): Type int_const 1852...(71 digits omitted)...7281 is not implicitly convertible to expected type uint256. |