From 168f64f4cb55a7055261a4c66ca54f496e96b503 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 23 Jun 2017 17:20:07 +0200 Subject: Fix negative stack size checks. --- libsolidity/codegen/ContractCompiler.cpp | 10 ++++++++++ libsolidity/codegen/ExpressionCompiler.cpp | 1 + 2 files changed, 11 insertions(+) (limited to 'libsolidity') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 977a2c7c..61a90050 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -267,12 +267,16 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac m_context << notFound; if (fallback) { + m_context.setStackOffset(0); if (!fallback->isPayable()) appendCallValueCheck(); eth::AssemblyItem returnTag = m_context.pushNewTag(); fallback->accept(*this); m_context << returnTag; + m_context.adjustStackOffset( + CompilerUtils(m_context).sizeOnStack(FunctionType(*fallback).returnParameterTypes()) - 1 + ); appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes(), _contract.isLibrary()); } else @@ -285,6 +289,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac CompilerContext::LocationSetter locationSetter(m_context, functionType->declaration()); m_context << callDataUnpackerEntryPoints.at(it.first); + m_context.setStackOffset(0); // We have to allow this for libraries, because value of the previous // call is still visible in the delegatecall. if (!functionType->isPayable() && !_contract.isLibrary()) @@ -295,6 +300,11 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac appendCalldataUnpacker(functionType->parameterTypes()); m_context.appendJumpTo(m_context.functionEntryLabel(functionType->declaration())); m_context << returnTag; + m_context.adjustStackOffset( + CompilerUtils(m_context).sizeOnStack(functionType->returnParameterTypes()) - + CompilerUtils(m_context).sizeOnStack(functionType->parameterTypes()) - + 1 + ); appendReturnValuePacker(functionType->returnParameterTypes(), _contract.isLibrary()); } } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index a65549fd..9d4024c9 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -88,6 +88,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& FunctionType accessorType(_varDecl); TypePointers paramTypes = accessorType.parameterTypes(); + m_context.adjustStackOffset(1 + CompilerUtils::sizeOnStack(paramTypes)); // retrieve the position of the variable auto const& location = m_context.storageLocationOfVariable(_varDecl); -- cgit From ef9a7b2144993e097da6bde7675abd5651bf64cc Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 27 Jun 2017 14:29:04 +0200 Subject: Stack adjustment and code generation for fallback function. This assumes that the fallback function does not have return parameters. --- libsolidity/codegen/ContractCompiler.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'libsolidity') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 61a90050..b6352b39 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -271,13 +271,15 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac if (!fallback->isPayable()) appendCallValueCheck(); + // Return tag is used to jump out of the function. eth::AssemblyItem returnTag = m_context.pushNewTag(); fallback->accept(*this); m_context << returnTag; - m_context.adjustStackOffset( - CompilerUtils(m_context).sizeOnStack(FunctionType(*fallback).returnParameterTypes()) - 1 - ); - appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes(), _contract.isLibrary()); + solAssert(FunctionType(*fallback).parameterTypes().empty(), ""); + solAssert(FunctionType(*fallback).returnParameterTypes().empty(), ""); + // Return tag gets consumed. + m_context.adjustStackOffset(-1); + m_context << Instruction::STOP; } else m_context.appendRevert(); -- cgit From 6a708b0cfe245499f85f7260f7267b399c9a7fcb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 28 Jun 2017 16:55:20 +0100 Subject: Document appendFunctionSelector --- libsolidity/codegen/ContractCompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libsolidity') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index b6352b39..74b07d4d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -297,16 +297,20 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac if (!functionType->isPayable() && !_contract.isLibrary()) appendCallValueCheck(); + // Return tag is used to jump out of the function. eth::AssemblyItem returnTag = m_context.pushNewTag(); + // Parameter for calldataUnpacker m_context << CompilerUtils::dataStartOffset; appendCalldataUnpacker(functionType->parameterTypes()); m_context.appendJumpTo(m_context.functionEntryLabel(functionType->declaration())); m_context << returnTag; + // Return tag and input parameters get consumed. m_context.adjustStackOffset( CompilerUtils(m_context).sizeOnStack(functionType->returnParameterTypes()) - CompilerUtils(m_context).sizeOnStack(functionType->parameterTypes()) - 1 ); + // Consumes the return parameters. appendReturnValuePacker(functionType->returnParameterTypes(), _contract.isLibrary()); } } -- cgit