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