aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity/SolidityEndToEndTest.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-09-25 23:13:29 +0800
committerchriseth <c@ethdev.com>2015-10-02 19:12:23 +0800
commitda408640ca44b0d0cd8140fe2882bd344b4e24b9 (patch)
tree214b57e1bd300e1df40263d1b0e52283fb342ef9 /test/libsolidity/SolidityEndToEndTest.cpp
parentcae8db989a28838dc25c262f60b34162e6e3f83d (diff)
downloaddexon-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.cpp110
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