@marcel91200 / caddy Mirror · read-only / commits / 437d5095
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

templates: Use text/template; add experimental notice to docs

Using html/template.HTML like we were doing before caused nested include to be HTML-escaped, which breaks sites. Now we do not escape any of the output; template input is usually trusted, and if it's not, users should employ escaping actions within their templates to keep it safe. The docs already said this.

Matthew Holt committed Apr 6, 2020 at 12:50 UTC 437d5095a6c9aabbabf900417724e655bd4de234
3 files changed +12 -13
modules/caddyhttp/templates/templates.go
+2
@@ -33,6 +33,8 @@ func init() {
33 // The syntax is documented in the Go standard library's
34 // [text/template package](https://golang.org/pkg/text/template/).
35 //
36 +// ⚠️ Template functions/actions are still experimental, so they are subject to change.
37 +//
38 // [All Sprig functions](https://masterminds.github.io/sprig/) are supported.
39 //
40 // In addition to the standard functions and Sprig functions, Caddy adds
modules/caddyhttp/templates/tplcontext.go
+9 -11
@@ -17,7 +17,6 @@ package templates
17 import (
18 "bytes"
19 "fmt"
20 - "html/template"
20 "io"
21 "net"
22 "net/http"
@@ -25,6 +24,7 @@ import (
24 "strconv"
25 "strings"
26 "sync"
27 + "text/template"
28
29 "github.com/Masterminds/sprig/v3"
30 "github.com/alecthomas/chroma/formatters/html"
@@ -57,7 +57,7 @@ func (c templateContext) OriginalReq() http.Request {
57 // Note that included files are NOT escaped, so you should only include
58 // trusted files. If it is not trusted, be sure to use escaping functions
59 // in your template.
60 -func (c templateContext) funcInclude(filename string, args ...interface{}) (template.HTML, error) {
60 +func (c templateContext) funcInclude(filename string, args ...interface{}) (string, error) {
61 if c.Root == nil {
62 return "", fmt.Errorf("root file system not specified")
63 }
@@ -84,14 +84,14 @@ func (c templateContext) funcInclude(filename string, args ...interface{}) (temp
84 return "", err
85 }
86
87 - return template.HTML(bodyBuf.String()), nil
87 + return bodyBuf.String(), nil
88 }
89
90 // funcHTTPInclude returns the body of a virtual (lightweight) request
91 // to the given URI on the same server. Note that included bodies
92 // are NOT escaped, so you should only include trusted resources.
93 // If it is not trusted, be sure to use escaping functions yourself.
94 -func (c templateContext) funcHTTPInclude(uri string) (template.HTML, error) {
94 +func (c templateContext) funcHTTPInclude(uri string) (string, error) {
95 // prevent virtual request loops by counting how many levels
96 // deep we are; and if we get too deep, return an error
97 recursionCount := 1
@@ -132,7 +132,7 @@ func (c templateContext) funcHTTPInclude(uri string) (template.HTML, error) {
132 return "", err
133 }
134
135 - return template.HTML(buf.String()), nil
135 + return buf.String(), nil
136 }
137
138 func (c templateContext) executeTemplateInBuffer(tplName string, buf *bytes.Buffer) error {
@@ -231,7 +231,7 @@ func (c templateContext) funcStripHTML(s string) string {
231
232 // funcMarkdown renders the markdown body as HTML. The resulting
233 // HTML is NOT escaped so that it can be rendered as HTML.
234 -func (c templateContext) funcMarkdown(input interface{}) (template.HTML, error) {
234 +func (c templateContext) funcMarkdown(input interface{}) (string, error) {
235 inputStr := toString(input)
236
237 md := goldmark.New(
@@ -259,7 +259,7 @@ func (c templateContext) funcMarkdown(input interface{}) (template.HTML, error)
259
260 md.Convert([]byte(inputStr), buf)
261
262 - return template.HTML(buf.String()), nil
262 + return buf.String(), nil
263 }
264
265 // splitFrontMatter parses front matter out from the beginning of input,
@@ -338,14 +338,12 @@ func toString(input interface{}) string {
338 switch v := input.(type) {
339 case string:
340 return v
341 - case template.HTML:
342 - return string(v)
341 case fmt.Stringer:
342 return v.String()
343 case error:
344 return v.Error()
345 default:
348 - return fmt.Sprintf("%s", input)
346 + return fmt.Sprintf("%v", input)
347 }
348 }
349
@@ -357,6 +355,6 @@ var bufPool = sync.Pool{
355
356 // at time of writing, sprig.FuncMap() makes a copy, thus
357 // involves iterating the whole map, so do it just once
360 -var sprigFuncMap = sprig.FuncMap()
358 +var sprigFuncMap = sprig.TxtFuncMap()
359
360 const recursionPreventionHeader = "Caddy-Templates-Include"
modules/caddyhttp/templates/tplcontext_test.go
+1 -2
@@ -31,7 +31,6 @@ package templates
31 import (
32 "bytes"
33 "fmt"
34 - "html/template"
34 "io/ioutil"
35 "net/http"
36 "os"
@@ -48,7 +47,7 @@ func TestMarkdown(t *testing.T) {
47
48 for i, test := range []struct {
49 body string
51 - expect template.HTML
50 + expect string
51 }{
52 {
53 body: "- str1\n- str2\n",