aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-07-12 04:56:09 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2017-07-14 04:33:46 +0800
commitcb4875a28b1595f31f1eb2d54464f5c3dfc66115 (patch)
tree2c18481b2d8fbd4d71ee7a5414229381f570a58e /libsolidity/ast
parent63bf0f68e6d232eccf6d64ca2bba5b39e108ea41 (diff)
downloaddexon-solidity-cb4875a28b1595f31f1eb2d54464f5c3dfc66115.tar.gz
dexon-solidity-cb4875a28b1595f31f1eb2d54464f5c3dfc66115.tar.zst
dexon-solidity-cb4875a28b1595f31f1eb2d54464f5c3dfc66115.zip
Issue error properly for oversized arrays for calldata
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/Types.cpp13
-rw-r--r--libsolidity/ast/Types.h5
2 files changed, 17 insertions, 1 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index b54407c6..76bfb1a8 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1395,12 +1395,23 @@ bool ArrayType::operator==(Type const& _other) const
return isDynamicallySized() || length() == other.length();
}
-unsigned ArrayType::calldataEncodedSize(bool _padded) const
+bool ArrayType::validForCalldata() const
+{
+ return unlimitedCalldataEncodedSize(true) <= numeric_limits<unsigned>::max();
+}
+
+bigint ArrayType::unlimitedCalldataEncodedSize(bool _padded) const
{
if (isDynamicallySized())
return 32;
bigint size = bigint(length()) * (isByteArray() ? 1 : baseType()->calldataEncodedSize(_padded));
size = ((size + 31) / 32) * 32;
+ return size;
+}
+
+unsigned ArrayType::calldataEncodedSize(bool _padded) const
+{
+ bigint size = unlimitedCalldataEncodedSize(_padded);
solAssert(size <= numeric_limits<unsigned>::max(), "Array size does not fit unsigned.");
return unsigned(size);
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index bd5da30a..c24cc11a 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -616,6 +616,9 @@ public:
virtual TypePointer interfaceType(bool _inLibrary) const override;
virtual bool canBeUsedExternally(bool _inLibrary) const override;
+ /// @returns true if this is valid to be stored in calldata
+ bool validForCalldata() const;
+
/// @returns true if this is a byte array or a string
bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
/// @returns true if this is a string
@@ -630,6 +633,8 @@ private:
/// String is interpreted as a subtype of Bytes.
enum class ArrayKind { Ordinary, Bytes, String };
+ bigint unlimitedCalldataEncodedSize(bool _padded) const;
+
///< Byte arrays ("bytes") and strings have different semantics from ordinary arrays.
ArrayKind m_arrayKind = ArrayKind::Ordinary;
TypePointer m_baseType;