mirror of
https://github.com/robertkrimen/otto
synced 2025-10-05 19:19:10 +08:00
add simple stack depth limit mechanism
This commit is contained in:
parent
53221230c2
commit
c142472392
4
otto.go
4
otto.go
|
@ -367,6 +367,10 @@ func (self Otto) SetRandomSource(fn func() float64) {
|
|||
self.runtime.random = fn
|
||||
}
|
||||
|
||||
func (self Otto) SetStackDepthLimit(limit int) {
|
||||
self.runtime.stackLimit = limit
|
||||
}
|
||||
|
||||
// Context is a structure that contains information about the current execution
|
||||
// context.
|
||||
type Context struct {
|
||||
|
|
50
otto_test.go
50
otto_test.go
|
@ -1650,6 +1650,56 @@ func Test_objectLength(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func Test_stackLimit(t *testing.T) {
|
||||
code := `
|
||||
function a() {}
|
||||
function b() { a(); }
|
||||
function c() { b(); }
|
||||
function d() { c(); }
|
||||
function e() { d(); }
|
||||
e();
|
||||
`
|
||||
|
||||
tt(t, func() {
|
||||
_, vm := test()
|
||||
|
||||
_, err := vm.Run(code)
|
||||
|
||||
is(err == nil, true)
|
||||
})
|
||||
|
||||
tt(t, func() {
|
||||
_, vm := test()
|
||||
|
||||
vm.vm.SetStackDepthLimit(2)
|
||||
|
||||
_, err := vm.Run(code)
|
||||
|
||||
is(err == nil, false)
|
||||
})
|
||||
|
||||
tt(t, func() {
|
||||
_, vm := test()
|
||||
|
||||
vm.vm.SetStackDepthLimit(6)
|
||||
|
||||
_, err := vm.Run(code)
|
||||
|
||||
is(err == nil, true)
|
||||
})
|
||||
|
||||
tt(t, func() {
|
||||
_, vm := test()
|
||||
|
||||
vm.vm.SetStackDepthLimit(1)
|
||||
vm.vm.SetStackDepthLimit(0)
|
||||
|
||||
_, err := vm.Run(code)
|
||||
|
||||
is(err == nil, true)
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkNew(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
New()
|
||||
|
|
|
@ -56,6 +56,7 @@ type _runtime struct {
|
|||
eval *_object // The builtin eval, for determine indirect versus direct invocation
|
||||
debugger func(*Otto)
|
||||
random func() float64
|
||||
stackLimit int
|
||||
|
||||
labels []string // FIXME
|
||||
lck sync.Mutex
|
||||
|
@ -63,6 +64,14 @@ type _runtime struct {
|
|||
|
||||
func (self *_runtime) enterScope(scope *_scope) {
|
||||
scope.outer = self.scope
|
||||
if self.scope != nil {
|
||||
scope.depth = self.scope.depth + 1
|
||||
}
|
||||
|
||||
if self.stackLimit != 0 && scope.depth >= self.stackLimit {
|
||||
panic(self.panicRangeError("RangeError: Maximum call stack size exceeded"))
|
||||
}
|
||||
|
||||
self.scope = scope
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user