Skip to content

Commit

Permalink
Merge pull request #3070 from ethereum/lll-assembly
Browse files Browse the repository at this point in the history
lll: disallow useless PUSHn in assembly
  • Loading branch information
pirapira authored Oct 18, 2017
2 parents e854da1 + 15517b5 commit fda8499
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
44 changes: 27 additions & 17 deletions liblll/CodeFragment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ void CodeFragment::finalise(CompilerState const& _cs)
}
}

namespace
{
/// Returns true iff the instruction is valid in "inline assembly".
bool validAssemblyInstruction(string us)
{
auto it = c_instructions.find(us);
return !(
it == c_instructions.end() ||
solidity::isPushInstruction(it->second)
);
}

/// Returns true iff the instruction is valid as a function.
bool validFunctionalInstruction(string us)
{
auto it = c_instructions.find(us);
return !(
it == c_instructions.end() ||
solidity::isPushInstruction(it->second) ||
solidity::isDupInstruction(it->second) ||
solidity::isSwapInstruction(it->second) ||
it->second == solidity::Instruction::JUMPDEST
);
}
}

CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback const& _readFile, bool _allowASM):
m_readFile(_readFile)
{
Expand Down Expand Up @@ -80,7 +106,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback
auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
string s(sr.begin(), sr.end());
string us = boost::algorithm::to_upper_copy(s);
if (_allowASM && c_instructions.count(us))
if (_allowASM && c_instructions.count(us) && validAssemblyInstruction(us))
m_asm.append(c_instructions.at(us));
else if (_s.defs.count(s))
m_asm.append(_s.defs.at(s).m_asm);
Expand Down Expand Up @@ -114,22 +140,6 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback
}
}

namespace
{
/// Returns true iff the instruction is valid as a function.
bool validFunctionalInstruction(string us)
{
auto it = c_instructions.find(us);
return !(
it == c_instructions.end() ||
solidity::isPushInstruction(it->second) ||
solidity::isDupInstruction(it->second) ||
solidity::isSwapInstruction(it->second) ||
it->second == solidity::Instruction::JUMPDEST
);
}
}

void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
{
if (_t.tag() == 0 && _t.empty())
Expand Down
17 changes: 17 additions & 0 deletions test/liblll/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ BOOST_AUTO_TEST_CASE(switch_inconsistent_return_count)
BOOST_CHECK(!successCompile(sourceCode));
}

BOOST_AUTO_TEST_CASE(disallowed_asm_instructions)
{
for (unsigned i = 1; i <= 32; i++)
BOOST_CHECK(!successCompile("(asm PUSH" + boost::lexical_cast<string>(i) + ")"));
}

BOOST_AUTO_TEST_CASE(disallowed_functional_asm_instructions)
{
for (unsigned i = 1; i <= 32; i++)
BOOST_CHECK(!successCompile("(PUSH" + boost::lexical_cast<string>(i) + ")"));
for (unsigned i = 1; i <= 16; i++)
BOOST_CHECK(!successCompile("(DUP" + boost::lexical_cast<string>(i) + ")"));
for (unsigned i = 1; i <= 16; i++)
BOOST_CHECK(!successCompile("(SWAP" + boost::lexical_cast<string>(i) + ")"));
BOOST_CHECK(!successCompile("(JUMPDEST)"));
}

BOOST_AUTO_TEST_SUITE_END()

}
Expand Down

0 comments on commit fda8499

Please sign in to comment.