mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3070 from ethereum/lll-assembly
lll: disallow useless PUSHn in assembly
This commit is contained in:
commit
fda8499c15
@ -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)
|
||||
{
|
||||
@ -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);
|
||||
@ -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())
|
||||
|
@ -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()
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user