Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/markup/__tests__/PhutilMarkupTestCase.php
12241 views
1
<?php
2
3
final class PhutilMarkupTestCase extends PhutilTestCase {
4
5
public function testTagDefaults() {
6
$this->assertEqual(
7
(string)phutil_tag('br'),
8
(string)phutil_tag('br', array()));
9
10
$this->assertEqual(
11
(string)phutil_tag('br', array()),
12
(string)phutil_tag('br', array(), null));
13
}
14
15
public function testTagEmpty() {
16
$this->assertEqual(
17
'<br />',
18
(string)phutil_tag('br', array(), null));
19
20
$this->assertEqual(
21
'<div></div>',
22
(string)phutil_tag('div', array(), null));
23
24
$this->assertEqual(
25
'<div></div>',
26
(string)phutil_tag('div', array(), ''));
27
}
28
29
public function testTagBasics() {
30
$this->assertEqual(
31
'<br />',
32
(string)phutil_tag('br'));
33
34
$this->assertEqual(
35
'<div>y</div>',
36
(string)phutil_tag('div', array(), 'y'));
37
}
38
39
public function testTagAttributes() {
40
$this->assertEqual(
41
'<div u="v">y</div>',
42
(string)phutil_tag('div', array('u' => 'v'), 'y'));
43
44
$this->assertEqual(
45
'<br u="v" />',
46
(string)phutil_tag('br', array('u' => 'v')));
47
}
48
49
public function testTagEscapes() {
50
$this->assertEqual(
51
'<br u="&lt;" />',
52
(string)phutil_tag('br', array('u' => '<')));
53
54
$this->assertEqual(
55
'<div><br /></div>',
56
(string)phutil_tag('div', array(), phutil_tag('br')));
57
}
58
59
public function testTagNullAttribute() {
60
$this->assertEqual(
61
'<br />',
62
(string)phutil_tag('br', array('y' => null)));
63
}
64
65
public function testTagJavascriptProtocolRejection() {
66
$hrefs = array(
67
'javascript:alert(1)' => true,
68
'JAVASCRIPT:alert(2)' => true,
69
70
// NOTE: When interpreted as a URI, this is dropped because of leading
71
// whitespace.
72
' javascript:alert(3)' => array(true, false),
73
'/' => false,
74
'/path/to/stuff/' => false,
75
'' => false,
76
'http://example.com/' => false,
77
'#' => false,
78
'javascript://anything' => true,
79
80
// Chrome 33 and IE11, at a minimum, treat this as Javascript.
81
"javascript\n:alert(4)" => true,
82
83
// Opera currently accepts a variety of unicode spaces. This test case
84
// has a smattering of them.
85
"\xE2\x80\x89javascript:" => true,
86
"javascript\xE2\x80\x89:" => true,
87
"\xE2\x80\x84javascript:" => true,
88
"javascript\xE2\x80\x84:" => true,
89
90
// Because we're aggressive, all of unicode should trigger detection
91
// by default.
92
"\xE2\x98\x83javascript:" => true,
93
"javascript\xE2\x98\x83:" => true,
94
"\xE2\x98\x83javascript\xE2\x98\x83:" => true,
95
96
// We're aggressive about this, so we'll intentionally raise false
97
// positives in these cases.
98
'javascript~:alert(5)' => true,
99
'!!!javascript!!!!:alert(6)' => true,
100
101
// However, we should raise true negatives in these slightly more
102
// reasonable cases.
103
'javascript/:docs.html' => false,
104
'javascripts:x.png' => false,
105
'COOLjavascript:page' => false,
106
'/javascript:alert(1)' => false,
107
);
108
109
foreach (array(true, false) as $use_uri) {
110
foreach ($hrefs as $href => $expect) {
111
if (is_array($expect)) {
112
$expect = ($use_uri ? $expect[1] : $expect[0]);
113
}
114
115
if ($use_uri) {
116
$href_value = new PhutilURI($href);
117
} else {
118
$href_value = $href;
119
}
120
121
$caught = null;
122
try {
123
phutil_tag('a', array('href' => $href_value), 'click for candy');
124
} catch (Exception $ex) {
125
$caught = $ex;
126
}
127
128
$desc = pht(
129
'Unexpected result for "%s". <uri = %s, expect exception = %s>',
130
$href,
131
$use_uri ? pht('Yes') : pht('No'),
132
$expect ? pht('Yes') : pht('No'));
133
134
$this->assertEqual(
135
$expect,
136
$caught instanceof Exception,
137
$desc);
138
}
139
}
140
}
141
142
public function testURIEscape() {
143
$this->assertEqual(
144
'%2B/%20%3F%23%26%3A%21xyz%25',
145
phutil_escape_uri('+/ ?#&:!xyz%'));
146
}
147
148
public function testURIPathComponentEscape() {
149
$this->assertEqual(
150
'a%252Fb',
151
phutil_escape_uri_path_component('a/b'));
152
153
$str = '';
154
for ($ii = 0; $ii <= 255; $ii++) {
155
$str .= chr($ii);
156
}
157
158
$this->assertEqual(
159
$str,
160
phutil_unescape_uri_path_component(
161
rawurldecode( // Simulates webserver.
162
phutil_escape_uri_path_component($str))));
163
}
164
165
public function testHsprintf() {
166
$this->assertEqual(
167
'<div>&lt;3</div>',
168
(string)hsprintf('<div>%s</div>', '<3'));
169
}
170
171
public function testAppendHTML() {
172
$html = phutil_tag('hr');
173
$html->appendHTML(phutil_tag('br'), '<evil>');
174
$this->assertEqual('<hr /><br />&lt;evil&gt;', $html->getHTMLContent());
175
}
176
177
public function testArrayEscaping() {
178
$this->assertEqual(
179
'<div>&lt;div&gt;</div>',
180
phutil_escape_html(
181
array(
182
hsprintf('<div>'),
183
array(
184
array(
185
'<',
186
array(
187
'd',
188
array(
189
array(
190
hsprintf('i'),
191
),
192
'v',
193
),
194
),
195
array(
196
array(
197
'>',
198
),
199
),
200
),
201
),
202
hsprintf('</div>'),
203
)));
204
205
$this->assertEqual(
206
'<div><br /><hr /><wbr /></div>',
207
phutil_tag(
208
'div',
209
array(),
210
array(
211
array(
212
array(
213
phutil_tag('br'),
214
array(
215
phutil_tag('hr'),
216
),
217
phutil_tag('wbr'),
218
),
219
),
220
))->getHTMLContent());
221
}
222
223
}
224
225