From 0a7700112f82e634a957685bee0cbaa3458f4945 Mon Sep 17 00:00:00 2001 From: Mel Date: Sat, 28 May 2022 01:22:17 +0000 Subject: Harden VM Mem --- pkg/lang/vm/exec.go | 103 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 26 deletions(-) (limited to 'pkg/lang/vm/exec.go') diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index ee977b7..c9b8615 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -14,8 +14,14 @@ func (vm *VM) execPushFloat(x float64) { vm.stack.Push(value.NewFloat(x)) } -func (vm *VM) execPushString(str string) { - vm.stack.Push(value.NewString(&vm.memory, str)) +func (vm *VM) execPushString(str string) error { + val, err := value.NewString(&vm.memory, str) + if err != nil { + return err + } + + vm.stack.Push(val) + return nil } func (vm *VM) execPushBool(b bool) { @@ -26,8 +32,14 @@ func (vm *VM) execPushNull() { vm.stack.Push(value.NewNull()) } -func (vm *VM) execPushArray() { - vm.stack.Push(value.NewArray(&vm.memory, []value.Value{})) +func (vm *VM) execPushArray() error { + val, err := value.NewArray(&vm.memory, []value.Value{}) + if err != nil { + return err + } + + vm.stack.Push(val) + return nil } func (vm *VM) execPushFunction(pc int) { @@ -47,15 +59,23 @@ func (vm *VM) execGetLocal(offset int) error { } func (vm *VM) execGetEnv(envIndex int) error { - envPtr := vm.stack.CurrentCallEnv() - env := vm.memory.Get(envPtr).(value.Env) + envCell, err := vm.getMemCell(vm.stack.CurrentCallEnv(), mem.CellKindEnv, false) + if err != nil { + return err + } + env := envCell.(value.EnvCell).Get() // First check outlet. outletPtr := env.GetOutlet(envIndex) - outlet := vm.memory.Get(outletPtr) - if outlet != nil { + outletCell, err := vm.getMemCell(outletPtr, mem.CellKindOutlet, true) + if err != nil { + return err + } + + if outletCell != nil { // Outlet is not null, so value escaped. - val := outlet.(value.Value).Clone(&vm.memory) + outlet := outletCell.(value.OutletCell).Get() + val := outlet.Clone(&vm.memory) vm.stack.Push(val) return nil } @@ -79,14 +99,23 @@ func (vm *VM) execSetEnv(envIndex int) error { return err } - envPtr := vm.stack.CurrentCallEnv() - env := vm.memory.Get(envPtr).(value.Env) + envCell, err := vm.getMemCell(vm.stack.CurrentCallEnv(), mem.CellKindEnv, false) + if err != nil { + return err + } + env := envCell.(value.EnvCell).Get() outletPtr := env.GetOutlet(envIndex) - outlet := vm.memory.Get(outletPtr) - if outlet != nil { - outlet.(value.Value).Drop(&vm.memory) - vm.memory.Set(outletPtr, new) + outletCell, err := vm.getMemCell(outletPtr, mem.CellKindOutlet, true) + if err != nil { + return err + } + + if outletCell != nil { + // Outlet is not null, so value escaped. + outlet := outletCell.(value.OutletCell).Get() + outlet.Drop(&vm.memory) + vm.memory.Set(outletPtr, value.OutletCell(new)) return nil } @@ -119,8 +148,12 @@ func (vm *VM) execAddToEnv(localIndex int) error { var envPtr mem.Ptr if fn.Env().IsNull() { // Allocate new Env. - envPtr = vm.memory.Allocate(mem.CellKindEnv) - vm.memory.Set(envPtr, value.NewEnv()) + envPtr, err = vm.memory.Allocate(mem.CellKindEnv) + if err != nil { + return err + } + + vm.memory.Set(envPtr, value.EnvCell(value.NewEnv())) fn = fn.WithEnv(envPtr) } else { envPtr = fn.Env() @@ -133,16 +166,24 @@ func (vm *VM) execAddToEnv(localIndex int) error { } if local.Outlet().IsNull() { - outlet := vm.memory.Allocate(mem.CellKindOutlet) - local = local.WithOutlet(outlet) + outletPtr, err := vm.memory.Allocate(mem.CellKindOutlet) + if err != nil { + return err + } + local = local.WithOutlet(outletPtr) } // Add local to env. stackIndex := vm.stack.LocalToStackIndex(localIndex) - env := vm.memory.Get(envPtr).(value.Env) + envCell, err := vm.getMemCell(envPtr, mem.CellKindEnv, false) + if err != nil { + return err + } + + env := envCell.(value.EnvCell).Get() env.Add(stackIndex, local.Outlet()) - vm.memory.Set(envPtr, env) + vm.memory.Set(envPtr, value.EnvCell(env)) // Push function back onto stack. f = f.WithData(fn) @@ -295,15 +336,22 @@ func (vm *VM) execIndex() error { switch i.Type().Kind { case value.IntType: idx := i.Data().(value.IntData).Get() - len := int64(arr.Len(&vm.memory)) - if idx < 0 || idx >= len { + len, err := arr.Len(&vm.memory) + if err != nil { + return err + } + if idx < 0 || idx >= int64(len) { return ErrArrayIndexOutOfBounds{ Index: int(idx), Len: int(len), } } - val := arr.At(&vm.memory, int(idx)).Clone(&vm.memory) + val, err := arr.At(&vm.memory, int(idx)) + if err != nil { + return err + } + val = val.Clone(&vm.memory) vm.stack.Push(val) default: return ErrInvalidOperandTypes{ @@ -458,8 +506,11 @@ func (vm *VM) execTempArrLen() error { switch a.Type().Kind { case value.ArrayType: arr := a.Data().(value.ArrayData) - len := int64(arr.Len(&vm.memory)) - res := value.NewInt(len) + len, err := arr.Len(&vm.memory) + if err != nil { + return err + } + res := value.NewInt(int64(len)) vm.stack.Push(res) default: return ErrInvalidOperandTypes{ -- cgit 1.4.1