mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
lll: disallow useless PUSHn in assembly
This commit is contained in:
parent
81f9f86ce5
commit
15517b571d
@ -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):
|
CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback const& _readFile, bool _allowASM):
|
||||||
m_readFile(_readFile)
|
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>>();
|
auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
|
||||||
string s(sr.begin(), sr.end());
|
string s(sr.begin(), sr.end());
|
||||||
string us = boost::algorithm::to_upper_copy(s);
|
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));
|
m_asm.append(c_instructions.at(us));
|
||||||
else if (_s.defs.count(s))
|
else if (_s.defs.count(s))
|
||||||
m_asm.append(_s.defs.at(s).m_asm);
|
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)
|
void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
|
||||||
{
|
{
|
||||||
if (_t.tag() == 0 && _t.empty())
|
if (_t.tag() == 0 && _t.empty())
|
||||||
|
@ -121,6 +121,23 @@ BOOST_AUTO_TEST_CASE(switch_inconsistent_return_count)
|
|||||||
BOOST_CHECK(!successCompile(sourceCode));
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user