ConvertTest.php
8.96 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
<?php
/**
* Test various functions on the {@link Convert} class.
* @package framework
* @subpackage tests
*/
class ConvertTest extends SapphireTest {
/**
* Tests {@link Convert::raw2att()}
*/
public function testRaw2Att() {
$val1 = '<input type="text">';
$this->assertEquals('<input type="text">', Convert::raw2att($val1),
'Special characters are escaped');
$val2 = 'This is some normal text.';
$this->assertEquals('This is some normal text.', Convert::raw2att($val2),
'Normal text is not escaped');
}
/**
* Tests {@link Convert::raw2htmlatt()}
*/
public function testRaw2HtmlAtt() {
$val1 = '<input type="text">';
$this->assertEquals('<input type="text">', Convert::raw2htmlatt($val1),
'Special characters are escaped');
$val2 = 'This is some normal text.';
$this->assertEquals('This is some normal text.', Convert::raw2htmlatt($val2),
'Normal text is not escaped');
}
public function testHtml2raw() {
$val1 = 'This has a <strong>strong tag</strong>.';
$this->assertEquals('This has a *strong tag*.', Convert::xml2raw($val1),
'Strong tags are replaced with asterisks');
$val1 = 'This has a <b class="test" style="font-weight: bold">b tag with attributes</b>.';
$this->assertEquals('This has a *b tag with attributes*.', Convert::xml2raw($val1),
'B tags with attributes are replaced with asterisks');
$val2 = 'This has a <strong class="test" style="font-weight: bold">strong tag with attributes</STRONG>.';
$this->assertEquals('This has a *strong tag with attributes*.', Convert::xml2raw($val2),
'Strong tags with attributes are replaced with asterisks');
$val3 = '<script type="text/javascript">Some really nasty javascript here</script>';
$this->assertEquals('', Convert::xml2raw($val3),
'Script tags are completely removed');
$val4 = '<style type="text/css">Some really nasty CSS here</style>';
$this->assertEquals('', Convert::xml2raw($val4),
'Style tags are completely removed');
$val5 = '<script type="text/javascript">Some really nasty
multiline javascript here</script>';
$this->assertEquals('', Convert::xml2raw($val5),
'Multiline script tags are completely removed');
$val6 = '<style type="text/css">Some really nasty
multiline CSS here</style>';
$this->assertEquals('', Convert::xml2raw($val6),
'Multiline style tags are completely removed');
}
/**
* Tests {@link Convert::raw2xml()}
*/
public function testRaw2Xml() {
$val1 = '<input type="text">';
$this->assertEquals('<input type="text">', Convert::raw2xml($val1),
'Special characters are escaped');
$val2 = 'This is some normal text.';
$this->assertEquals('This is some normal text.', Convert::raw2xml($val2),
'Normal text is not escaped');
$val3 = "This is test\nNow on a new line.";
$this->assertEquals("This is test\nNow on a new line.", Convert::raw2xml($val3),
'Newlines are retained. They should not be replaced with <br /> as it is not XML valid');
}
public function testRaw2HtmlName() {
$val1 = 'test test 123';
$this->assertEquals('testtest123', Convert::raw2htmlname($val1));
}
/**
* Tests {@link Convert::xml2raw()}
*/
public function testXml2Raw() {
$val1 = '<input type="text">';
$this->assertEquals('<input type="text">', Convert::xml2raw($val1), 'Special characters are escaped');
$val2 = 'This is some normal text.';
$this->assertEquals('This is some normal text.', Convert::xml2raw($val2), 'Normal text is not escaped');
}
public function testArray2JSON() {
$val = array(
'Joe' => 'Bloggs',
'Tom' => 'Jones',
'My' => array(
'Complicated' => 'Structure'
)
);
$encoded = Convert::array2json($val);
$this->assertEquals('{"Joe":"Bloggs","Tom":"Jones","My":{"Complicated":"Structure"}}', $encoded,
'Array is encoded in JSON');
}
public function testJSON2Array() {
$val = '{"Joe":"Bloggs","Tom":"Jones","My":{"Complicated":"Structure"}}';
$decoded = Convert::json2array($val);
$this->assertEquals(3, count($decoded), '3 items in the decoded array');
$this->assertContains('Bloggs', $decoded, 'Contains "Bloggs" value in decoded array');
$this->assertContains('Jones', $decoded, 'Contains "Jones" value in decoded array');
$this->assertContains('Structure', $decoded['My']['Complicated']);
}
public function testJSON2Obj() {
$val = '{"Joe":"Bloggs","Tom":"Jones","My":{"Complicated":"Structure"}}';
$obj = Convert::json2obj($val);
$this->assertEquals('Bloggs', $obj->Joe);
$this->assertEquals('Jones', $obj->Tom);
$this->assertEquals('Structure', $obj->My->Complicated);
}
/**
* @todo test toASCII()
*/
public function testRaw2URL() {
$orig = Config::inst()->get('URLSegmentFilter', 'default_allow_multibyte');
Config::inst()->update('URLSegmentFilter', 'default_allow_multibyte', false);
$this->assertEquals('foo', Convert::raw2url('foo'));
$this->assertEquals('foo-and-bar', Convert::raw2url('foo & bar'));
$this->assertEquals('foo-and-bar', Convert::raw2url('foo & bar!'));
$this->assertEquals('foos-bar-2', Convert::raw2url('foo\'s [bar] (2)'));
Config::inst()->update('URLSegmentFilter', 'default_allow_multibyte', $orig);
}
/**
* Helper function for comparing characters with significant whitespaces
* @param type $expected
* @param type $actual
*/
protected function assertEqualsQuoted($expected, $actual) {
$message = sprintf(
"Expected \"%s\" but given \"%s\"",
addcslashes($expected, "\r\n"),
addcslashes($actual, "\r\n")
);
$this->assertEquals($expected, $actual, $message);
}
public function testNL2OS() {
foreach(array("\r\n", "\r", "\n") as $nl) {
// Base case: no action
$this->assertEqualsQuoted(
"Base case",
Convert::nl2os("Base case", $nl)
);
// Mixed formats
$this->assertEqualsQuoted(
"Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}.",
Convert::nl2os("Test\rText\r\nIs\n\rHere\r\n.", $nl)
);
// Test that multiple runs are non-destructive
$expected = "Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}.";
$this->assertEqualsQuoted(
$expected,
Convert::nl2os($expected, $nl)
);
// Check repeated sequence behaves correctly
$expected = "{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}";
$input = "\r\r\n\r\r\n\n\n\n\r";
$this->assertEqualsQuoted(
$expected,
Convert::nl2os($input, $nl)
);
}
}
public function testRaw2JS() {
// Test attempt to break out of string
$this->assertEquals(
'\\"; window.location=\\"http://www.google.com',
Convert::raw2js('"; window.location="http://www.google.com')
);
$this->assertEquals(
'\\\'; window.location=\\\'http://www.google.com',
Convert::raw2js('\'; window.location=\'http://www.google.com')
);
// Test attempt to close script tag
$this->assertEquals(
'\\"; \\x3c/script\\x3e\\x3ch1\\x3eHa \\x26amp; Ha\\x3c/h1\\x3e\\x3cscript\\x3e',
Convert::raw2js('"; </script><h1>Ha & Ha</h1><script>')
);
// Test newlines are properly escaped
$this->assertEquals(
'New\\nLine\\rReturn', Convert::raw2js("New\nLine\rReturn")
);
// Check escape of slashes
$this->assertEquals(
'\\\\\\"\\x3eClick here',
Convert::raw2js('\\">Click here')
);
}
public function testRaw2JSON() {
// Test object
$input = new stdClass();
$input->Title = 'My Object';
$input->Content = '<p>Data</p>';
$this->assertEquals(
'{"Title":"My Object","Content":"<p>Data<\/p>"}',
Convert::raw2json($input)
);
// Array
$array = array('One' => 'Apple', 'Two' => 'Banana');
$this->assertEquals(
'{"One":"Apple","Two":"Banana"}',
Convert::raw2json($array)
);
// String value with already encoded data. Result should be quoted.
$value = '{"Left": "Value"}';
$this->assertEquals(
'"{\\"Left\\": \\"Value\\"}"',
Convert::raw2json($value)
);
}
public function testXML2Array() {
// Ensure an XML file at risk of entity expansion can be avoided safely
$inputXML = <<<XML
<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]>
<results>
<result>Now include &long; lots of times to expand the in-memory size of this XML structure</result>
<result>&long;&long;&long;</result>
</results>
XML
;
try {
Convert::xml2array($inputXML, true);
} catch(Exception $ex) {}
$this->assertTrue(
isset($ex)
&& $ex instanceof InvalidArgumentException
&& $ex->getMessage() === 'XML Doctype parsing disabled'
);
// Test without doctype validation
$expected = array(
'result' => array(
"Now include SOME_SUPER_LONG_STRING lots of times to expand the in-memory size of this XML structure",
array(
'long' => array(
array(
'long' => 'SOME_SUPER_LONG_STRING'
),
array(
'long' => 'SOME_SUPER_LONG_STRING'
),
array(
'long' => 'SOME_SUPER_LONG_STRING'
)
)
)
)
);
$result = Convert::xml2array($inputXML, false, true);
$this->assertEquals(
$expected,
$result
);
$result = Convert::xml2array($inputXML, false, false);
$this->assertEquals(
$expected,
$result
);
}
}