From d32ba3f38cc8ca677d35367267353e73bdbdd7de Mon Sep 17 00:00:00 2001 From: Arpit Jain Date: Sat, 11 Jul 2026 05:50:05 +0900 Subject: [PATCH] fix: do not panic on an invalid image name regexp IsImageMatched interpolates the image name from kustomization images[].name straight into a regexp and discarded the compile error. When the name is not a valid regexp (for example "["), regexp.Compile returns a nil *Regexp and the following MatchString call dereferences it, so kustomize build crashes with a SIGSEGV. Capture the compile error and return false when it is set. A name that can't compile matches no image, which leaves the resource untouched (the same result you get for any name that doesn't match). Adds a unit test for the invalid name and a krusty end-to-end case that builds without panicking. Signed-off-by: Arpit Jain --- api/internal/image/image.go | 9 ++++++- api/internal/image/image_test.go | 8 ++++++ api/krusty/transformersimage_test.go | 39 ++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/api/internal/image/image.go b/api/internal/image/image.go index da6af527a..acc1745dc 100644 --- a/api/internal/image/image.go +++ b/api/internal/image/image.go @@ -21,7 +21,14 @@ func IsImageMatched(s, t string) bool { // using any OCI-valid digest algorithm match consistently with Split, // which accepts any algorithm. // See https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests - pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.{}-]*)?(@[a-zA-Z0-9]+([.+_-][a-zA-Z0-9]+)*:[a-zA-Z0-9_.{}-]*)?$") + // The name t comes from kustomization images[].name and is interpolated + // into the pattern directly, so it can be an invalid regexp (for example + // "["). When it fails to compile, treat it as matching nothing rather than + // dereferencing a nil *Regexp, which would panic during the build. + pattern, err := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.{}-]*)?(@[a-zA-Z0-9]+([.+_-][a-zA-Z0-9]+)*:[a-zA-Z0-9_.{}-]*)?$") + if err != nil { + return false + } return pattern.MatchString(s) } diff --git a/api/internal/image/image_test.go b/api/internal/image/image_test.go index 334f639f1..099cd9216 100644 --- a/api/internal/image/image_test.go +++ b/api/internal/image/image_test.go @@ -75,6 +75,14 @@ func TestIsImageMatched(t *testing.T) { name: "nginx", isMatched: false, }, + { + // A name that is not a valid regexp must not panic. It can't + // compile, so it should simply match nothing. + testName: "name is an invalid regexp", + value: "nginx", + name: "[", + isMatched: false, + }, } for _, tc := range testCases { diff --git a/api/krusty/transformersimage_test.go b/api/krusty/transformersimage_test.go index 38f7d3775..b014f36c3 100644 --- a/api/krusty/transformersimage_test.go +++ b/api/krusty/transformersimage_test.go @@ -401,3 +401,42 @@ spec: image: solsa-echo:foo `) } + +// An images[].name value that is not a valid regexp (here "[") used to crash +// the build with a nil-pointer panic. It should be treated as matching no +// container image, so the resource passes through untouched. +func TestTransfomersImageInvalidNameRegexp(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +resources: +- deploy.yaml +images: +- name: "[" + newTag: v2 +`) + th.WriteF("deploy.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - name: nginx + image: nginx:1.7.9 +`) + m := th.Run(".", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - image: nginx:1.7.9 + name: nginx +`) +}