diff options
author | chriseth <c@ethdev.com> | 2015-09-25 23:13:29 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-10-02 19:12:23 +0800 |
commit | da408640ca44b0d0cd8140fe2882bd344b4e24b9 (patch) | |
tree | 214b57e1bd300e1df40263d1b0e52283fb342ef9 /test/libsolidity/SolidityEndToEndTest.cpp | |
parent | cae8db989a28838dc25c262f60b34162e6e3f83d (diff) | |
download | dexon-solidity-da408640ca44b0d0cd8140fe2882bd344b4e24b9.tar.gz dexon-solidity-da408640ca44b0d0cd8140fe2882bd344b4e24b9.tar.zst dexon-solidity-da408640ca44b0d0cd8140fe2882bd344b4e24b9.zip |
Store small byte arrays and strings in storage in one slot with their
length.
Diffstat (limited to 'test/libsolidity/SolidityEndToEndTest.cpp')
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 0459c3ae..86caacb6 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5354,6 +5354,116 @@ BOOST_AUTO_TEST_CASE(fixed_arrays_as_return_type) ); } +BOOST_AUTO_TEST_CASE(short_strings) +{ + // This test verifies that the byte array encoding that combines length and data works + // correctly. + char const* sourceCode = R"( + contract A { + bytes public data1 = "123"; + bytes data2; + function lengthChange() returns (uint) + { + // store constant in short and long string + data1 = "123"; + if (!equal(data1, "123")) return 1; + data2 = "12345678901234567890123456789012345678901234567890a"; + if (data2[17] != "8") return 3; + if (data2.length != 51) return 4; + if (data2[data2.length - 1] != "a") return 5; + // change length: short -> short + data1.length = 5; + if (data1.length != 5) return 6; + data1[4] = "4"; + if (data1[0] != "1") return 7; + if (data1[4] != "4") return 8; + // change length: short -> long + data1.length = 80; + if (data1.length != 80) return 9; + data1.length = 70; + if (data1.length != 70) return 9; + if (data1[0] != "1") return 10; + if (data1[4] != "4") return 11; + for (uint i = 0; i < data1.length; i ++) + data1[i] = byte(i * 3); + if (data1[4] != 4 * 3) return 12; + if (data1[67] != 67 * 3) return 13; + // change length: long -> short + data1.length = 22; + if (data1.length != 22) return 14; + if (data1[21] != byte(21 * 3)) return 15; + if (data1[2] != 2 * 3) return 16; + // change length: short -> shorter + data1.length = 19; + if (data1.length != 19) return 17; + if (data1[7] != byte(7 * 3)) return 18; + // and now again to original size + data1.length = 22; + if (data1.length != 22) return 19; + if (data1[21] != 0) return 20; + data1.length = 0; + data2.length = 0; + } + function copy() returns (uint) { + bytes memory x = "123"; + bytes memory y = "012345678901234567890123456789012345678901234567890123456789"; + bytes memory z = "1234567"; + data1 = x; + data2 = y; + if (!equal(data1, x)) return 1; + if (!equal(data2, y)) return 2; + // lengthen + data1 = y; + if (!equal(data1, y)) return 3; + // shorten + data1 = x; + if (!equal(data1, x)) return 4; + // change while keeping short + data1 = z; + if (!equal(data1, z)) return 5; + // copy storage -> storage + data1 = x; + data2 = y; + // lengthen + data1 = data2; + if (!equal(data1, y)) return 6; + // shorten + data1 = x; + data2 = data1; + if (!equal(data2, x)) return 7; + bytes memory c = data2; + data1 = c; + if (!equal(data1, x)) return 8; + data1 = ""; + data2 = ""; + } + function deleteElements() returns (uint) { + data1 = "01234"; + delete data1[2]; + if (data1[2] != 0) return 1; + if (data1[0] != "0") return 2; + if (data1[3] != "3") return 3; + delete data1; + if (data1.length != 0) return 4; + } + + function equal(bytes storage a, bytes memory b) internal returns (bool) { + if (a.length != b.length) return false; + for (uint i = 0; i < a.length; ++i) if (a[i] != b[i]) return false; + return true; + } + } + )"; + compileAndRun(sourceCode, 0, "A"); + BOOST_CHECK(callContractFunction("data1()") == encodeDyn(string("123"))); + BOOST_CHECK(callContractFunction("lengthChange()") == encodeArgs(u256(0))); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("deleteElements()") == encodeArgs(u256(0))); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("copy()") == encodeArgs(u256(0))); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + BOOST_AUTO_TEST_CASE(calldata_offset) { // This tests a specific bug that was caused by not using the correct memory offset in the |