From e86927211ae6cb09cdcf3872cbe770331222f44f Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 18 Jun 2019 10:32:30 -0400 Subject: [PATCH] Fix bug / leak in JS function processors In an effort to minimize allocations a slice used to hold function arguments is reused rather than allocation new each time a Javascript function processor is used. However there was a typo in re-slicing code so instead of reseting the length to 0 it was a no-op. Hence all future invocations appended to the slice causing a leak. This affects code that uses native Javascript functions in a processor chain (e.g. `new process.Chain().Add(function(event) { event.Put("x", "y"); }).Build()`). --- CHANGELOG.next.asciidoc | 1 + .../script/javascript/module/processor/chain.go | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index d74bf68c2a7..6b9d0ea1b11 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -72,6 +72,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add host.os.codename to fields.yml. {pull}12261[12261] - Fix `@timestamp` being duplicated in events if `@timestamp` is set in a processor (or by any code utilizing `PutValue()` on a `beat.Event`). +- Fix leak in script processor when using Javascript functions in a processor chain. {pull}12600[12600] *Auditbeat* diff --git a/libbeat/processors/script/javascript/module/processor/chain.go b/libbeat/processors/script/javascript/module/processor/chain.go index f86300c213b..dd61022c29c 100644 --- a/libbeat/processors/script/javascript/module/processor/chain.go +++ b/libbeat/processors/script/javascript/module/processor/chain.go @@ -83,7 +83,7 @@ func (b *chainBuilder) Add(call goja.FunctionCall) goja.Value { case *beatProcessor: b.procs = append(b.procs, v.p) case func(goja.FunctionCall) goja.Value: - b.procs = append(b.procs, &jsProcessor{fn: v}) + b.procs = append(b.procs, newJSProcessor(v)) default: panic(b.runtime.NewGoError(errors.Errorf("arg0 must be a processor object, but got %T", a0.Export()))) } @@ -119,9 +119,12 @@ type jsProcessor struct { call goja.FunctionCall } +func newJSProcessor(fn jsFunction) *jsProcessor { + return &jsProcessor{fn: fn, call: goja.FunctionCall{Arguments: make([]goja.Value, 1)}} +} + func (p *jsProcessor) run(event javascript.Event) error { - p.call.Arguments = p.call.Arguments[0:] - p.call.Arguments = append(p.call.Arguments, event.JSObject()) + p.call.Arguments[0] = event.JSObject() p.fn(p.call) return nil }