// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package template import ( "bytes" "encoding/json" "fmt" "os" "strings" "testing" "text/template" "text/template/parse" ) type badMarshaler struct{} func (x *badMarshaler) MarshalJSON() ([]byte, error) { // Keys in valid JSON must be double quoted as must all strings. return []byte("{ foo: 'not quite valid JSON' }"), nil } type goodMarshaler struct{} func (x *goodMarshaler) MarshalJSON() ([]byte, error) { return []byte(`{ "": "O'Reilly" }`), nil } func TestEscape(t *testing.T) { data := struct { F, T bool C, G, H, I string A, E []string B, M json.Marshaler N int U any // untyped nil Z *int // typed nil W HTML }{ F: false, T: true, C: "", G: "", H: "", A: []string{"", ""}, E: []string{}, N: 42, B: &badMarshaler{}, M: &goodMarshaler{}, U: nil, Z: nil, W: HTML(`¡Hello, !`), I: "${ asd `` }", } pdata := &data tests := []struct { name string input string output string }{ { "if", "{{if .T}}Hello{{end}}, {{.C}}!", "Hello, <Cincinnati>!", }, { "else", "{{if .F}}{{.H}}{{else}}{{.G}}{{end}}!", "<Goodbye>!", }, { "overescaping1", "Hello, {{.C | html}}!", "Hello, <Cincinnati>!", }, { "overescaping2", "Hello, {{html .C}}!", "Hello, <Cincinnati>!", }, { "overescaping3", "{{with .C}}{{$msg := .}}Hello, {{$msg}}!{{end}}", "Hello, <Cincinnati>!", }, { "assignment", "{{if $x := .H}}{{$x}}{{end}}", "<Hello>", }, { "withBody", "{{with .H}}{{.}}{{end}}", "<Hello>", }, { "withElse", "{{with .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>", }, { "rangeBody", "{{range .A}}{{.}}{{end}}", "<a><b>", }, { "rangeElse", "{{range .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>", }, { "nonStringValue", "{{.T}}", "true", }, { "untypedNilValue", "{{.U}}", "", }, { "typedNilValue", "{{.Z}}", "<nil>", }, { "constant", ``, ``, }, { "multipleAttrs", "", "", }, { "urlStartRel", ``, ``, }, { "urlStartAbsOk", ``, ``, }, { "protocolRelativeURLStart", ``, ``, }, { "pathRelativeURLStart", ``, ``, }, { "dangerousURLStart", ``, ``, }, { "dangerousURLStart2", ``, ``, }, { "nonHierURL", `"}}>`, ``, }, { "urlPath", ``, ``, }, { "urlQuery", ``, ``, }, { "urlFragment", ``, ``, }, { "urlBranch", ``, ``, }, { "urlBranchConflictMoot", ``, ``, }, { "jsStrValue", "