From 9d7b269499f83e19a49e9e5e8121edeae4da26c7 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 20 Mar 2020 09:52:02 -0700 Subject: [PATCH] fix recursion count in templates backport of #7558 from master Signed-off-by: Matthew Fisher --- pkg/engine/engine.go | 1 + pkg/engine/engine_test.go | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index de9820278..8c7d36112 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -163,6 +163,7 @@ func (e *Engine) alterFuncMap(t *template.Template, referenceTpls map[string]ren if err := t.ExecuteTemplate(buf, name, data); err != nil { return "", err } + includedNames[name]-- return buf.String(), nil } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index c130540aa..14963fda3 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -18,6 +18,7 @@ package engine import ( "fmt" + "strings" "sync" "testing" @@ -604,3 +605,58 @@ func TestAlterFuncMap(t *testing.T) { } } + +func TestRenderRecursionLimit(t *testing.T) { + // endless recursion should produce an error + c := &chart.Chart{ + Metadata: &chart.Metadata{Name: "bad"}, + Templates: []*chart.Template{ + {Name: "templates/base", Data: []byte(`{{include "recursion" . }}`)}, + {Name: "templates/recursion", Data: []byte(`{{define "recursion"}}{{include "recursion" . }}{{end}}`)}, + }, + } + v := chartutil.Values{ + "Values": "", + "Chart": c.Metadata, + "Release": chartutil.Values{ + "Name": "TestRelease", + }, + } + expectErr := "rendering template has a nested reference name: recursion: unable to execute template" + + e := New() + _, err := e.Render(c, v) + if err == nil || !strings.HasSuffix(err.Error(), expectErr) { + t.Errorf("Expected err with suffix: %s", expectErr) + } + + // calling the same function many times is ok + times := 4000 + phrase := "All work and no play makes Jack a dull boy" + printFunc := `{{define "overlook"}}{{printf "` + phrase + `\n"}}{{end}}` + var repeatedIncl string + for i := 0; i < times; i++ { + repeatedIncl += `{{include "overlook" . }}` + } + + d := &chart.Chart{ + Metadata: &chart.Metadata{Name: "overlook"}, + Templates: []*chart.Template{ + {Name: "templates/quote", Data: []byte(repeatedIncl)}, + {Name: "templates/_function", Data: []byte(printFunc)}, + }, + } + + out, err := e.Render(d, v) + if err != nil { + t.Fatal(err) + } + + var expect string + for i := 0; i < times; i++ { + expect += phrase + "\n" + } + if got := out["overlook/templates/quote"]; got != expect { + t.Errorf("Expected %q, got %q (%v)", expect, got, out) + } +}