From 54e6b1c44fe39bb06e94cbbfc87b5885fc6f7445 Mon Sep 17 00:00:00 2001 From: Nikolaus Schuetz Date: Wed, 22 Jul 2026 00:51:47 -0700 Subject: [PATCH] fix: prevent panic on invalid regex in reload annotation ShouldReload compiled each comma-separated value of a named reload annotation (e.g. secret.reloader.stakater.com/reload) with regexp.MustCompile, which panics on an invalid pattern. The value comes straight from a user-set annotation on a watched workload, and the queue worker has no recover(), so a single malformed annotation (e.g. "app-config[") on any workload in any watched namespace crashes Reloader and stops reloads cluster-wide. Use regexp.Compile and, on error, log and skip that pattern instead of panicking. --- pkg/common/common.go | 6 +++++- pkg/common/common_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pkg/common/common.go b/pkg/common/common.go index de37ad86..45de1f19 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -276,7 +276,11 @@ func ShouldReload(config Config, resourceType string, annotations Map, podAnnota values := strings.Split(annotationValue, ",") for _, value := range values { value = strings.TrimSpace(value) - re := regexp.MustCompile("^" + value + "$") + re, err := regexp.Compile("^" + value + "$") + if err != nil { + logrus.Errorf("Invalid regex %q in reload annotation %q on resource '%s' of type '%s'; skipping this pattern: %v", value, config.Annotation, config.ResourceName, config.Type, err) + continue + } if re.Match([]byte(config.ResourceName)) { return ReloadCheckResult{ ShouldReload: true, diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 532d3adf..0bbdab54 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -222,3 +222,27 @@ func TestShouldReload_IssueRBACPermissionFixed(t *testing.T) { }) } } + +// A malformed regex in a named reload annotation must not panic the operator. +// Regression test: previously regexp.MustCompile("^"+value+"$") panicked on an +// invalid pattern, crashing Reloader cluster-wide (no recover on the worker). +func TestShouldReload_InvalidRegexAnnotation_DoesNotPanic(t *testing.T) { + config := Config{ + ResourceName: "app-config", + Annotation: "secret.reloader.stakater.com/reload", + } + annotations := Map{ + // unbalanced bracket => invalid regex + "secret.reloader.stakater.com/reload": "app-config[", + } + opts := &ReloaderOptions{ + ReloaderAutoAnnotation: "reloader.stakater.com/auto", + } + + // Before the fix this panicked inside ShouldReload. + result := ShouldReload(config, "Deployment", annotations, Map{}, opts) + + if result.ShouldReload { + t.Errorf("Expected ShouldReload=false for an invalid regex pattern, got=%v", result.ShouldReload) + } +}