Fixes large rational number literals being wrongly interpreted.

Fixes #5052.
This commit is contained in:
Christian Parpart 2018-10-02 15:31:55 +02:00 committed by chriseth
parent 547b26d464
commit 4d5216c2e0
3 changed files with 21 additions and 9 deletions

View File

@ -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())

View File

@ -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;
}
}
// ----

View File

@ -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.