From 5c8a6aac698f6d084a22c6ec9f282b3f26ddb8bb Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 16 Mar 2018 16:06:40 +0100 Subject: Prevent encoding of weird types and support packed encoding of external function types. --- libsolidity/analysis/TypeChecker.cpp | 11 +++++++++++ libsolidity/ast/Types.cpp | 2 ++ libsolidity/ast/Types.h | 11 ++++++++--- libsolidity/codegen/CompilerUtils.cpp | 1 - 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'libsolidity') diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 6e287f83..620dfca4 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1644,9 +1644,20 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) auto const& argType = type(*arguments[i]); if (functionType->takesArbitraryParameters()) { + bool errored = false; if (auto t = dynamic_cast(argType.get())) if (!t->mobileType()) + { m_errorReporter.typeError(arguments[i]->location(), "Invalid rational number (too large or division by zero)."); + errored = true; + } + if (!errored && !( + argType->mobileType() && + argType->mobileType()->interfaceType(false) && + argType->mobileType()->interfaceType(false)->encodingType() && + !(dynamic_cast(argType->mobileType()->interfaceType(false)->encodingType().get())) + )) + m_errorReporter.typeError(arguments[i]->location(), "This type cannot be encoded."); } else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i])) m_errorReporter.typeError( diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 720215c9..4c462d09 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1262,6 +1262,8 @@ bool ContractType::isPayable() const TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const { + if (isSuper()) + return TypePointer{}; return _operator == Token::Delete ? make_shared() : TypePointer(); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index c930dd24..b7e64891 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -692,22 +692,27 @@ public: virtual bool operator==(Type const& _other) const override; virtual unsigned calldataEncodedSize(bool _padded ) const override { + solAssert(!isSuper(), ""); return encodingType()->calldataEncodedSize(_padded); } - virtual unsigned storageBytes() const override { return 20; } - virtual bool canLiveOutsideStorage() const override { return true; } + virtual unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; } + virtual bool canLiveOutsideStorage() const override { return !isSuper(); } virtual unsigned sizeOnStack() const override { return m_super ? 0 : 1; } - virtual bool isValueType() const override { return true; } + virtual bool isValueType() const override { return !isSuper(); } virtual std::string toString(bool _short) const override; virtual std::string canonicalName() const override; virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override; virtual TypePointer encodingType() const override { + if (isSuper()) + return TypePointer{}; return std::make_shared(160, IntegerType::Modifier::Address); } virtual TypePointer interfaceType(bool _inLibrary) const override { + if (isSuper()) + return TypePointer{}; return _inLibrary ? shared_from_this() : encodingType(); } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 68f0b3a1..676d5d4e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -142,7 +142,6 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound dynamic_cast(_type).kind() == FunctionType::Kind::External ) { - solUnimplementedAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); combineExternalFunctionType(true); m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; -- cgit v1.2.3