Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions templates/template_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,26 +336,27 @@ func TmplText(ctx context.Context, tmpl *Template, alerts []*types.Alert, l log.
if *tmplErr != nil {
return
}
s, *tmplErr = executeTextString(tmpl, name, data)
s, *tmplErr = executeTextStringWithLimit(tmpl, name, data)
return s
}, data
}

func executeTextString(tmpl *Template, text string, data *ExtendedData) (string, error) {
if text == "" {
return "", nil
}
textTmpl := tmpltext.New("").Option("missingkey=zero")
textTmpl, err := textTmpl.Parse(text)
func executeTextStringWithLimit(tmpl *Template, name string, data *ExtendedData) (string, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these names changing? Is this change backported?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are our changes, not a direct backport from upstream.

The upstream v11.6.x fix (grafana/alerting@35f3427554ec) uses tmpl.Text() to get the base
template before applying size limits. But tmpl.Text() doesn't exist in v10's
prometheus-alertmanager (requires Go 1.22+, v10 uses Go 1.21).

So changed the fix to call tmpl.ExecuteTextString(name, data) (the existing v10 method)
and check output size through LimitedWriter afterward. S

The func rename was just to clarify that this now forces size limits.

var buf bytes.Buffer
limitedWriter := utils.NewLimitedWriter(&buf, MaxTemplateOutputSize)

// Use the template's ExecuteTextString but capture output through limited writer
result, err := tmpl.ExecuteTextString(name, data)
if err != nil {
return "", err
}
var buf bytes.Buffer
err = textTmpl.Execute(utils.NewLimitedWriter(&buf, MaxTemplateOutputSize), data)
if errors.Is(err, utils.ErrWriteLimitExceeded) {
err = ErrTemplateOutputTooLarge

_, writeErr := limitedWriter.Write([]byte(result))
if errors.Is(writeErr, utils.ErrWriteLimitExceeded) {
return "", ErrTemplateOutputTooLarge
}
return buf.String(), err

return result, nil
}

// Firing returns the subset of alerts that are firing.
Expand All @@ -379,3 +380,15 @@ func (as ExtendedAlerts) Resolved() []ExtendedAlert {
}
return res
}

// resetTimeNow resets the global variable timeNow to the default value, which is time.Now
func resetTimeNow() {
timeNow = time.Now
}

func mockTimeNow(constTime time.Time) func() {
timeNow = func() time.Time {
return constTime
}
return resetTimeNow
}
Comment on lines +384 to +394
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used by templates/template_data_test.go which was added in the original CVE fix PR (#2) calls mockTimeNow() but the function wasn't
defined anywhere. Found this out when aws-grafana CI ran tests.