aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-24 01:21:17 +0800
committerChristian <c@ethdev.com>2015-02-24 01:28:33 +0800
commit820ed2dfe17d93a586ba1519333bbe79cc6b9a9c (patch)
tree56c3a5bd411ff3a684e0cb08e060c8aada088628 /ExpressionCompiler.cpp
parent5d2323c91486cfcab9322b01d52ba35525e06272 (diff)
downloaddexon-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.cpp24
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);
}