func (p ProbeRunner) Run() { var err error var state *lua.State var fun *luar.LuaObject var res interface{} r := p.Error args := make(map[string]interface{}) if err = json.Unmarshal([]byte(p.Probe.Arguments), &args); err != nil { goto out } state = mkstate() defer state.Close() err = state.DoString(fmt.Sprintf("fun = function(args) %s end", p.Script.Code)) if err != nil { goto out } state.GetGlobal("fun") fun = luar.NewLuaObject(state, -1) if res, err = fun.Call(args); err != nil { goto out } else if res == nil { // if nil, that means no error. just go to out. goto out } else if status, ok := res.(string); !ok { // if it's not a string, that's bad. luar seems to convert go errors to strings.. err = fmt.Errorf("script resulted in non-string return value %q", res) } else if status != "" { // if the string is not empty that's an error. err = fmt.Errorf("probe error: %s", status) } out: r <- err close(r) }
func runUnsafeLua(vm *lua.State, unsafe string) error { start := time.Now() defer func() { duration := time.Since(start) if err := recover(); err != nil { if err == halt { fmt.Println("Some code took too long! Stopping after: ", duration) } panic(err) } }() vm.SetExecutionLimit(maxExecutionTime * (1 << 26)) err := vm.DoString(unsafe) if err.Error() == "Lua execution quantum exceeded" { panic(halt) } return err }
func (p *LuaPlugin) enableDebug(L *lua.State) { L.DoString(inspectLua) L.SetGlobal("inspect") }
// 'exist' is optional. func run(L *lua.State, registryIndex string, code string, input *inputInfo, output *outputInfo, exist *inputInfo) error { // Restore the sandbox. err := L.DoString(luaRestoreSandbox) if err != nil { log.Fatal("Cannot load function to restore sandbox", err) } L.PushString(registryWhitelist) L.GetTable(lua.LUA_REGISTRYINDEX) err = L.Call(1, 0) if err != nil { log.Fatal("Failed to restore sandbox", err) } goToLua(L, "input", *input) goToLua(L, "output", *output) if exist != nil { goToLua(L, "existinfo", *exist) } // Shortcut (mostly for prescript and postscript). L.GetGlobal("input") L.GetField(-1, "tags") L.SetGlobal("i") L.Pop(1) L.GetGlobal("output") L.GetField(-1, "tags") L.SetGlobal("o") L.Pop(1) // Call the compiled script. L.PushString(registryIndex) L.GetTable(lua.LUA_REGISTRYINDEX) L.PushString(code) if L.IsTable(-2) { L.GetTable(-2) if L.IsFunction(-1) { err := L.Call(0, 0) if err != nil { L.SetTop(0) return fmt.Errorf("%s", err) } } else { L.Pop(1) } } else { L.Pop(1) } L.Pop(1) // Allow tags to be numbers for convenience. outputNumbersToStrings(L) L.GetGlobal("output") r := luar.LuaToGo(L, reflect.TypeOf(*output), -1) L.Pop(1) *output = r.(outputInfo) return nil }