diff --git a/cmd/kubeadm/app/cmd/util/join.go b/cmd/kubeadm/app/cmd/util/join.go
index cbf58238ab0..feded1d06d7 100644
--- a/cmd/kubeadm/app/cmd/util/join.go
+++ b/cmd/kubeadm/app/cmd/util/join.go
@@ -19,7 +19,7 @@ package util
import (
"bytes"
"crypto/x509"
- "html/template"
+ "html/template" //nolint:depguard
"strings"
"k8s.io/client-go/tools/clientcmd"
diff --git a/hack/golangci-hints.yaml b/hack/golangci-hints.yaml
index 81e5e95e753..66e21cca6e3 100644
--- a/hack/golangci-hints.yaml
+++ b/hack/golangci-hints.yaml
@@ -254,6 +254,8 @@ linters:
deny:
- pkg: "github.com/google/go-cmp/cmp"
desc: "cmp is allowed only in test files"
+ - pkg: "html/template"
+ desc: "template is allowed only in test files as it disables dead code elimination"
forbidigo:
analyze-types: true
forbid:
diff --git a/hack/golangci.yaml b/hack/golangci.yaml
index 2306878a6bf..94dcd95e711 100644
--- a/hack/golangci.yaml
+++ b/hack/golangci.yaml
@@ -268,6 +268,8 @@ linters:
deny:
- pkg: "github.com/google/go-cmp/cmp"
desc: "cmp is allowed only in test files"
+ - pkg: "html/template"
+ desc: "template is allowed only in test files as it disables dead code elimination"
forbidigo:
analyze-types: true
forbid:
diff --git a/hack/golangci.yaml.in b/hack/golangci.yaml.in
index cebfd06fd5e..d6c7373af03 100644
--- a/hack/golangci.yaml.in
+++ b/hack/golangci.yaml.in
@@ -198,6 +198,8 @@ linters:
deny:
- pkg: "github.com/google/go-cmp/cmp"
desc: "cmp is allowed only in test files"
+ - pkg: "html/template"
+ desc: "template is allowed only in test files as it disables dead code elimination"
forbidigo:
analyze-types: true
forbid:
diff --git a/staging/src/k8s.io/apiserver/pkg/server/routes/flags.go b/staging/src/k8s.io/apiserver/pkg/server/routes/flags.go
index e7b4a7c6025..2b18af30a10 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/routes/flags.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/routes/flags.go
@@ -18,7 +18,7 @@ package routes
import (
"fmt"
- "html/template"
+ "html/template" //nolint:depguard
"io"
"net/http"
"path"
@@ -56,12 +56,15 @@ func (f DebugFlags) Install(c *mux.PathRecorderMux, flag string, handler func(ht
func (f DebugFlags) Index(w http.ResponseWriter, r *http.Request) {
lock.RLock()
defer lock.RUnlock()
- if err := indexTmpl.Execute(w, registeredFlags); err != nil {
+ if err := indexTmpl(w, registeredFlags); err != nil {
klog.Error(err)
}
}
-var indexTmpl = template.Must(template.New("index").Parse(`
+func indexTmpl(w io.Writer, flags map[string]debugFlag) error {
+ // avoid using a template to avoid disabling dead code elimination
+ // https://github.com/golang/go/issues/72895
+ _, err := w.Write([]byte(`
/debug/flags/
@@ -70,15 +73,27 @@ var indexTmpl = template.Must(template.New("index").Parse(`
flags:
-{{range .}}
-{{.Flag}}
-{{end}}
-
+`))
+ if err != nil {
+ return err
+ }
+
+ for _, flag := range flags {
+ _, err := fmt.Fprintf(w, `%s
+`, template.HTMLEscapeString(flag.Flag))
+ if err != nil {
+ return err
+ }
+ }
+
+ _, err = w.Write([]byte(`
full flags configurable
`))
+ return err
+}
type debugFlag struct {
Flag string
diff --git a/staging/src/k8s.io/component-base/zpages/statusz/statusz.go b/staging/src/k8s.io/component-base/zpages/statusz/statusz.go
index ef0814e3600..a60f6a0f894 100644
--- a/staging/src/k8s.io/component-base/zpages/statusz/statusz.go
+++ b/staging/src/k8s.io/component-base/zpages/statusz/statusz.go
@@ -17,9 +17,8 @@ limitations under the License.
package statusz
import (
- "bytes"
"fmt"
- "html/template"
+ "html"
"math/rand"
"net/http"
"time"
@@ -35,30 +34,11 @@ var (
const DefaultStatuszPath = "/statusz"
-const (
- headerFmt = `
+const headerFmt = `
%s statusz
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
`
- dataTemplate = `
-Started{{.Delim}} {{.StartTime}}
-Up{{.Delim}} {{.Uptime}}
-Go version{{.Delim}} {{.GoVersion}}
-Binary version{{.Delim}} {{.BinaryVersion}}
-{{if .EmulationVersion}}Emulation version{{.Delim}} {{.EmulationVersion}}{{end}}
-`
-)
-
-type contentFields struct {
- Delim string
- StartTime string
- Uptime string
- GoVersion string
- BinaryVersion string
- EmulationVersion string
-}
-
type mux interface {
Handle(path string, handler http.Handler)
}
@@ -68,25 +48,10 @@ func NewRegistry(effectiveVersion compatibility.EffectiveVersion) statuszRegistr
}
func Install(m mux, componentName string, reg statuszRegistry) {
- dataTmpl, err := initializeTemplates()
- if err != nil {
- klog.Errorf("error while parsing gotemplates: %v", err)
- return
- }
- m.Handle(DefaultStatuszPath, handleStatusz(componentName, dataTmpl, reg))
+ m.Handle(DefaultStatuszPath, handleStatusz(componentName, reg))
}
-func initializeTemplates() (*template.Template, error) {
- d := template.New("data")
- dataTmpl, err := d.Parse(dataTemplate)
- if err != nil {
- return nil, err
- }
-
- return dataTmpl, nil
-}
-
-func handleStatusz(componentName string, dataTmpl *template.Template, reg statuszRegistry) http.HandlerFunc {
+func handleStatusz(componentName string, reg statuszRegistry) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !httputil.AcceptableMediaType(r) {
http.Error(w, httputil.ErrUnsupportedMediaType.Error(), http.StatusNotAcceptable)
@@ -94,7 +59,7 @@ func handleStatusz(componentName string, dataTmpl *template.Template, reg status
}
fmt.Fprintf(w, headerFmt, componentName)
- data, err := populateStatuszData(dataTmpl, reg)
+ data, err := populateStatuszData(reg)
if err != nil {
klog.Errorf("error while populating statusz data: %v", err)
http.Error(w, "error while populating statusz data", http.StatusInternalServerError)
@@ -106,31 +71,28 @@ func handleStatusz(componentName string, dataTmpl *template.Template, reg status
}
}
-func populateStatuszData(tmpl *template.Template, reg statuszRegistry) (string, error) {
- if tmpl == nil {
- return "", fmt.Errorf("received nil template")
- }
-
+func populateStatuszData(reg statuszRegistry) (string, error) {
randomIndex := rand.Intn(len(delimiters))
- data := contentFields{
- Delim: delimiters[randomIndex],
- StartTime: reg.processStartTime().Format(time.UnixDate),
- Uptime: uptime(reg.processStartTime()),
- GoVersion: reg.goVersion(),
- BinaryVersion: reg.binaryVersion().String(),
- }
+ delim := html.EscapeString(delimiters[randomIndex])
+ startTime := html.EscapeString(reg.processStartTime().Format(time.UnixDate))
+ uptime := html.EscapeString(uptime(reg.processStartTime()))
+ goVersion := html.EscapeString(reg.goVersion())
+ binaryVersion := html.EscapeString(reg.binaryVersion().String())
+ var emulationVersion string
if reg.emulationVersion() != nil {
- data.EmulationVersion = reg.emulationVersion().String()
+ emulationVersion = fmt.Sprintf(`Emulation version%s %s`, delim, html.EscapeString(reg.emulationVersion().String()))
}
- var tpl bytes.Buffer
- err := tmpl.Execute(&tpl, data)
- if err != nil {
- return "", fmt.Errorf("error executing statusz template: %w", err)
- }
+ status := fmt.Sprintf(`
+Started%[1]s %[2]s
+Up%[1]s %[3]s
+Go version%[1]s %[4]s
+Binary version%[1]s %[5]s
+%[6]s
+`, delim, startTime, uptime, goVersion, binaryVersion, emulationVersion)
- return tpl.String(), nil
+ return status, nil
}
func uptime(t time.Time) string {