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",