diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp index 66a8f8820..95f253d56 100644 --- a/libsolidity/SolidityEndToEndTest.cpp +++ b/libsolidity/SolidityEndToEndTest.cpp @@ -4243,9 +4243,9 @@ BOOST_AUTO_TEST_CASE(return_string) function get1() returns (string r) { return s; } -// function get2() returns (string r) { -// r = s; -// } + function get2() returns (string r) { + r = s; + } } )"; compileAndRun(sourceCode, 0, "Main"); @@ -4253,8 +4253,86 @@ BOOST_AUTO_TEST_CASE(return_string) bytes args = encodeArgs(u256(0x20), u256(s.length()), s); BOOST_REQUIRE(callContractFunction("set(string)", asString(args)) == encodeArgs()); BOOST_CHECK(callContractFunction("get1()") == args); -// BOOST_CHECK(callContractFunction("get2()") == args); -// BOOST_CHECK(callContractFunction("s()") == args); + BOOST_CHECK(callContractFunction("get2()") == args); + BOOST_CHECK(callContractFunction("s()") == args); +} + +BOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes) +{ + char const* sourceCode = R"( + contract Main { + string public s1; + string public s2; + function set(string _s1, uint x, string _s2) external returns (uint) { + s1 = _s1; + s2 = _s2; + return x; + } + function get() returns (string r1, string r2) { + r1 = s1; + r2 = s2; + } + } + )"; + compileAndRun(sourceCode, 0, "Main"); + string s1( + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + ); + string s2( + "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" + "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" + "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" + "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" + "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" + ); + vector lengthes{0, 30, 32, 63, 64, 65, 210, 300}; + for (auto l1: lengthes) + for (auto l2: lengthes) + { + bytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1)); + bytes dyn2 = encodeArgs(u256(l2), s2.substr(0, l2)); + bytes args = encodeArgs(u256(0x60), u256(l1), u256(0x60 + dyn1.size())) + dyn1 + dyn2; + BOOST_REQUIRE( + callContractFunction("set(string,uint256,string)", asString(args)) == + encodeArgs(u256(l1)) + ); + bytes result = encodeArgs(u256(0x40), u256(0x40 + dyn1.size())) + dyn1 + dyn2; + BOOST_CHECK(callContractFunction("get()") == result); + BOOST_CHECK(callContractFunction("s1()") == encodeArgs(0x20) + dyn1); + BOOST_CHECK(callContractFunction("s2()") == encodeArgs(0x20) + dyn2); + } +} + +BOOST_AUTO_TEST_CASE(accessor_involving_strings) +{ + char const* sourceCode = R"( + contract Main { + struct stringData { string a; uint b; string c; } + mapping(uint => stringData[]) public data; + function set(uint x, uint y, string a, uint b, string c) external returns (bool) { + data[x].length = y + 1; + data[x][y].a = a; + data[x][y].b = b; + data[x][y].c = c; + return true; + } + } + )"; + compileAndRun(sourceCode, 0, "Main"); + string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + string s2("ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ"); + bytes s1Data = encodeArgs(u256(s1.length()), s1); + bytes s2Data = encodeArgs(u256(s2.length()), s2); + u256 b = 765; + u256 x = 7; + u256 y = 123; + bytes args = encodeArgs(x, y, u256(0xa0), b, u256(0xa0 + s1Data.size()), s1Data, s2Data); + bytes result = encodeArgs(u256(0x60), b, u256(0x60 + s1Data.size()), s1Data, s2Data); + BOOST_REQUIRE(callContractFunction("set(uint256,uint256,string,uint256,string)", asString(args)) == encodeArgs(true)); + BOOST_REQUIRE(callContractFunction("data(uint256,uint256)", x, y) == result); } BOOST_AUTO_TEST_CASE(storage_array_ref) diff --git a/libsolidity/SolidityTypes.cpp b/libsolidity/SolidityTypes.cpp index 718798a5a..7892de673 100644 --- a/libsolidity/SolidityTypes.cpp +++ b/libsolidity/SolidityTypes.cpp @@ -77,13 +77,13 @@ BOOST_AUTO_TEST_CASE(storage_layout_mapping) BOOST_AUTO_TEST_CASE(storage_layout_arrays) { - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(1), 32).getStorageSize() == 1); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(1), 33).getStorageSize() == 2); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(2), 31).getStorageSize() == 2); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(7), 8).getStorageSize() == 2); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(7), 9).getStorageSize() == 3); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(31), 9).getStorageSize() == 9); - BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared(32), 9).getStorageSize() == 9); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(1), 32).getStorageSize() == 1); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(1), 33).getStorageSize() == 2); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(2), 31).getStorageSize() == 2); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(7), 8).getStorageSize() == 2); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(7), 9).getStorageSize() == 3); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(31), 9).getStorageSize() == 9); + BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared(32), 9).getStorageSize() == 9); } BOOST_AUTO_TEST_SUITE_END()