Просмотр исходного кода

Reset args, newTarget and privEnv on recursive VM runs. See #481

Dmitry Panov 2 лет назад
Родитель
Сommit
5937a312ed
2 измененных файлов с 28 добавлено и 0 удалено
  1. 3 0
      runtime.go
  2. 25 0
      runtime_test.go

+ 3 - 0
runtime.go

@@ -1495,6 +1495,9 @@ func (r *Runtime) RunProgram(p *Program) (result Value, err error) {
 	if recursive {
 		vm.pushCtx()
 		vm.stash = &r.global.stash
+		vm.privEnv = nil
+		vm.newTarget = nil
+		vm.args = 0
 		sp := vm.sp
 		vm.stack.expand(sp + 1)
 		vm.stack[sp] = _undefined // 'callee'

+ 25 - 0
runtime_test.go

@@ -239,6 +239,31 @@ func TestRecursiveRun(t *testing.T) {
 	}
 }
 
+func TestRecursiveRunWithNArgs(t *testing.T) {
+	vm := New()
+	vm.Set("f", func() (Value, error) {
+		return vm.RunString(`
+		{
+			let a = 0;
+			let b = 1;
+			a = 2; // this used to to corrupt b, because its location on the stack was off by vm.args (1 in our case)
+			b;
+		}
+	`)
+	})
+	_, err := vm.RunString(`
+		(function(arg) { // need an ES function call with an argument to set vm.args
+			let res = f();
+			if (res !== 1) {
+				throw new Error(res);
+			}
+		})(123);
+	`)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestRecursiveRunCallee(t *testing.T) {
 	// Make sure that a recursive call to Run*() correctly sets the callee (i.e. stack[sb-1])
 	vm := New()