Skip to content

Commit

Permalink
smallIntGetUnsignedArgument handle index error
Browse files Browse the repository at this point in the history
  • Loading branch information
bbyalcinkaya committed Jul 19, 2023
1 parent dd6bbf3 commit ba55b83
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 10 deletions.
85 changes: 85 additions & 0 deletions tests/simple/bad-bounds.wast
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ deployTx(
(import "env" "getCaller" (func $getCaller (param i32)))
(import "env" "isSmartContract" (func $isSmartContract (param i32) (result i32)))
(import "env" "writeEventLog" (func $writeEventLog (param i32 i32 i32 i32 i32)))

(import "env" "smallIntGetUnsignedArgument"
(func $smallIntGetUnsignedArgument (param i32) (result i64))
)

(import "env" "smallIntGetSignedArgument"
(func $smallIntGetSignedArgument (param i32) (result i64))
)

(import "env" "smallIntFinishUnsigned" (func $smallIntFinishUnsigned (param i64)))
(import "env" "smallIntFinishSigned" (func $smallIntFinishSigned (param i64)))

(func (export "memStoreNegativeOffset")
i32.const -1
call $getCaller
Expand All @@ -34,6 +46,19 @@ deployTx(
i32.const 0
call $writeEventLog
)

(func (export "smallIntGetUnsignedArgumentTest")
(call $smallIntGetSignedArgument (i32.const 0)) ;; read the first argument: i
call $smallIntGetUnsignedArgument ;; read the ith argument
call $smallIntFinishUnsigned ;; return it
)

(func (export "smallIntGetSignedArgumentTest")
(call $smallIntGetSignedArgument (i32.const 0)) ;; read the first argument: i
call $smallIntGetSignedArgument ;; read the ith argument
call $smallIntFinishSigned ;; return it
)

(func (export "init"))
(memory (;0;) 17)
(export "memory" (memory 0))
Expand Down Expand Up @@ -105,4 +130,64 @@ callTx(
checkExpectStatus(ExecutionFailed)
checkExpectMessage(b"negative numArguments")

;; pass 2 arguments, get 2nd
callTx(
"testCaller"
, "testContract"
, 0, .List
, "smallIntGetUnsignedArgumentTest"
, ListItem(Int2Bytes(1, BE, Signed)) ListItem(Int2Bytes(123, BE, Unsigned))
, 0
, 0
)

checkExpectStatus(OK)
checkExpectOut(ListItem(Int2Bytes(123, BE, Unsigned)))


;; pass 1 argument, get 2nd, should fail
callTx(
"testCaller"
, "testContract"
, 0, .List
, "smallIntGetUnsignedArgumentTest"
, ListItem(Int2Bytes(1, BE, Signed))
, 0
, 0
)

checkExpectStatus(ExecutionFailed)
checkExpectMessage(b"argument index out of range")


;; pass 2 arguments, get -1st, should fail
callTx(
"testCaller"
, "testContract"
, 0, .List
, "smallIntGetUnsignedArgumentTest"
, ListItem(Int2Bytes(-1, BE, Signed)) ListItem(Int2Bytes(123, BE, Unsigned))
, 0
, 0
)

checkExpectStatus(ExecutionFailed)
checkExpectMessage(b"argument index out of range")


;; pass 2 arguments (2nd is too big for u64), get 2nd, should fail
callTx(
"testCaller"
, "testContract"
, 0, .List
, "smallIntGetUnsignedArgumentTest"
, ListItem(Int2Bytes(1, BE, Signed))
ListItem(Int2Bytes(maxUInt64 +Int 5, BE, Unsigned))
, 0
, 0
)

checkExpectStatus(ExecutionFailed)
checkExpectMessage(b"argument out of range")

setExitCode 0
37 changes: 27 additions & 10 deletions vmhooks/smallIntOps.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,37 @@ require "../elrond-config.md"
module SMALLINTOPS
imports BASEOPS
imports ELROND-CONFIG
imports private LIST-BYTES-EXTENSIONS
// extern long long smallIntGetUnsignedArgument(void *context, int32_t id);
rule <instrs> hostCall("env", "smallIntGetUnsignedArgument", [ i32 .ValTypes ] -> [ i64 .ValTypes ])
=> #returnIfUInt64(Bytes2Int(ARGS[ARG_IDX], BE, Unsigned), "argument out of range") ... </instrs>
<locals> 0 |-> <i32> ARG_IDX </locals>
<callArgs> ARGS </callArgs>
requires #validArgIdx(ARG_IDX, ARGS)
rule [smallIntGetUnsignedArgument]:
<instrs> hostCall("env", "smallIntGetUnsignedArgument", [ i32 .ValTypes ] -> [ i64 .ValTypes ])
=> #if #validArgIdx(ARG_IDX, ARGS)
#then #returnIfUInt64(
Bytes2Int(ARGS[ARG_IDX] orDefault b"", BE, Unsigned),
"argument out of range"
)
#else #throwException(ExecutionFailed, "argument index out of range")
#fi
...
</instrs>
<locals> 0 |-> <i32> ARG_IDX </locals>
<callArgs> ARGS </callArgs>
// extern long long smallIntGetSignedArgument(void *context, int32_t id);
rule <instrs> hostCall("env", "smallIntGetSignedArgument", [ i32 .ValTypes ] -> [ i64 .ValTypes ])
=> #returnIfSInt64(Bytes2Int(ARGS[ARG_IDX], BE, Signed), "argument out of range") ... </instrs>
<locals> 0 |-> <i32> ARG_IDX </locals>
<callArgs> ARGS </callArgs>
requires ARG_IDX <Int size(ARGS)
rule [smallIntGetSignedArgument]:
<instrs> hostCall("env", "smallIntGetSignedArgument", [ i32 .ValTypes ] -> [ i64 .ValTypes ])
=> #if #validArgIdx(ARG_IDX, ARGS)
#then #returnIfSInt64(
Bytes2Int(ARGS[ARG_IDX] orDefault b"", BE, Signed),
"argument out of range"
)
#else #throwException(ExecutionFailed, "argument index out of range")
#fi
...
</instrs>
<locals> 0 |-> <i32> ARG_IDX </locals>
<callArgs> ARGS </callArgs>
// extern void smallIntFinishUnsigned(void* context, long long value);
rule <instrs> hostCall("env", "smallIntFinishUnsigned", [ i64 .ValTypes ] -> [ .ValTypes ])
Expand Down

0 comments on commit ba55b83

Please sign in to comment.