Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 22 additions & 25 deletions src/Neo.VM/JumpTable/JumpTable.Compound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,9 @@ public virtual void HasKey(ExecutionEngine engine, Instruction instruction)
// For arrays, check if the index is within bounds and push the result onto the stack.
case VMArray array:
{
// TODO: Overflow and underflow checking needs to be done.
var index = (int)key.GetInteger();
if (index < 0)
throw new InvalidOperationException($"The negative index {index} is invalid for OpCode.{instruction.OpCode}.");
var index = key.GetInteger();
if (index < 0 || index >= engine.Limits.MaxStackSize)
throw new InvalidOperationException($"The index {index} is invalid for OpCode.{instruction.OpCode}.");
engine.Push(index < array.Count);
break;
}
Expand All @@ -296,20 +295,18 @@ public virtual void HasKey(ExecutionEngine engine, Instruction instruction)
// For buffers, check if the index is within bounds and push the result onto the stack.
case Buffer buffer:
{
// TODO: Overflow and underflow checking needs to be done.
var index = (int)key.GetInteger();
if (index < 0)
throw new InvalidOperationException($"The negative index {index} is invalid for OpCode.{instruction.OpCode}.");
var index = key.GetInteger();
if (index < 0 || index >= engine.Limits.MaxItemSize)
throw new InvalidOperationException($"The index {index} is invalid for OpCode.{instruction.OpCode}.");
engine.Push(index < buffer.Size);
break;
}
// For byte strings, check if the index is within bounds and push the result onto the stack.
case ByteString array:
{
// TODO: Overflow and underflow checking needs to be done.
var index = (int)key.GetInteger();
if (index < 0)
throw new InvalidOperationException($"The negative index {index} is invalid for OpCode.{instruction.OpCode}.");
var index = key.GetInteger();
if (index < 0 || index >= engine.Limits.MaxItemSize)
throw new InvalidOperationException($"The index {index} is invalid for OpCode.{instruction.OpCode}.");
engine.Push(index < array.Size);
break;
}
Expand Down Expand Up @@ -375,10 +372,10 @@ public virtual void PickItem(ExecutionEngine engine, Instruction instruction)
{
case VMArray array:
{
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= array.Count)
throw new CatchableException($"The index of {nameof(VMArray)} is out of range, {index}/[0, {array.Count}).");
engine.Push(array[index]);
engine.Push(array[(int)index]);
break;
}
case Map map:
Expand All @@ -391,18 +388,18 @@ public virtual void PickItem(ExecutionEngine engine, Instruction instruction)
case PrimitiveType primitive:
{
var byteArray = primitive.GetSpan();
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= byteArray.Length)
throw new CatchableException($"The index of {nameof(PrimitiveType)} is out of range, {index}/[0, {byteArray.Length}).");
engine.Push((BigInteger)byteArray[index]);
engine.Push((BigInteger)byteArray[(int)index]);
break;
}
case Buffer buffer:
{
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= buffer.Size)
throw new CatchableException($"The index of {nameof(Buffer)} is out of range, {index}/[0, {buffer.Size}).");
engine.Push((BigInteger)buffer.InnerBuffer.Span[index]);
engine.Push((BigInteger)buffer.InnerBuffer.Span[(int)index]);
break;
}
default:
Expand Down Expand Up @@ -444,10 +441,10 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction)
{
case VMArray array:
{
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= array.Count)
throw new CatchableException($"The index of {nameof(VMArray)} is out of range, {index}/[0, {array.Count}).");
array[index] = value;
array[(int)index] = value;
break;
}
case Map map:
Expand All @@ -457,15 +454,15 @@ public virtual void SetItem(ExecutionEngine engine, Instruction instruction)
}
case Buffer buffer:
{
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= buffer.Size)
throw new CatchableException($"The index of {nameof(Buffer)} is out of range, {index}/[0, {buffer.Size}).");
if (value is not PrimitiveType p)
throw new InvalidOperationException($"Only primitive type values can be set in {nameof(Buffer)} in {instruction.OpCode}.");
var b = (int)p.GetInteger();
var b = p.GetInteger();
if (b < sbyte.MinValue || b > byte.MaxValue)
throw new InvalidOperationException($"Overflow in {instruction.OpCode}, {b} is not a byte type.");
buffer.InnerBuffer.Span[index] = (byte)b;
buffer.InnerBuffer.Span[(int)index] = (byte)b;
buffer.InvalidateHashCode();
break;
}
Expand Down Expand Up @@ -514,10 +511,10 @@ public virtual void Remove(ExecutionEngine engine, Instruction instruction)
switch (x)
{
case VMArray array:
var index = (int)key.GetInteger();
var index = key.GetInteger();
if (index < 0 || index >= array.Count)
throw new InvalidOperationException($"The index of {nameof(VMArray)} is out of range, {index}/[0, {array.Count}).");
array.RemoveAt(index);
array.RemoveAt((int)index);
break;
case Map map:
map.Remove(key);
Expand Down
40 changes: 40 additions & 0 deletions tests/Neo.VM.Tests/Tests/OpCodes/Arrays/HASKEY.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,46 @@
}
]
},
{
"name": "Overflow index [Array]",
"script": [
"PUSH1",
"NEWARRAY",
"PUSHINT64",
"0x0000008000000000",
"HASKEY"
],
"steps": [
{
"actions": [
"execute"
],
"result": {
"state": "FAULT"
}
}
]
},
{
"name": "Underflow index [Array]",
"script": [
"PUSH1",
"NEWARRAY",
"PUSHINT64",
"0xffffff7fffffffff",
"HASKEY"
],
"steps": [
{
"actions": [
"execute"
],
"result": {
"state": "FAULT"
}
}
]
},
{
"name": "Check key size [Map]",
"script": [
Expand Down