From 12073ba52337c8ac98af315e8d0e236dc0302ecd Mon Sep 17 00:00:00 2001 From: Cody Lee Date: Tue, 18 Aug 2026 08:36:50 -0500 Subject: [PATCH] Fix nil-pointer panic in collectEvents for disabled input plugins InputUnifi.Events returns (nil, nil) when disabled, but collectEvents dereferenced e.Logs unconditionally after a successful (err == nil) call, crashing the poller. Same crash class as #1030, found while verifying the recover-based fix. --- pkg/poller/inputs.go | 6 ++++++ pkg/poller/inputs_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/pkg/poller/inputs.go b/pkg/poller/inputs.go index 1546a4f5..4b6d5073 100644 --- a/pkg/poller/inputs.go +++ b/pkg/poller/inputs.go @@ -183,6 +183,12 @@ func collectEvents(filter *Filter, inputs []*InputPlugin) (*Events, error) { return } + if e == nil { + resultChan <- eventInputResult{} + + return + } + resultChan <- eventInputResult{logs: e.Logs} }(input) } diff --git a/pkg/poller/inputs_test.go b/pkg/poller/inputs_test.go index 2206dd09..6a41f2d1 100644 --- a/pkg/poller/inputs_test.go +++ b/pkg/poller/inputs_test.go @@ -46,6 +46,38 @@ func TestCollectMetricsRecoversPanickingInput(t *testing.T) { assert.Contains(t, err.Error(), "panic-input") } +// nilEventsInput simulates a disabled input plugin, which returns (nil, nil) +// from Events. See https://github.com/unpoller/unpoller/issues/1030. +type nilEventsInput struct{} + +func (nilEventsInput) Initialize(poller.Logger) error { return nil } + +func (nilEventsInput) Metrics(*poller.Filter) (*poller.Metrics, error) { return nil, nil } + +func (nilEventsInput) Events(*poller.Filter) (*poller.Events, error) { return nil, nil } + +func (nilEventsInput) RawMetrics(*poller.Filter) ([]byte, error) { return nil, nil } + +func (nilEventsInput) DebugInput() (bool, error) { return false, nil } + +func TestCollectEventsHandlesNilEventsResult(t *testing.T) { + t.Parallel() + + collector := poller.NewTestCollector(t) + collector.AddInput(&poller.InputPlugin{Name: "nil-events-input", Input: nilEventsInput{}}) + + var events *poller.Events + + var err error + + require.NotPanics(t, func() { + events, err = collector.Events(nil) + }) + + assert.NotNil(t, events) + require.NoError(t, err) +} + func TestCollectEventsRecoversPanickingInput(t *testing.T) { t.Parallel()