vm: harden SUBSTR implementation against bad index/offset values

The upper index bound for slices is capacity, not length. Check for negative
values also. Fixes #387.
This commit is contained in:
Roman Khimov 2019-09-11 12:00:11 +03:00
parent fc1075bf75
commit 17f3a21e27
2 changed files with 41 additions and 0 deletions

View file

@ -320,6 +320,15 @@ func (v *VM) execute(ctx *Context, op Instruction) {
l := int(v.estack.Pop().BigInt().Int64())
o := int(v.estack.Pop().BigInt().Int64())
s := v.estack.Pop().Bytes()
if l < 0 {
panic("negative length")
}
if o < 0 {
panic("negative index")
}
if l+o > len(s) {
panic("out of bounds access")
}
v.estack.PushVal(s[o : o+l])
case LEFT:
l := int(v.estack.Pop().BigInt().Int64())

View file

@ -878,6 +878,38 @@ func TestSUBSTRBadLen(t *testing.T) {
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestSUBSTRBad387(t *testing.T) {
prog := makeProgram(SUBSTR)
vm := load(prog)
b := make([]byte, 6, 20)
copy(b, "abcdef")
vm.estack.PushVal(b)
vm.estack.PushVal(1)
vm.estack.PushVal(6)
vm.Run()
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestSUBSTRBadNegativeOffset(t *testing.T) {
prog := makeProgram(SUBSTR)
vm := load(prog)
vm.estack.PushVal([]byte("abcdef"))
vm.estack.PushVal(-1)
vm.estack.PushVal(3)
vm.Run()
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestSUBSTRBadNegativeLen(t *testing.T) {
prog := makeProgram(SUBSTR)
vm := load(prog)
vm.estack.PushVal([]byte("abcdef"))
vm.estack.PushVal(3)
vm.estack.PushVal(-1)
vm.Run()
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestLEFTBadNoArgs(t *testing.T) {
prog := makeProgram(LEFT)
vm := load(prog)