From e77dd369ef13e3eabb86c73571d63642b5396088 Mon Sep 17 00:00:00 2001 From: MaMe82 Date: Mon, 15 Oct 2018 10:26:57 +0200 Subject: [PATCH] Wrapping HIDScript into anonymous, self-invoked function --- cmd/testhid/testhid.go | 10 +++++----- hid/AsyncOtto.go | 21 +++++++++++++++------ hid/controller.go | 8 ++++---- service/triggerAction.go | 18 +++++++++--------- service/usb.go | 4 ++-- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/cmd/testhid/testhid.go b/cmd/testhid/testhid.go index c8fcf66..2638ceb 100644 --- a/cmd/testhid/testhid.go +++ b/cmd/testhid/testhid.go @@ -213,7 +213,7 @@ func TestCombinedScript(hidCtl *hid.HIDController) (err error) { } ` - _,err = hidCtl.RunScript(context.Background(),testcript) + _,err = hidCtl.RunScript(context.Background(),testcript, true) if err != nil {panic(err)} return @@ -253,7 +253,7 @@ func TestMouseCircle(hidCtl *hid.HIDController) { } ` - _,err := hidCtl.RunScript(context.Background(),scriptMouse) + _,err := hidCtl.RunScript(context.Background(),scriptMouse, true) if err != nil { panic(err)} } @@ -273,7 +273,7 @@ func TestControllerReInit() { script := "console.log('...started');delay(3000);console.log('...ended');" ctx := context.Background() for i:=0;i<4;i++ { - job,err := hidCtlTest.StartScriptAsBackgroundJob(ctx, script) + job,err := hidCtlTest.StartScriptAsBackgroundJob(ctx, script, true) if err != nil { fmt.Printf("Error starting new job: %v\n",err) } else { @@ -343,7 +343,7 @@ func main() { script := "console.log('START ' + JID + ' on VM ' + VMID);waitLEDRepeat(ANY,5000);console.log(JID + ' returned from 5s blocking delay');" startTime := time.Now() for i:=1; i<4; i++ { - job,err := hidCtl.StartScriptAsBackgroundJob(ctxT,script) + job,err := hidCtl.StartScriptAsBackgroundJob(ctxT,script,true) if err != nil { fmt.Printf("Failed adding background job: %v\n", err) } else { @@ -377,7 +377,7 @@ func main() { if scriptFile, err := ioutil.ReadFile(filepath); err != nil { log.Printf("Couldn't load HIDScript testfile: %s\n", filepath) } else { - _,err = hidCtl.RunScript(context.Background(),string(scriptFile)) + _,err = hidCtl.RunScript(context.Background(),string(scriptFile), true) if err != nil { panic(err)} } diff --git a/hid/AsyncOtto.go b/hid/AsyncOtto.go index 8529c9b..19e109e 100644 --- a/hid/AsyncOtto.go +++ b/hid/AsyncOtto.go @@ -123,7 +123,7 @@ func (avm *AsyncOttoVM) SetWorking(working bool) { return } -func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}) (job *AsyncOttoJob, err error) { +func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}, anonymousSelfInvoked bool) (job *AsyncOttoJob, err error) { if avm.IsWorking() { return job, errors.New(fmt.Sprintf("VM %d couldn't start new job, because it is still running one")) } @@ -179,10 +179,19 @@ func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}) (job *Asy fmt.Printf("START JOB %d SCRIPT ON VM %d\n", job.Id, avm.Id) //DEBUG //short pre-run to set JobID and VMID (ignore errors) - avm.vm.Run(fmt.Sprintf("JID=%d;VMID=%d;", job.Id, avm.Id)) + avm.vm.Run(fmt.Sprintf("JID=%d;VMID=%d;\n", job.Id, avm.Id)) - job.ResultValue, job.ResultErr = avm.vm.Run(job.Source) //store result - job.SetFinished() // signal job finished + // try to wrap source into a anonymous, self-invoked function, to avoid polluting global scope (only if source is string) + if src, isString := job.Source.(string); isString { + if anonymousSelfInvoked { + src = fmt.Sprintf("(function() {\n%s\n})();",src) + job.ResultValue, job.ResultErr = avm.vm.Run(src) //store result + job.SetFinished() // signal job finished + } + } else { + job.ResultValue, job.ResultErr = avm.vm.Run(job.Source) //store result + job.SetFinished() // signal job finished + } //Emit event + print DEBUG evRes := Event{ Vm: avm, Job: job } @@ -211,8 +220,8 @@ func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}) (job *Asy } -func (avm *AsyncOttoVM) Run(ctx context.Context,src interface{}) (val otto.Value, res error) { - job,err := avm.RunAsync(ctx, src) +func (avm *AsyncOttoVM) Run(ctx context.Context,src interface{}, anonymousSelfInvoked bool) (val otto.Value, res error) { + job,err := avm.RunAsync(ctx, src, anonymousSelfInvoked) if err != nil { return val,err } return job.WaitResult() } diff --git a/hid/controller.go b/hid/controller.go index 1c59029..85d46bd 100644 --- a/hid/controller.go +++ b/hid/controller.go @@ -156,7 +156,7 @@ func (ctl *HIDController) NextUnusedVM() (vm *AsyncOttoVM, err error) { return nil, errors.New("No free JavaScript VM available in pool") } -func (ctl *HIDController) RunScript(ctx context.Context, script string) (val otto.Value, err error) { +func (ctl *HIDController) RunScript(ctx context.Context, script string, anonymousSelfInvoked bool) (val otto.Value, err error) { /* //fetch next free vm from pool avm,err := ctl.NextUnusedVM() @@ -167,7 +167,7 @@ func (ctl *HIDController) RunScript(ctx context.Context, script string) (val ott // use backround job and wait, to force keeping track of job in joblist, in case the result is never fetched due to // remote CLI abort after running endless script (wouldn't cancel the script) - job,err := ctl.StartScriptAsBackgroundJob(ctx, script) + job,err := ctl.StartScriptAsBackgroundJob(ctx, script, anonymousSelfInvoked) if err != nil { return val,err } val,err = ctl.WaitBackgroundJobResult(ctx, job) return @@ -212,7 +212,7 @@ func (ctl *HIDController) retrieveJobFromOtto(vm *otto.Otto) (job *AsyncOttoJob, } } -func (ctl *HIDController) StartScriptAsBackgroundJob(ctx context.Context,script string) (job *AsyncOttoJob, err error) { +func (ctl *HIDController) StartScriptAsBackgroundJob(ctx context.Context,script string, anonymousSelfInvoked bool) (job *AsyncOttoJob, err error) { //fetch next free vm from pool avm,err := ctl.NextUnusedVM() if err != nil { @@ -225,7 +225,7 @@ func (ctl *HIDController) StartScriptAsBackgroundJob(ctx context.Context,script } //try to run script async - job,err = avm.RunAsync(ctx,script) + job,err = avm.RunAsync(ctx,script,anonymousSelfInvoked) if err != nil { return nil, err } ctl.emitEvent(Event{ diff --git a/service/triggerAction.go b/service/triggerAction.go index 7d29865..b8a8ad1 100644 --- a/service/triggerAction.go +++ b/service/triggerAction.go @@ -389,13 +389,13 @@ func (tam *TriggerActionManager) executeActionStartHidScript(evt *pb.Event, ta * fmt.Printf("Trigger '%s' fired -> executing action '%s' ('%s')\n", triggerName, actionName, action.ScriptName) scriptPath := PATH_HID_SCRIPTS + "/" + action.ScriptName - preScript := fmt.Sprintf("TRIGGER='%s';\n", triggerName) + preScript := fmt.Sprintf("var TRIGGER='%s';\n", triggerName) switch tt { case triggerTypeGpioIn: gpioPin := ta.Trigger.(*pb.TriggerAction_GpioIn).GpioIn.GpioNum gpioPinName := pb.GPIONum_name[int32(gpioPin)] - preScript += fmt.Sprintf("GPIO_PIN=%s;\n", gpioPinName) + preScript += fmt.Sprintf("var GPIO_PIN=%s;\n", gpioPinName) case triggerTypeGroupReceiveSequence: groupName := ta.Trigger.(*pb.TriggerAction_GroupReceiveSequence).GroupReceiveSequence.GroupName values := ta.Trigger.(*pb.TriggerAction_GroupReceiveSequence).GroupReceiveSequence.Values @@ -409,23 +409,23 @@ func (tam *TriggerActionManager) executeActionStartHidScript(evt *pb.Event, ta * } } jsArray += "]" - preScript += fmt.Sprintf("GROUP='%s';\n", groupName) + preScript += fmt.Sprintf("var GROUP='%s';\n", groupName) preScript += fmt.Sprintf("var VALUES=%s;\n", jsArray) case triggerTypeGroupReceive: groupName := ta.Trigger.(*pb.TriggerAction_GroupReceive).GroupReceive.GroupName value := ta.Trigger.(*pb.TriggerAction_GroupReceive).GroupReceive.Value - preScript += fmt.Sprintf("GROUP='%s';\n", groupName) - preScript += fmt.Sprintf("VALUE=%d;\n", value) + preScript += fmt.Sprintf("var GROUP='%s';\n", groupName) + preScript += fmt.Sprintf("var VALUE=%d;\n", value) case triggerTypeDhcpLeaseGranted: iface := evt.Values[1].GetTstring() mac := evt.Values[2].GetTstring() ip := evt.Values[3].GetTstring() - preScript += fmt.Sprintf("DHCP_LEASE_IFACE=%s;\n", iface) - preScript += fmt.Sprintf("DHCP_LEASE_MAC=%s;\n", mac) - preScript += fmt.Sprintf("DHCP_LEASE_IP=%s;\n", ip) + preScript += fmt.Sprintf("var DHCP_LEASE_IFACE=%s;\n", iface) + preScript += fmt.Sprintf("var DHCP_LEASE_MAC=%s;\n", mac) + preScript += fmt.Sprintf("var DHCP_LEASE_IP=%s;\n", ip) case triggerTypeSshLogin: loginUser := evt.Values[1].GetTstring() - preScript += fmt.Sprintf("SSH_LOGIN_USER=%s;\n", loginUser) + preScript += fmt.Sprintf("var SSH_LOGIN_USER=%s;\n", loginUser) } diff --git a/service/usb.go b/service/usb.go index 2ccef3e..cf1b9e2 100644 --- a/service/usb.go +++ b/service/usb.go @@ -113,7 +113,7 @@ func (gm *UsbGadgetManager) HidScriptRun(ctx context.Context, scriptContent stri err = gm.HidScriptUsable() if err != nil { return } - scriptVal,err := gm.hidCtl.RunScript(ctx, scriptContent) + scriptVal,err := gm.hidCtl.RunScript(ctx, scriptContent, true) if err != nil { return nil, err} return scriptVal.Export() @@ -123,7 +123,7 @@ func (gm *UsbGadgetManager) HidScriptStartBackground(ctx context.Context, script err = gm.HidScriptUsable() if err != nil { return } - return gm.hidCtl.StartScriptAsBackgroundJob(ctx, scriptContent) + return gm.hidCtl.StartScriptAsBackgroundJob(ctx, scriptContent, true) } //WaitBackgroundJobResult(ctx context.Context, job *AsyncOttoJob) (val otto.Value, err error) {