From 626a57826cd46c25f78cc5cf22e828b3a21b419c Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 25 Aug 2015 17:41:23 +0200 Subject: [PATCH 01/14] test --- test/libsolidity/SolidityEndToEndTest.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c56845aa0..43a5043d4 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5262,6 +5262,23 @@ BOOST_AUTO_TEST_CASE(library_stray_values) BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42))); } +BOOST_AUTO_TEST_CASE(array_out_of_bound_access) +{ + char const* sourceCode = R"( + contract c { + uint[4] data; + function set(uint index) returns (bool) { + data[index] = 2; + return true; + } + } + )"; +// compileAndRun(sourceCode, 0, "Test"); +// BOOST_CHECK(callContractFunction("set()", u256(7)) == encodeArgs(false)); +// BOOST_CHECK(callContractFunction("set()", u256(3)) == encodeArgs(true)); + compileRequireThrow(sourceCode); +} + BOOST_AUTO_TEST_SUITE_END() } From b7b16b153b7763237ebd8d5b4db8aad4f4b2f4f2 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Wed, 9 Sep 2015 17:35:27 +0200 Subject: [PATCH 02/14] added compile time check for out of bounds access for ordinary arrays todo: check for dynamicaly sized arrays Conflicts: libsolidity/ExpressionCompiler.cpp --- libsolidity/ExpressionCompiler.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index b22a78dc0..06cccc249 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -821,6 +821,8 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) _indexAccess.baseExpression().accept(*this); Type const& baseType = *_indexAccess.baseExpression().type(); + Type const& indexType = *_indexAccess.indexExpression()->type(); + if (baseType.category() == Type::Category::Mapping) { // stack: storage_base_ref @@ -861,8 +863,20 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) solAssert(_indexAccess.indexExpression(), "Index expression expected."); _indexAccess.indexExpression()->accept(*this); + + // check for dynamically sized arrays should be done after memberAccess visit to have length + if ( + (indexType.category() == Type::Category::IntegerConstant) && + ((arrayType.isDynamicallySized() && arrayType.length()) || !arrayType.isDynamicallySized())) + { + IntegerConstantType const& constant = dynamic_cast(indexType); + if (arrayType.length() < constant.literalValue(nullptr)) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Out of bounds access.")); + } + // stack layout: [] ArrayUtils(m_context).accessIndex(arrayType); + switch (arrayType.location()) { case DataLocation::Storage: From e21632555c1a9df86341d773af88bade4825d674 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 15 Sep 2015 11:40:14 +0200 Subject: [PATCH 03/14] added compile time check for out of bounds access for ordinary arrays todo: check for dynamicaly sized arrays Conflicts: test/libsolidity/SolidityEndToEndTest.cpp --- test/libsolidity/SolidityEndToEndTest.cpp | 78 +++++++++++++++-------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 43a5043d4..73b246640 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1037,12 +1037,9 @@ BOOST_AUTO_TEST_CASE(array_accessor) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data(uint256)", 0) == encodeArgs(8)); - BOOST_CHECK(callContractFunction("data(uint256)", 8) == encodeArgs()); BOOST_CHECK(callContractFunction("dynamicData(uint256)", 2) == encodeArgs(8)); - BOOST_CHECK(callContractFunction("dynamicData(uint256)", 8) == encodeArgs()); BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 1) == encodeArgs(22)); BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 127) == encodeArgs(2)); - BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 128) == encodeArgs()); BOOST_CHECK(callContractFunction("multiple_map(uint256,uint256,uint256)", 2, 1, 2) == encodeArgs(3)); } @@ -1061,9 +1058,7 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data(uint256,uint256)", 2, 2) == encodeArgs(8)); - BOOST_CHECK(callContractFunction("data(uint256, 256)", 2, 8) == encodeArgs()); BOOST_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 2) == encodeArgs(8)); - BOOST_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 8) == encodeArgs()); } BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) @@ -1248,6 +1243,7 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_same_size) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToBytes(bytes4)", "abcd") == encodeArgs("abcd")); } + // fixed bytes to uint conversion tests BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_size) { @@ -1300,6 +1296,7 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_greater_size) BOOST_CHECK(callContractFunction("bytesToUint(bytes4)", string("abcd")) == encodeArgs(u256("0x61626364"))); } + // uint fixed bytes conversion tests BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_size) { @@ -4180,21 +4177,21 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_call_fail) BOOST_CHECK(callContractFunction("test()") == encodeArgs(2)); } -BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) -{ - char const* sourceCode = R"( - contract A { - uint public test = 1; - uint[3] arr; - function A() - { - test = arr[5]; - ++test; - } - } - )"; - BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty()); -} +//BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) +//{ +// char const* sourceCode = R"( +// contract A { +// uint public test = 1; +// uint[3] arr; +// function A() +// { +// test = arr[5]; +// ++test; +// } +// } +// )"; +// BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty()); +//} BOOST_AUTO_TEST_CASE(positive_integers_to_signed) { @@ -5266,19 +5263,48 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access) { char const* sourceCode = R"( contract c { - uint[4] data; - function set(uint index) returns (bool) { - data[index] = 2; + uint[2] dataArray; + function set5th() returns (bool) { + dataArray[5] = 2; return true; } } )"; -// compileAndRun(sourceCode, 0, "Test"); -// BOOST_CHECK(callContractFunction("set()", u256(7)) == encodeArgs(false)); -// BOOST_CHECK(callContractFunction("set()", u256(3)) == encodeArgs(true)); compileRequireThrow(sourceCode); } +//BOOST_AUTO_TEST_CASE(dynamic_array_out_of_bound_access) +//{ +// char const* sourceCode = R"( +// contract c { +// uint[] dataArrayDynamic; +// function set5th() returns (bool) { +// dataArrayDynamic.length = 2; +// dataArrayDynamic[5] = 3; +// return true; +// } +// } +// )"; +// compileRequireThrow(sourceCode); +//} + +//BOOST_AUTO_TEST_CASE(bytes_out_of_bound_access) +//{ +// char const* sourceCode = R"( +// contract c { +// bytes data; +// function write() returns (uint) { +// data.length = 3; +// data[1] = 0x77; +// data[2] = 0x14; + +// data[8] = 3; +// } +// } +// )"; +// compileRequireThrow(sourceCode); +//} + BOOST_AUTO_TEST_SUITE_END() } From ede1f4b153d010cb3d2b4e7182630baa6f241938 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Wed, 9 Sep 2015 17:37:05 +0200 Subject: [PATCH 04/14] Update ExpressionCompiler.cpp Conflicts: libsolidity/ExpressionCompiler.cpp --- libsolidity/ExpressionCompiler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 06cccc249..4e607afdc 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -867,7 +867,8 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) // check for dynamically sized arrays should be done after memberAccess visit to have length if ( (indexType.category() == Type::Category::IntegerConstant) && - ((arrayType.isDynamicallySized() && arrayType.length()) || !arrayType.isDynamicallySized())) + ((arrayType.isDynamicallySized() && arrayType.length()) || !arrayType.isDynamicallySized()) + ) { IntegerConstantType const& constant = dynamic_cast(indexType); if (arrayType.length() < constant.literalValue(nullptr)) From 7dbff2489f1f01d78690188bd0966af454999b26 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 8 Sep 2015 15:26:33 +0200 Subject: [PATCH 05/14] some fixes in tests --- test/libsolidity/SolidityEndToEndTest.cpp | 53 +++-------------------- 1 file changed, 5 insertions(+), 48 deletions(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 73b246640..1ad57fb94 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1037,9 +1037,12 @@ BOOST_AUTO_TEST_CASE(array_accessor) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data(uint256)", 0) == encodeArgs(8)); + BOOST_CHECK(callContractFunction("data(uint256)", 8) == encodeArgs()); BOOST_CHECK(callContractFunction("dynamicData(uint256)", 2) == encodeArgs(8)); + BOOST_CHECK(callContractFunction("dynamicData(uint256)", 8) == encodeArgs()); BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 1) == encodeArgs(22)); BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 127) == encodeArgs(2)); + BOOST_CHECK(callContractFunction("smallTypeData(uint256)", 128) == encodeArgs()); BOOST_CHECK(callContractFunction("multiple_map(uint256,uint256,uint256)", 2, 1, 2) == encodeArgs(3)); } @@ -1058,7 +1061,9 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data(uint256,uint256)", 2, 2) == encodeArgs(8)); + BOOST_CHECK(callContractFunction("data(uint256, 256)", 2, 8) == encodeArgs()); BOOST_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 2) == encodeArgs(8)); + BOOST_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 8) == encodeArgs()); } BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) @@ -4177,22 +4182,6 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_call_fail) BOOST_CHECK(callContractFunction("test()") == encodeArgs(2)); } -//BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) -//{ -// char const* sourceCode = R"( -// contract A { -// uint public test = 1; -// uint[3] arr; -// function A() -// { -// test = arr[5]; -// ++test; -// } -// } -// )"; -// BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty()); -//} - BOOST_AUTO_TEST_CASE(positive_integers_to_signed) { char const* sourceCode = R"( @@ -5273,38 +5262,6 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access) compileRequireThrow(sourceCode); } -//BOOST_AUTO_TEST_CASE(dynamic_array_out_of_bound_access) -//{ -// char const* sourceCode = R"( -// contract c { -// uint[] dataArrayDynamic; -// function set5th() returns (bool) { -// dataArrayDynamic.length = 2; -// dataArrayDynamic[5] = 3; -// return true; -// } -// } -// )"; -// compileRequireThrow(sourceCode); -//} - -//BOOST_AUTO_TEST_CASE(bytes_out_of_bound_access) -//{ -// char const* sourceCode = R"( -// contract c { -// bytes data; -// function write() returns (uint) { -// data.length = 3; -// data[1] = 0x77; -// data[2] = 0x14; - -// data[8] = 3; -// } -// } -// )"; -// compileRequireThrow(sourceCode); -//} - BOOST_AUTO_TEST_SUITE_END() } From e4eb40036b67b17462e28401447fa3db61c9b4cd Mon Sep 17 00:00:00 2001 From: LianaHus Date: Wed, 9 Sep 2015 17:43:01 +0200 Subject: [PATCH 06/14] - changed implementation - style fixes Conflicts: libsolidity/AST.cpp --- libsolidity/AST.cpp | 89 +++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 674f33b77..a77bf0a2c 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -58,11 +58,11 @@ void ContractDefinition::checkTypeRequirements() checkAbstractFunctions(); checkAbstractConstructors(); - FunctionDefinition const* function = constructor(); - if (function && !function->returnParameters().empty()) - BOOST_THROW_EXCEPTION( - function->returnParameterList()->createTypeError("Non-empty \"returns\" directive for constructor.") - ); + FunctionDefinition const* functionDefinition = constructor(); + if (functionDefinition && !functionDefinition->getReturnParameters().empty()) + BOOST_THROW_EXCEPTION(functionDefinition->getReturnParameterList()->createTypeError( + "Non-empty \"returns\" directive for constructor." + )); FunctionDefinition const* fallbackFunction = nullptr; for (ASTPointer const& function: definedFunctions()) @@ -119,8 +119,7 @@ map, FunctionTypePointer> ContractDefinition::interfaceFunctions() for (auto const& it: exportedFunctionList) exportedFunctions.insert(it); - solAssert( - exportedFunctionList.size() == exportedFunctions.size(), + solAssert(exportedFunctionList.size() == exportedFunctions.size(), "Hash collision at Function Definition Hash calculation" ); @@ -178,7 +177,9 @@ void ContractDefinition::checkDuplicateFunctions() const errinfo_sourceLocation(overloads[j]->location()) << errinfo_comment("Function with same name and arguments defined twice.") << errinfo_secondarySourceLocation(SecondarySourceLocation().append( - "Other declaration is here:", overloads[i]->location())) + "Other declaration is here:", overloads[i]->location()) + ) + ); } } @@ -767,8 +768,10 @@ void Return::checkTypeRequirements() if (!m_returnParameters) BOOST_THROW_EXCEPTION(createTypeError("Return arguments not allowed.")); if (m_returnParameters->parameters().size() != 1) - BOOST_THROW_EXCEPTION(createTypeError("Different number of arguments in return statement " - "than in returns declaration.")); + BOOST_THROW_EXCEPTION(createTypeError( + "Different number of arguments in return statement " + "than in returns declaration." + )); // this could later be changed such that the paramaters type is an anonymous struct type, // but for now, we only allow one return parameter m_expression->expectType(*m_returnParameters->parameters().front()->type()); @@ -795,10 +798,14 @@ void Assignment::checkTypeRequirements(TypePointers const*) TypePointer resultType = m_type->binaryOperatorResult(Token::AssignmentToBinaryOp(m_assigmentOperator), m_rightHandSide->type()); if (!resultType || *resultType != *m_type) - BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_assigmentOperator)) + - " not compatible with types " + - m_type->toString() + " and " + - m_rightHandSide->type()->toString())); + BOOST_THROW_EXCEPTION(createTypeError( + "Operator " + + string(Token::toString(m_assigmentOperator)) + + " not compatible with types " + + m_type->toString() + + " and " + + m_rightHandSide->type()->toString() + )); } } @@ -850,16 +857,13 @@ void BinaryOperation::checkTypeRequirements(TypePointers const*) m_right->checkTypeRequirements(nullptr); m_commonType = m_left->type()->binaryOperatorResult(m_operator, m_right->type()); if (!m_commonType) - BOOST_THROW_EXCEPTION( - createTypeError( - "Operator " + - string(Token::toString(m_operator)) + - " not compatible with types " + - m_left->type()->toString() + - " and " + - m_right->type()->toString() - ) - ); + BOOST_THROW_EXCEPTION(createTypeError( + "Operator " + string(Token::toString(m_operator)) + + " not compatible with types " + + m_left->type()->toString() + + " and " + + m_right->type()->toString() + )); m_type = Token::isCompareOp(m_operator) ? make_shared() : m_commonType; } @@ -1040,7 +1044,8 @@ void NewExpression::checkTypeRequirements(TypePointers const*) TypePointers{contractType}, strings(), strings(), - FunctionType::Location::Creation); + FunctionType::Location::Creation + ); } void MemberAccess::checkTypeRequirements(TypePointers const* _argumentTypes) @@ -1069,19 +1074,25 @@ void MemberAccess::checkTypeRequirements(TypePointers const* _argumentTypes) ); if (!storageType->members().membersByName(*m_memberName).empty()) BOOST_THROW_EXCEPTION(createTypeError( - "Member \"" + *m_memberName + "\" is not available in " + + "Member \"" + + *m_memberName + + "\" is not available in " + type.toString() + " outside of storage." )); BOOST_THROW_EXCEPTION(createTypeError( - "Member \"" + *m_memberName + "\" not found or not visible " - "after argument-dependent lookup in " + type.toString() + "Member \"" + + *m_memberName + + "\" not found or not visible after argument-dependent lookup in " + + type.toString() )); } else if (possibleMembers.size() > 1) BOOST_THROW_EXCEPTION(createTypeError( - "Member \"" + *m_memberName + "\" not unique " - "after argument-dependent lookup in " + type.toString() + "Member \"" + + *m_memberName + + "\" not unique after argument-dependent lookup in " + + type.toString() )); m_referencedDeclaration = possibleMembers.front().declaration; @@ -1114,10 +1125,12 @@ void IndexAccess::checkTypeRequirements(TypePointers const*) if (type.isString()) BOOST_THROW_EXCEPTION(createTypeError("Index access for string is not possible.")); m_index->expectType(IntegerType(256)); - if (type.isByteArray()) - m_type = make_shared(1); - else - m_type = type.baseType(); + + m_type = type.baseType(); + if(IntegerConstantType const* integerType = dynamic_cast(m_index->type().get())) + if (!type.isDynamicallySized() && type.length() <= integerType->literalValue(nullptr)) + BOOST_THROW_EXCEPTION(createTypeError("Out of bounds access.")); + m_isLValue = type.location() != DataLocation::CallData; break; } @@ -1143,7 +1156,8 @@ void IndexAccess::checkTypeRequirements(TypePointers const*) if (!length) BOOST_THROW_EXCEPTION(m_index->createTypeError("Integer constant expected.")); m_type = make_shared(make_shared( - DataLocation::Memory, type.actualType(), + DataLocation::Memory, + type.actualType(), length->literalValue(nullptr) )); } @@ -1151,7 +1165,10 @@ void IndexAccess::checkTypeRequirements(TypePointers const*) } default: BOOST_THROW_EXCEPTION(m_base->createTypeError( - "Indexed expression has to be a type, mapping or array (is " + m_base->type()->toString() + ")")); + "Indexed expression has to be a type, mapping or array (is " + + m_base->type()->toString() + + ")" + )); } } From bc914641318a70dada6cd4c8223f95efeb919771 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Wed, 9 Sep 2015 17:15:23 +0200 Subject: [PATCH 07/14] - changed implementation - style fixes --- test/libsolidity/SolidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 1ad57fb94..21e210183 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5259,7 +5259,7 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access) } } )"; - compileRequireThrow(sourceCode); + compileRequireThrow(sourceCode); } BOOST_AUTO_TEST_SUITE_END() From e17938a2a9f1e19a179e1d260d1d7f83668827f5 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Wed, 9 Sep 2015 18:18:34 +0200 Subject: [PATCH 08/14] fixed conflict mergeing --- libsolidity/AST.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index a77bf0a2c..7480ef305 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -59,8 +59,8 @@ void ContractDefinition::checkTypeRequirements() checkAbstractConstructors(); FunctionDefinition const* functionDefinition = constructor(); - if (functionDefinition && !functionDefinition->getReturnParameters().empty()) - BOOST_THROW_EXCEPTION(functionDefinition->getReturnParameterList()->createTypeError( + if (functionDefinition && !functionDefinition->returnParameters().empty()) + BOOST_THROW_EXCEPTION(functionDefinition->returnParameterList()->createTypeError( "Non-empty \"returns\" directive for constructor." )); From dd3b0664c667896c983579f18559e1e45db550b1 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 10 Sep 2015 10:17:17 +0200 Subject: [PATCH 09/14] style fixes --- libsolidity/AST.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 7480ef305..daa84016d 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -119,7 +119,8 @@ map, FunctionTypePointer> ContractDefinition::interfaceFunctions() for (auto const& it: exportedFunctionList) exportedFunctions.insert(it); - solAssert(exportedFunctionList.size() == exportedFunctions.size(), + solAssert( + exportedFunctionList.size() == exportedFunctions.size(), "Hash collision at Function Definition Hash calculation" ); @@ -1127,7 +1128,7 @@ void IndexAccess::checkTypeRequirements(TypePointers const*) m_index->expectType(IntegerType(256)); m_type = type.baseType(); - if(IntegerConstantType const* integerType = dynamic_cast(m_index->type().get())) + if (auto integerType = dynamic_cast(m_index->type().get())) if (!type.isDynamicallySized() && type.length() <= integerType->literalValue(nullptr)) BOOST_THROW_EXCEPTION(createTypeError("Out of bounds access.")); From 5291467a26342e746028b0b238df6b364d0b1065 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 10 Sep 2015 10:20:16 +0200 Subject: [PATCH 10/14] removed unneccessary check from ExpresiionCompiler --- libsolidity/ExpressionCompiler.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 4e607afdc..1b9f21500 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -821,7 +821,6 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) _indexAccess.baseExpression().accept(*this); Type const& baseType = *_indexAccess.baseExpression().type(); - Type const& indexType = *_indexAccess.indexExpression()->type(); if (baseType.category() == Type::Category::Mapping) { @@ -863,21 +862,8 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) solAssert(_indexAccess.indexExpression(), "Index expression expected."); _indexAccess.indexExpression()->accept(*this); - - // check for dynamically sized arrays should be done after memberAccess visit to have length - if ( - (indexType.category() == Type::Category::IntegerConstant) && - ((arrayType.isDynamicallySized() && arrayType.length()) || !arrayType.isDynamicallySized()) - ) - { - IntegerConstantType const& constant = dynamic_cast(indexType); - if (arrayType.length() < constant.literalValue(nullptr)) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Out of bounds access.")); - } - // stack layout: [] ArrayUtils(m_context).accessIndex(arrayType); - switch (arrayType.location()) { case DataLocation::Storage: From 466f5a4b88b4f317e8a4d9b5734fd938d4e01e80 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 10 Sep 2015 10:29:19 +0200 Subject: [PATCH 11/14] returned test for exceptions in constructor --- test/libsolidity/SolidityEndToEndTest.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 21e210183..8f94cba16 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -4182,6 +4182,23 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_call_fail) BOOST_CHECK(callContractFunction("test()") == encodeArgs(2)); } +BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) +{ + char const* sourceCode = R"( + contract A { + uint public test = 1; + uint[3] arr; + function A() + { + uint index = 5; + test = arr[index]; + ++test; + } + } + )"; + BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty()); +} + BOOST_AUTO_TEST_CASE(positive_integers_to_signed) { char const* sourceCode = R"( From 9d44e659321cad4fe9955895d8487bf4a089ae92 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 15 Sep 2015 11:41:40 +0200 Subject: [PATCH 12/14] moved the test Conflicts: test/libsolidity/SolidityEndToEndTest.cpp test/libsolidity/SolidityNameAndTypeResolution.cpp --- test/libsolidity/SolidityEndToEndTest.cpp | 3 +++ .../libsolidity/SolidityNameAndTypeResolution.cpp | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 8f94cba16..05508e2ba 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5233,6 +5233,7 @@ BOOST_AUTO_TEST_CASE(storage_string_as_mapping_key_without_variable) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); } +<<<<<<< HEAD BOOST_AUTO_TEST_CASE(library_call) { char const* sourceCode = R"( @@ -5279,6 +5280,8 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access) compileRequireThrow(sourceCode); } +======= +>>>>>>> 6920415... moved the test BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 5d1743679..f671c5ec0 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2250,10 +2250,23 @@ BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract) function f() { var x = new Test(); } } )"; - BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(array_out_of_bound_access) +{ + char const* text = R"( + contract c { + uint[2] dataArray; + function set5th() returns (bool) { + dataArray[5] = 2; + return true; + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From dbb36a7a7bc81d5397b5da316c9a7d89c76cc52b Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 15 Sep 2015 11:44:04 +0200 Subject: [PATCH 13/14] fixed rebase --- test/libsolidity/SolidityEndToEndTest.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 05508e2ba..cac2d2966 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5233,7 +5233,6 @@ BOOST_AUTO_TEST_CASE(storage_string_as_mapping_key_without_variable) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); } -<<<<<<< HEAD BOOST_AUTO_TEST_CASE(library_call) { char const* sourceCode = R"( @@ -5266,22 +5265,6 @@ BOOST_AUTO_TEST_CASE(library_stray_values) BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42))); } -BOOST_AUTO_TEST_CASE(array_out_of_bound_access) -{ - char const* sourceCode = R"( - contract c { - uint[2] dataArray; - function set5th() returns (bool) { - dataArray[5] = 2; - return true; - } - } - )"; - compileRequireThrow(sourceCode); -} - -======= ->>>>>>> 6920415... moved the test BOOST_AUTO_TEST_SUITE_END() } From 152bc642a6e8025d7957898e25848c9c836eb462 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 15 Sep 2015 12:06:16 +0200 Subject: [PATCH 14/14] style fix --- test/libsolidity/SolidityEndToEndTest.cpp | 2 +- test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index cac2d2966..2ba6ab85c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -4195,7 +4195,7 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) ++test; } } - )"; + )"; BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty()); } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index f671c5ec0..2a720494a 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2256,13 +2256,13 @@ BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract) BOOST_AUTO_TEST_CASE(array_out_of_bound_access) { char const* text = R"( - contract c { - uint[2] dataArray; - function set5th() returns (bool) { - dataArray[5] = 2; - return true; + contract c { + uint[2] dataArray; + function set5th() returns (bool) { + dataArray[5] = 2; + return true; + } } - } )"; BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); }