diff --git a/vm/vm.go b/vm/vm.go index ed61d2f90..b0819d5f2 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -176,29 +176,47 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) { vm.push(a.(string) == b.(string)) case OpJump: + if arg < 0 { + panic("negative jump offset is invalid") + } vm.ip += arg case OpJumpIfTrue: + if arg < 0 { + panic("negative jump offset is invalid") + } if vm.current().(bool) { vm.ip += arg } case OpJumpIfFalse: + if arg < 0 { + panic("negative jump offset is invalid") + } if !vm.current().(bool) { vm.ip += arg } case OpJumpIfNil: + if arg < 0 { + panic("negative jump offset is invalid") + } if runtime.IsNil(vm.current()) { vm.ip += arg } case OpJumpIfNotNil: + if arg < 0 { + panic("negative jump offset is invalid") + } if !runtime.IsNil(vm.current()) { vm.ip += arg } case OpJumpIfEnd: + if arg < 0 { + panic("negative jump offset is invalid") + } scope := vm.scope() if scope.Index >= scope.Len { vm.ip += arg diff --git a/vm/vm_test.go b/vm/vm_test.go index 817fc6cc2..ca2f317e1 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -1331,3 +1331,34 @@ func TestVM_Limits(t *testing.T) { }) } } + +func TestVM_OpJump_NegativeOffset(t *testing.T) { + program := vm.NewProgram( + file.Source{}, + nil, + nil, + 0, + nil, + []vm.Opcode{ + vm.OpInt, + vm.OpInt, + vm.OpJump, + vm.OpInt, + vm.OpJump, + }, + []int{ + 1, + 2, + -2, // negative offset for a forward jump opcode + 3, + -2, + }, + nil, + nil, + nil, + ) + + _, err := vm.Run(program, nil) + require.Error(t, err) + require.Contains(t, err.Error(), "negative jump offset is invalid") +}