@@ -1968,6 +1968,180 @@ BOOST_FIXTURE_TEST_CASE(crypto_tests, TESTER) { try {
19681968 BOOST_REQUIRE_EQUAL ( validate (), true );
19691969} FC_LOG_AND_RETHROW () }
19701970
1971+ /* ************************************************************************************
1972+ * memory_tests test case
1973+ *************************************************************************************/
1974+ static const char memcpy_pass_wast[] = R"======(
1975+ (module
1976+ (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32)))
1977+ (import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
1978+ (memory 1)
1979+ (func (export "apply") (param i64 i64 i64)
1980+ (i64.store (i32.const 0) (i64.const 0x8877665544332211))
1981+ (call $eosio_assert (i32.eq (call $memcpy (i32.const 65535) (i32.const 0) (i32.const 1)) (i32.const 65535)) (i32.const 128))
1982+ (call $eosio_assert (i64.eq (i64.load (i32.const 65528)) (i64.const 0x1100000000000000)) (i32.const 256))
1983+ (drop (call $memcpy (i32.const 8) (i32.const 7) (i32.const 1)))
1984+ (drop (call $memcpy (i32.const 7) (i32.const 8) (i32.const 1)))
1985+ )
1986+ (data (i32.const 128) "expected memcpy to return 65535")
1987+ (data (i32.const 256) "expected memcpy to write one byte")
1988+ )
1989+ )======" ;
1990+
1991+ static const char memcpy_overlap_wast[] = R"======(
1992+ (module
1993+ (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32)))
1994+ (memory 1)
1995+ (func (export "apply") (param i64 i64 i64)
1996+ (drop (call $memcpy (i32.const 16) (i32.wrap/i64 (get_local 2)) (i32.const 8)))
1997+ )
1998+ )
1999+ )======" ;
2000+
2001+ static const char memcpy_past_end_wast[] = R"======(
2002+ (module
2003+ (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32)))
2004+ (memory 1)
2005+ (func (export "apply") (param i64 i64 i64)
2006+ (drop (call $memcpy (i32.const 65535) (i32.const 0) (i32.const 2)))
2007+ )
2008+ )
2009+ )======" ;
2010+
2011+ static const char memmove_pass_wast[] = R"======(
2012+ (module
2013+ (import "env" "memmove" (func $memmove (param i32 i32 i32) (result i32)))
2014+ (import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
2015+ (memory 1)
2016+ (func $fillmem (param i32 i32)
2017+ (loop
2018+ (i32.store8 (get_local 0) (get_local 1))
2019+ (set_local 1 (i32.sub (get_local 1) (i32.const 1)))
2020+ (set_local 0 (i32.add (get_local 0) (i32.const 1)))
2021+ (br_if 0 (get_local 1))
2022+ )
2023+ )
2024+ (func $checkmem (param i32 i32 i32)
2025+ (loop
2026+ (call $eosio_assert (i32.eq (i32.load8_u (get_local 0)) (get_local 1)) (get_local 2))
2027+ (set_local 1 (i32.sub (get_local 1) (i32.const 1)))
2028+ (set_local 0 (i32.add (get_local 0) (i32.const 1)))
2029+ (br_if 0 (get_local 1))
2030+ )
2031+ )
2032+ (func (export "apply") (param i64 i64 i64)
2033+ (i64.store (i32.const 0) (i64.const 0x8877665544332211))
2034+ (call $eosio_assert (i32.eq (call $memmove (i32.const 65535) (i32.const 0) (i32.const 1)) (i32.const 65535)) (i32.const 128))
2035+ (call $eosio_assert (i64.eq (i64.load (i32.const 65528)) (i64.const 0x1100000000000000)) (i32.const 256))
2036+
2037+ (call $fillmem (i32.const 8) (i32.const 128))
2038+ (drop (call $memmove (i32.const 64) (i32.const 8) (i32.const 128)))
2039+ (call $checkmem (i32.const 64) (i32.const 128) (i32.const 384))
2040+
2041+ (call $fillmem (i32.const 8) (i32.const 128))
2042+ (drop (call $memmove (i32.const 8) (i32.const 8) (i32.const 128)))
2043+ (call $checkmem (i32.const 8) (i32.const 128) (i32.const 512))
2044+
2045+ (call $fillmem (i32.const 64) (i32.const 128))
2046+ (drop (call $memmove (i32.const 8) (i32.const 64) (i32.const 128)))
2047+ (call $checkmem (i32.const 8) (i32.const 128) (i32.const 640))
2048+ )
2049+ (data (i32.const 128) "expected memmove to return 65535")
2050+ (data (i32.const 256) "expected memmove to write one byte")
2051+ (data (i32.const 384) "memmove overlap dest above src")
2052+ (data (i32.const 512) "memmove overlap exact")
2053+ (data (i32.const 640) "memmove overlap src above dst")
2054+ )
2055+ )======" ;
2056+
2057+ static const char memcmp_pass_wast[] = R"======(
2058+ (module
2059+ (import "env" "memcmp" (func $memcmp (param i32 i32 i32) (result i32)))
2060+ (import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
2061+ (memory 1)
2062+ (func (export "apply") (param i64 i64 i64)
2063+ (call $eosio_assert (i32.eq (call $memcmp (i32.const 65535) (i32.const 65535) (i32.const 1)) (i32.const 0)) (i32.const 128))
2064+ (call $eosio_assert (i32.eq (call $memcmp (i32.const 0) (i32.const 2) (i32.const 3)) (i32.const 0)) (i32.const 256))
2065+ (call $eosio_assert (i32.eq (call $memcmp (i32.const 0) (i32.const 2) (i32.const 6)) (i32.const -1)) (i32.const 384))
2066+ (call $eosio_assert (i32.eq (call $memcmp (i32.const 2) (i32.const 0) (i32.const 6)) (i32.const 1)) (i32.const 512))
2067+ )
2068+ (data (i32.const 0) "abababcdcdcd")
2069+ (data (i32.const 128) "memcmp at end of memory")
2070+ (data (i32.const 256) "memcmp overlap eq1")
2071+ (data (i32.const 384) "memcmp overlap <")
2072+ (data (i32.const 512) "memcmp overlap >")
2073+ )
2074+ )======" ;
2075+
2076+ static const char memset_pass_wast[] = R"======(
2077+ (module
2078+ (import "env" "memset" (func $memset (param i32 i32 i32) (result i32)))
2079+ (import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
2080+ (memory 1)
2081+ (func (export "apply") (param i64 i64 i64)
2082+ (call $eosio_assert (i32.eq (call $memset (i32.const 65535) (i32.const 0xCC) (i32.const 1)) (i32.const 65535)) (i32.const 128))
2083+ (call $eosio_assert (i64.eq (i64.load (i32.const 65528)) (i64.const 0xCC00000000000000)) (i32.const 256))
2084+ )
2085+ (data (i32.const 128) "expected memset to return 65535")
2086+ (data (i32.const 256) "expected memset to write one byte")
2087+ )
2088+ )======" ;
2089+
2090+ BOOST_FIXTURE_TEST_CASE (memory_tests, TESTER) {
2091+ produce_block ();
2092+ create_accounts ( { " memcpy" _n, " memcpy2" _n, " memcpy3" _n, " memmove" _n, " memcmp" _n, " memset" _n } );
2093+ set_code ( " memcpy" _n, memcpy_pass_wast );
2094+ set_code ( " memcpy2" _n, memcpy_overlap_wast );
2095+ set_code ( " memcpy3" _n, memcpy_past_end_wast );
2096+ set_code ( " memmove" _n, memmove_pass_wast );
2097+ set_code ( " memcmp" _n, memcmp_pass_wast );
2098+ set_code ( " memset" _n, memset_pass_wast );
2099+ auto pushit = [&](name acct, name act) {
2100+ signed_transaction trx;
2101+ trx.actions .push_back ({ { {acct, config::active_name} }, acct, act, bytes ()});
2102+ set_transaction_headers (trx);
2103+ trx.sign (get_private_key (acct, " active" ), control->get_chain_id ());
2104+ push_transaction (trx);
2105+ };
2106+ pushit (" memcpy" _n, name ());
2107+ pushit (" memcpy2" _n, name (0 ));
2108+ pushit (" memcpy2" _n, name (8 ));
2109+ BOOST_CHECK_THROW (pushit (" memcpy2" _n, name (12 )), overlapping_memory_error);
2110+ BOOST_CHECK_THROW (pushit (" memcpy2" _n, name (16 )), overlapping_memory_error);
2111+ BOOST_CHECK_THROW (pushit (" memcpy2" _n, name (20 )), overlapping_memory_error);
2112+ BOOST_CHECK_THROW (pushit (" memcpy3" _n, name ()), wasm_execution_error);
2113+ pushit (" memcpy2" _n, name (24 ));
2114+
2115+ pushit (" memmove" _n, name ());
2116+ pushit (" memcmp" _n, name ());
2117+ pushit (" memset" _n, name ());
2118+ }
2119+
2120+ static const char cstr_wast[] = R"======(
2121+ (module
2122+ (import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
2123+ (memory 1)
2124+ (func (export "apply") (param i64 i64 i64)
2125+ (call $eosio_assert (i32.const 1) (i32.const 65534))
2126+ )
2127+ (data (i32.const 65535) "x")
2128+ )
2129+ )======" ;
2130+
2131+ BOOST_FIXTURE_TEST_CASE (cstr_tests, TESTER) {
2132+ produce_block ();
2133+ create_accounts ( { " cstr" _n } );
2134+ set_code ( " cstr" _n, cstr_wast );
2135+ auto pushit = [&](name acct, name act) {
2136+ signed_transaction trx;
2137+ trx.actions .push_back ({ { {acct, config::active_name} }, acct, act, bytes ()});
2138+ set_transaction_headers (trx);
2139+ trx.sign (get_private_key (acct, " active" ), control->get_chain_id ());
2140+ push_transaction (trx);
2141+ };
2142+ pushit (" cstr" _n, name ());
2143+ }
2144+
19712145/* ************************************************************************************
19722146 * print_tests test case
19732147 *************************************************************************************/
0 commit comments