From 143631f7356d7f2250540c044ae20277f495cc2f Mon Sep 17 00:00:00 2001 From: Mahesh Sadupalli Date: Fri, 3 Jul 2026 20:28:01 +0200 Subject: [PATCH] fix(engine): prevent Files.Lines panic on empty file Files.Lines guards against a nil entry but an empty file inside a chart is stored as a non-nil zero-length byte slice, so the trailing newline check indexes s[-1] and panics. The engine recovers the panic into a render error, making every template/install/upgrade/lint that references the file fail. Extend the guard to len(f[path]) == 0 and return an empty slice, matching the behaviour for missing files. Fixes #32279 Signed-off-by: Mahesh Sadupalli --- pkg/engine/files.go | 2 +- pkg/engine/files_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pkg/engine/files.go b/pkg/engine/files.go index 7834cac2c..eeb04d76c 100644 --- a/pkg/engine/files.go +++ b/pkg/engine/files.go @@ -154,7 +154,7 @@ func (f files) AsSecrets() string { // {{ range .Files.Lines "foo/bar.html" }} // {{ . }}{{ end }} func (f files) Lines(path string) []string { - if f == nil || f[path] == nil { + if f == nil || len(f[path]) == 0 { return []string{} } s := string(f[path]) diff --git a/pkg/engine/files_test.go b/pkg/engine/files_test.go index f07f6afeb..b4318a597 100644 --- a/pkg/engine/files_test.go +++ b/pkg/engine/files_test.go @@ -30,6 +30,8 @@ var cases = []struct { {"story/author.txt", "Joseph Conrad"}, {"multiline/test.txt", "bar\nfoo\n"}, {"multiline/test_with_blank_lines.txt", "bar\nfoo\n\n\n"}, + {"empty/empty.txt", ""}, + {"empty/newline_only.txt", "\n"}, } func getTestFiles() files { @@ -109,3 +111,31 @@ func TestBlankLines(t *testing.T) { as.Equal("bar", out[0]) as.Empty(out[3]) } + +func TestLinesEmptyFile(t *testing.T) { + as := assert.New(t) + + f := getTestFiles() + + out := f.Lines("empty/empty.txt") + as.Empty(out) +} + +func TestLinesNewlineOnlyFile(t *testing.T) { + as := assert.New(t) + + f := getTestFiles() + + out := f.Lines("empty/newline_only.txt") + as.Len(out, 1) + as.Empty(out[0]) +} + +func TestLinesMissingFile(t *testing.T) { + as := assert.New(t) + + f := getTestFiles() + + out := f.Lines("nonexistent.txt") + as.Empty(out) +}