8
8
"strings"
9
9
"testing"
10
10
11
+ "code.gitea.io/gitea/modules/htmlutil"
11
12
"code.gitea.io/gitea/modules/util"
12
13
13
14
"github.com/stretchr/testify/assert"
@@ -65,31 +66,12 @@ func TestSanitizeHTML(t *testing.T) {
65
66
assert .Equal (t , template .HTML (`<a href="/" rel="nofollow">link</a> xss <div>inline</div>` ), SanitizeHTML (`<a href="/">link</a> <a href="javascript:">xss</a> <div style="dangerous">inline</div>` ))
66
67
}
67
68
68
- func TestTemplateTruthy (t * testing.T ) {
69
+ func TestTemplateIif (t * testing.T ) {
69
70
tmpl := template .New ("test" )
70
71
tmpl .Funcs (template.FuncMap {"Iif" : iif })
71
72
template .Must (tmpl .Parse (`{{if .Value}}true{{else}}false{{end}}:{{Iif .Value "true" "false"}}` ))
72
73
73
- cases := []any {
74
- nil , false , true , "" , "string" , 0 , 1 ,
75
- byte (0 ), byte (1 ), int64 (0 ), int64 (1 ), float64 (0 ), float64 (1 ),
76
- complex (0 , 0 ), complex (1 , 0 ),
77
- (chan int )(nil ), make (chan int ),
78
- (func ())(nil ), func () {},
79
- util .ToPointer (0 ), util .ToPointer (util .ToPointer (0 )),
80
- util .ToPointer (1 ), util .ToPointer (util .ToPointer (1 )),
81
- [0 ]int {},
82
- [1 ]int {0 },
83
- []int (nil ),
84
- []int {},
85
- []int {0 },
86
- map [any ]any (nil ),
87
- map [any ]any {},
88
- map [any ]any {"k" : "v" },
89
- (* struct {})(nil ),
90
- struct {}{},
91
- util .ToPointer (struct {}{}),
92
- }
74
+ cases := []any {nil , false , true , "" , "string" , 0 , 1 }
93
75
w := & strings.Builder {}
94
76
truthyCount := 0
95
77
for i , v := range cases {
@@ -102,3 +84,37 @@ func TestTemplateTruthy(t *testing.T) {
102
84
}
103
85
assert .True (t , truthyCount != 0 && truthyCount != len (cases ))
104
86
}
87
+
88
+ func TestTemplateEscape (t * testing.T ) {
89
+ execTmpl := func (code string ) string {
90
+ tmpl := template .New ("test" )
91
+ tmpl .Funcs (template.FuncMap {"QueryBuild" : QueryBuild , "HTMLFormat" : htmlutil .HTMLFormat })
92
+ template .Must (tmpl .Parse (code ))
93
+ w := & strings.Builder {}
94
+ assert .NoError (t , tmpl .Execute (w , nil ))
95
+ return w .String ()
96
+ }
97
+
98
+ t .Run ("Golang URL Escape" , func (t * testing.T ) {
99
+ // Golang template considers "href", "*src*", "*uri*", "*url*" (and more) ... attributes as contentTypeURL and does auto-escaping
100
+ actual := execTmpl (`<a href="?a={{"%"}}"></a>` )
101
+ assert .Equal (t , `<a href="?a=%25"></a>` , actual )
102
+ actual = execTmpl (`<a data-xxx-url="?a={{"%"}}"></a>` )
103
+ assert .Equal (t , `<a data-xxx-url="?a=%25"></a>` , actual )
104
+ })
105
+ t .Run ("Golang URL No-escape" , func (t * testing.T ) {
106
+ // non-URL content isn't auto-escaped
107
+ actual := execTmpl (`<a data-link="?a={{"%"}}"></a>` )
108
+ assert .Equal (t , `<a data-link="?a=%"></a>` , actual )
109
+ })
110
+ t .Run ("QueryBuild" , func (t * testing.T ) {
111
+ actual := execTmpl (`<a href="{{QueryBuild "?" "a" "%"}}"></a>` )
112
+ assert .Equal (t , `<a href="?a=%25"></a>` , actual )
113
+ actual = execTmpl (`<a href="?{{QueryBuild "a" "%"}}"></a>` )
114
+ assert .Equal (t , `<a href="?a=%25"></a>` , actual )
115
+ })
116
+ t .Run ("HTMLFormat" , func (t * testing.T ) {
117
+ actual := execTmpl ("{{HTMLFormat `<a k=\" %s\" >%s</a>` `\" ` `<>`}}" )
118
+ assert .Equal (t , `<a k="""><></a>` , actual )
119
+ })
120
+ }
0 commit comments