aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-10-13 09:04:36 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2017-10-13 09:04:36 +0800
commit15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5 (patch)
tree6f89e072754834bac5f6b27c0d590c39635695fd
parent81f9f86ce51d2e9b54bf76b1169f12e193c79745 (diff)
downloaddexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar.gz
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar.bz2
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar.lz
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar.xz
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.tar.zst
dexon-solidity-15517b571d3ac4ee01af3e2e2f3fff7c5b2296c5.zip
lll: disallow useless PUSHn in assembly
-rw-r--r--liblll/CodeFragment.cpp44
-rw-r--r--test/liblll/Compiler.cpp17
2 files changed, 44 insertions, 17 deletions
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index d4ef3888..5c68194b 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -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())
diff --git a/test/liblll/Compiler.cpp b/test/liblll/Compiler.cpp
index 2d66bce1..77d263b8 100644
--- a/test/liblll/Compiler.cpp
+++ b/test/liblll/Compiler.cpp
@@ -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()
}