aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Parpart <christian@parpart.family>2018-10-02 21:31:55 +0800
committerchriseth <chris@ethereum.org>2018-10-09 20:36:49 +0800
commit4d5216c2e0bdfb1b0098451215a2e7d12f65055f (patch)
tree7c30e72285882fe5a0e4ff62efbde280c9f6b612
parent547b26d46462663b49631d55cf32dc10094eb4d4 (diff)
downloaddexon-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.cpp12
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_huge.sol10
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_huge_fail.sol8
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.