-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathscript_test.go
More file actions
144 lines (138 loc) · 3.4 KB
/
script_test.go
File metadata and controls
144 lines (138 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) 2017 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 or at
// https://developers.google.com/open-source/licenses/bsd
package safehtml
import (
"strings"
"testing"
)
func TestScriptFromDataAndConstant(t *testing.T) {
testStruct := struct {
ID int
Name string
Data []string
}{
ID: 3,
Name: "Animals",
Data: []string{"Cats", "Dogs", "Hamsters"},
}
for _, test := range [...]struct {
desc string
name stringConstant
data interface{}
script stringConstant
want, err string
}{
{
"string data with HTML special characters",
`myVar`,
`</script>`,
`alert(myVar);`,
`var myVar = "\u003c/script\u003e";
alert(myVar);`, "",
},
{
"output of custom JSON marshaler escaped",
`myVar`,
dataWithUnsafeMarshaler(`"</script>"`),
`alert(myVar);`,
`var myVar = "\u003c/script\u003e";
alert(myVar);`, "",
},
{
"invalid output of custom JSON marshaler rejected",
`myVar`,
dataWithUnsafeMarshaler(`"hello"; alert(1)`),
`alert(myVar);`,
"", "json: error calling MarshalJSON for type safehtml.dataWithUnsafeMarshaler",
},
{
"struct data",
`myVar`,
testStruct,
`alert(myVar);`,
`var myVar = {"ID":3,"Name":"Animals","Data":["Cats","Dogs","Hamsters"]};
alert(myVar);`, "",
},
{
"multi-line script",
`myVar`,
`<foo>`,
`alert(myVar);
alert("hello world!");`,
`var myVar = "\u003cfoo\u003e";
alert(myVar);
alert("hello world!");`, "",
},
{
"empty variable name",
"",
`<foo>`,
`alert(myVar);`,
"", `variable name "" is an invalid Javascript identifier`,
},
{
"invalid variable name",
"café",
`<foo>`,
`alert(myVar);`,
"", `variable name "café" is an invalid Javascript identifier`,
},
{
"JSON encoding error",
`myVar`,
make(chan int),
`alert(myVar);`,
"", "json: unsupported type: chan int",
},
} {
s, err := ScriptFromDataAndConstant(test.name, test.data, test.script)
if test.err != "" && err == nil {
t.Errorf("%s : expected error", test.desc)
} else if test.err != "" && !strings.Contains(err.Error(), test.err) {
t.Errorf("%s : got error:\n\t%s\nwant error:\n\t%s", test.desc, err, test.err)
} else if test.err == "" && err != nil {
t.Errorf("%s : unexpected error: %s", test.desc, err)
} else if got := s.String(); got != test.want {
t.Errorf("%s : got:\n%s\nwant:\n%s", test.desc, got, test.want)
}
}
}
type dataWithUnsafeMarshaler string
func (d dataWithUnsafeMarshaler) MarshalJSON() ([]byte, error) {
return []byte(string(d)), nil
}
func TestJSIdentifierPattern(t *testing.T) {
for _, test := range [...]struct {
in string
want bool
}{
{`foo`, true},
{`Foo`, true},
{`f0o`, true},
{`_f0o`, true},
{`$f0o`, true},
{`f0$_o`, true},
{`_f0$_o`, true},
// Starts with digit.
{`2foo`, false},
// Contains alphabetic codepoints that are not ASCII letters.
{`café`, false},
{`Χαίρετε`, false},
// Contains non-alphabetic codepoints.
{`你好`, false},
// Contains unicode escape sequences.
{`\u0192oo`, false},
{`f\u006Fo`, false},
// Contains zero-width non-joiner.
{"dea\u200Cly", false},
// Contains zero-width joiner.
{"क्\u200D", false},
} {
if got := jsIdentifierPattern.MatchString(test.in); got != test.want {
t.Errorf("jsIdentifierPattern.MatchString(%q) = %t", test.in, got)
}
}
}