From 35483422f35054a21fc0833b5f270c3158a68b7a Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 28 Jan 2019 11:59:18 +0100 Subject: [PATCH] Pad code to multiple of 32 bytes. --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index ff635c208..d3172cb06 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.5.4 (unreleased) Bugfixes: + * Code generator: Defensively pad allocation of creationCode and runtimeCode to multiples of 32 bytes. * Parser: Disallow empty import statements. * Type system: Properly report packed encoded size for arrays and structs (mostly unused until now). diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index e6bb163dd..c1079ed32 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1348,7 +1348,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) m_context.appendInlineAssembly( Whiskers(R"({ mstore(start, sub(end, add(start, 0x20))) - mstore(, end) + mstore(, and(add(end, 31), not(31))) })")("free", to_string(CompilerUtils::freeMemoryPointer)).render(), {"start", "end"} ); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 38be5ae7c..e738eb04b 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -14275,6 +14275,25 @@ BOOST_AUTO_TEST_CASE(code_access) ABI_CHECK(codeRuntime1, codeRuntime2); } +BOOST_AUTO_TEST_CASE(code_access_padding) +{ + char const* sourceCode = R"( + contract C { + function diff() public pure returns (uint remainder) { + bytes memory a = type(D).creationCode; + bytes memory b = type(D).runtimeCode; + assembly { remainder := mod(sub(b, a), 0x20) } + } + } + contract D { + function f() public pure returns (uint) { return 7; } + } + )"; + compileAndRun(sourceCode, 0, "C"); + // This checks that the allocation function pads to multiples of 32 bytes + ABI_CHECK(callContractFunction("diff()"), encodeArgs(0)); +} + BOOST_AUTO_TEST_CASE(code_access_create) { char const* sourceCode = R"(