diff options
author | Christian <c@ethdev.com> | 2015-02-24 01:21:17 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-02-24 01:28:33 +0800 |
commit | 820ed2dfe17d93a586ba1519333bbe79cc6b9a9c (patch) | |
tree | 56c3a5bd411ff3a684e0cb08e060c8aada088628 /ExpressionCompiler.cpp | |
parent | 5d2323c91486cfcab9322b01d52ba35525e06272 (diff) | |
download | dexon-solidity-820ed2dfe17d93a586ba1519333bbe79cc6b9a9c.tar.gz dexon-solidity-820ed2dfe17d93a586ba1519333bbe79cc6b9a9c.tar.zst dexon-solidity-820ed2dfe17d93a586ba1519333bbe79cc6b9a9c.zip |
Out-of-bounds checking.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index a54915bc..183864ec 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -586,11 +586,29 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) "TODO: Index acces only implemented for storage arrays."); solAssert(!arrayType.isByteArray(), "TODO: Index acces not implemented for byte arrays."); solAssert(_indexAccess.getIndexExpression(), "Index expression expected."); + + _indexAccess.getIndexExpression()->accept(*this); + // retrieve length if (arrayType.isDynamicallySized()) + m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD; + else + m_context << arrayType.getLength(); + // stack: <base_ref> <index> <length> + // check out-of-bounds access + m_context << eth::Instruction::DUP2 << eth::Instruction::LT; + eth::AssemblyItem legalAccess = m_context.appendConditionalJump(); + // out-of-bounds access throws exception (just STOP for now) + m_context << eth::Instruction::STOP; + + m_context << legalAccess; + // stack: <base_ref> <index> + m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; + if (arrayType.isDynamicallySized()) + { + m_context << eth::Instruction::SWAP1; CompilerUtils(m_context).computeHashStatic(); - _indexAccess.getIndexExpression()->accept(*this); - m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL - << eth::Instruction::ADD; + } + m_context << eth::Instruction::ADD; m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType()); m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess); } |