mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-11 20:24:15 +00:00
Add SafeJS template function
This commit adds a SafeJS template function. Tests and documentation are included. Fixes #1579
This commit is contained in:
parent
7c9a2dfee2
commit
c5a4c07b89
3 changed files with 56 additions and 1 deletions
|
@ -456,6 +456,21 @@ Example: Given `style = "color: red;"` defined in the front matter of your `.md`
|
||||||
Note: "ZgotmplZ" is a special value that indicates that unsafe content reached a
|
Note: "ZgotmplZ" is a special value that indicates that unsafe content reached a
|
||||||
CSS or URL context.
|
CSS or URL context.
|
||||||
|
|
||||||
|
### safeJS
|
||||||
|
|
||||||
|
Declares the provided string as a known "safe" Javascript string so Go
|
||||||
|
html/templates will not escape it. "Safe" means the string encapsulates a known
|
||||||
|
safe EcmaScript5 Expression, for example, `(x + y * z())`. Template authors
|
||||||
|
are responsible for ensuring that typed expressions do not break the intended
|
||||||
|
precedence and that there is no statement/expression ambiguity as when passing
|
||||||
|
an expression like `{ foo:bar() }\n['foo']()`, which is both a valid Expression
|
||||||
|
and a valid Program with a very different meaning.
|
||||||
|
|
||||||
|
Example: Given `hash = "619c16f"` defined in the front matter of your `.md` file:
|
||||||
|
|
||||||
|
* `<script>var form_{{ .Params.hash | safeJS }};…</script>` ⇒ `<script>var form_619c16f;…</script>` (Good!)
|
||||||
|
* `<script>var form_{{ .Params.hash }};…</script>` ⇒ `<script>var form_"619c16f";…</script>` (Bad!)
|
||||||
|
|
||||||
### singularize
|
### singularize
|
||||||
Singularize the given word with a set of common English singularization rules.
|
Singularize the given word with a set of common English singularization rules.
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package tpl
|
package tpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bitbucket.org/pkg/inflect"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -28,6 +27,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"bitbucket.org/pkg/inflect"
|
||||||
|
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
"github.com/spf13/hugo/helpers"
|
"github.com/spf13/hugo/helpers"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
|
@ -1192,6 +1193,9 @@ func SafeURL(text string) template.URL {
|
||||||
|
|
||||||
func SafeHTML(a string) template.HTML { return template.HTML(a) }
|
func SafeHTML(a string) template.HTML { return template.HTML(a) }
|
||||||
|
|
||||||
|
// SafeJS returns the given string as a template.JS type from html/template.
|
||||||
|
func SafeJS(a string) template.JS { return template.JS(a) }
|
||||||
|
|
||||||
func doArithmetic(a, b interface{}, op rune) (interface{}, error) {
|
func doArithmetic(a, b interface{}, op rune) (interface{}, error) {
|
||||||
av := reflect.ValueOf(a)
|
av := reflect.ValueOf(a)
|
||||||
bv := reflect.ValueOf(b)
|
bv := reflect.ValueOf(b)
|
||||||
|
@ -1393,6 +1397,7 @@ func init() {
|
||||||
"echoParam": ReturnWhenSet,
|
"echoParam": ReturnWhenSet,
|
||||||
"safeHTML": SafeHTML,
|
"safeHTML": SafeHTML,
|
||||||
"safeCSS": SafeCSS,
|
"safeCSS": SafeCSS,
|
||||||
|
"safeJS": SafeJS,
|
||||||
"safeURL": SafeURL,
|
"safeURL": SafeURL,
|
||||||
"absURL": func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) },
|
"absURL": func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) },
|
||||||
"relURL": func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
|
"relURL": func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
|
||||||
|
|
|
@ -1580,6 +1580,41 @@ func TestSafeCSS(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSafeJS(t *testing.T) {
|
||||||
|
for i, this := range []struct {
|
||||||
|
str string
|
||||||
|
tmplStr string
|
||||||
|
expectWithoutEscape string
|
||||||
|
expectWithEscape string
|
||||||
|
}{
|
||||||
|
{`619c16f`, `<script>var x{{ . }};</script>`, `<script>var x"619c16f";</script>`, `<script>var x619c16f;</script>`},
|
||||||
|
} {
|
||||||
|
tmpl, err := template.New("test").Parse(this.tmplStr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
err = tmpl.Execute(buf, this.str)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
|
||||||
|
}
|
||||||
|
if buf.String() != this.expectWithoutEscape {
|
||||||
|
t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
err = tmpl.Execute(buf, SafeJS(this.str))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("[%d] execute template with an escaped string value by SafeJS returns unexpected error: %s", i, err)
|
||||||
|
}
|
||||||
|
if buf.String() != this.expectWithEscape {
|
||||||
|
t.Errorf("[%d] execute template with an escaped string value by SafeJS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSafeURL(t *testing.T) {
|
func TestSafeURL(t *testing.T) {
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
str string
|
str string
|
||||||
|
|
Loading…
Add table
Reference in a new issue