[BUGFIX] cmpIPv4: prevent E_NOTICE, cleanup compare, testcases
[Packages/TYPO3.CMS.git] / tests / t3lib / class.t3lib_divTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Testcase for class t3lib_div
27 *
28 * @author Ingo Renner <ingo@typo3.org>
29 * @author Oliver Klee <typo3-coding@oliverklee.de>
30 *
31 * @package TYPO3
32 * @subpackage t3lib
33 */
34 class t3lib_divTest extends tx_phpunit_testcase {
35
36 /**
37 * Enable backup of global and system variables
38 *
39 * @var boolean
40 */
41 protected $backupGlobals = TRUE;
42
43 /**
44 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
45 * because resource types cannot be handled during serializing
46 *
47 * @var array
48 */
49 protected $backupGlobalsBlacklist = array('TYPO3_DB');
50
51 public function tearDown() {
52 t3lib_div::purgeInstances();
53 }
54
55
56 ///////////////////////////////
57 // Tests concerning gif_compress
58 ///////////////////////////////
59
60 /**
61 * @test
62 */
63 public function gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() {
64 if (TYPO3_OS == 'WIN') {
65 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
66 }
67
68 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
69 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available without imagemagick setup.');
70 }
71
72 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
73 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
74
75 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
76
77 // Copy file to unique filename in typo3temp, set target permissions and run method
78 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
79 @copy($fixtureGifFile, $testFilename);
80 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
81 t3lib_div::gif_compress($testFilename, 'IM');
82
83 // Get actual permissions and clean up
84 clearstatcache();
85 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
86 t3lib_div::unlink_tempfile($testFilename);
87
88 $this->assertEquals($resultFilePermissions, '0777');
89 }
90
91 /**
92 * @test
93 */
94 public function gifCompressFixesPermissionOfConvertedFileIfUsingGd() {
95 if (TYPO3_OS == 'WIN') {
96 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
97 }
98
99 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
100 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
101
102 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] = TRUE;
103 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] = FALSE;
104
105 // Copy file to unique filename in typo3temp, set target permissions and run method
106 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
107 @copy($fixtureGifFile, $testFilename);
108 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
109 t3lib_div::gif_compress($testFilename, 'GD');
110
111 // Get actual permissions and clean up
112 clearstatcache();
113 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
114 t3lib_div::unlink_tempfile($testFilename);
115
116 $this->assertEquals($resultFilePermissions, '0777');
117 }
118
119 ///////////////////////////////
120 // Tests concerning png_to_gif_by_imagemagick
121 ///////////////////////////////
122
123 /**
124 * @test
125 */
126 public function pngToGifByImagemagickFixesPermissionsOfConvertedFile() {
127 if (TYPO3_OS == 'WIN') {
128 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available on Windows.');
129 }
130
131 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
132 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
133 }
134
135 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
136 $fixturePngFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.png';
137
138 $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] = TRUE;
139
140 // Copy file to unique filename in typo3temp, set target permissions and run method
141 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.png';
142 @copy($fixturePngFile, $testFilename);
143 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
144 $newGifFile = t3lib_div::png_to_gif_by_imagemagick($testFilename);
145
146 // Get actual permissions and clean up
147 clearstatcache();
148 $resultFilePermissions = substr(decoct(fileperms($newGifFile)), 2);
149 t3lib_div::unlink_tempfile($newGifFile);
150
151 $this->assertEquals($resultFilePermissions, '0777');
152 }
153
154 ///////////////////////////////
155 // Tests concerning read_png_gif
156 ///////////////////////////////
157
158 /**
159 * @test
160 */
161 public function readPngGifFixesPermissionsOfConvertedFile() {
162 if (TYPO3_OS == 'WIN') {
163 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available on Windows.');
164 }
165
166 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
167 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
168 }
169
170 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
171 $testGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
172
173 // Set target permissions and run method
174 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
175 $newPngFile = t3lib_div::read_png_gif($testGifFile, TRUE);
176
177 // Get actual permissions and clean up
178 clearstatcache();
179 $resultFilePermissions = substr(decoct(fileperms($newPngFile)), 2);
180 t3lib_div::unlink_tempfile($newPngFile);
181
182 $this->assertEquals($resultFilePermissions, '0777');
183 }
184
185 ///////////////////////////
186 // Tests concerning cmpIPv4
187 ///////////////////////////
188
189 /**
190 * Data provider for cmpIPv4ReturnsTrueForMatchingAddress
191 *
192 * @return array Data sets
193 */
194 public static function cmpIPv4DataProviderMatching() {
195 return array(
196 'host with full IP address' => array('127.0.0.1', '127.0.0.1'),
197 'host with two wildcards at the end' => array('127.0.0.1', '127.0.*.*'),
198 'host with wildcard at third octet' => array('127.0.0.1', '127.0.*.1'),
199 'host with wildcard at second octet' => array('127.0.0.1', '127.*.0.1'),
200 '/8 subnet' => array('127.0.0.1', '127.1.1.1/8'),
201 '/32 subnet (match only name)' => array('127.0.0.1', '127.0.0.1/32'),
202 '/30 subnet' => array('10.10.3.1', '10.10.3.3/30'),
203 'host with wildcard in list with IPv4/IPv6 addresses' => array('192.168.1.1', '127.0.0.1, 1234:5678::/126, 192.168.*'),
204 'host in list with IPv4/IPv6 addresses' => array('192.168.1.1', '::1, 1234:5678::/126, 192.168.1.1'),
205 );
206 }
207
208 /**
209 * @test
210 * @dataProvider cmpIPv4DataProviderMatching
211 */
212 public function cmpIPv4ReturnsTrueForMatchingAddress($ip, $list) {
213 $this->assertTrue(t3lib_div::cmpIPv4($ip, $list));
214 }
215
216 /**
217 * Data provider for cmpIPv4ReturnsFalseForNotMatchingAddress
218 *
219 * @return array Data sets
220 */
221 public static function cmpIPv4DataProviderNotMatching() {
222 return array(
223 'single host' => array('127.0.0.1', '127.0.0.2'),
224 'single host with wildcard' => array('127.0.0.1', '127.*.1.1'),
225 'single host with /32 subnet mask' => array('127.0.0.1', '127.0.0.2/32'),
226 '/31 subnet' => array('127.0.0.1', '127.0.0.2/31'),
227 'list with IPv4/IPv6 addresses' => array('127.0.0.1', '10.0.2.3, 192.168.1.1, ::1'),
228 'list with only IPv6 addresses' => array('10.20.30.40', '::1, 1234:5678::/127'),
229 );
230 }
231
232 /**
233 * @test
234 * @dataProvider cmpIPv4DataProviderNotMatching
235 */
236 public function cmpIPv4ReturnsFalseForNotMatchingAddress($ip, $list) {
237 $this->assertFalse(t3lib_div::cmpIPv4($ip, $list));
238 }
239 ///////////////////////////
240 // Tests concerning cmpIPv6
241 ///////////////////////////
242
243 /**
244 * Data provider for cmpIPv6ReturnsTrueForMatchingAddress
245 *
246 * @return array Data sets
247 */
248 public static function cmpIPv6DataProviderMatching() {
249 return array(
250 'empty address' => array('::', '::'),
251 'empty with netmask in list' => array('::', '::/0'),
252 'empty with netmask 0 and host-bits set in list' => array('::', '::123/0'),
253 'localhost' => array('::1', '::1'),
254 'localhost with leading zero blocks' => array('::1', '0:0::1'),
255 'host with submask /128' => array('::1', '0:0::1/128'),
256 '/16 subnet' => array('1234::1', '1234:5678::/16'),
257 '/126 subnet' => array('1234:5678::3', '1234:5678::/126'),
258 '/126 subnet with host-bits in list set' => array('1234:5678::3', '1234:5678::2/126'),
259 'list with IPv4/IPv6 addresses' => array('1234:5678::3', '::1, 127.0.0.1, 1234:5678::/126, 192.168.1.1'),
260 );
261 }
262
263 /**
264 * @test
265 * @dataProvider cmpIPv6DataProviderMatching
266 */
267 public function cmpIPv6ReturnsTrueForMatchingAddress($ip, $list) {
268 $this->assertTrue(t3lib_div::cmpIPv6($ip, $list));
269 }
270
271 /**
272 * Data provider for cmpIPv6ReturnsFalseForNotMatchingAddress
273 *
274 * @return array Data sets
275 */
276 public static function cmpIPv6DataProviderNotMatching() {
277 return array(
278 'empty against localhost' => array('::', '::1'),
279 'empty against localhost with /128 netmask' => array('::', '::1/128'),
280 'localhost against different host' => array('::1', '::2'),
281 'localhost against host with prior bits set' => array('::1', '::1:1'),
282 'host against different /17 subnet' => array('1234::1', '1234:f678::/17'),
283 'host against different /127 subnet' => array('1234:5678::3', '1234:5678::/127'),
284 'host against IPv4 address list' => array('1234:5678::3', '127.0.0.1, 192.168.1.1'),
285 'host against mixed list with IPv6 host in different subnet' => array('1234:5678::3', '::1, 1234:5678::/127'),
286 );
287 }
288
289 /**
290 * @test
291 * @dataProvider cmpIPv6DataProviderNotMatching
292 */
293 public function cmpIPv6ReturnsFalseForNotMatchingAddress($ip, $list) {
294 $this->assertFalse(t3lib_div::cmpIPv6($ip, $list));
295 }
296
297 ///////////////////////////////
298 // Tests concerning IPv6Hex2Bin
299 ///////////////////////////////
300
301 /**
302 * Data provider for IPv6Hex2BinReturnsCorrectBinaryHosts
303 *
304 * @return array Data sets
305 */
306 public static function IPv6Hex2BinDataProviderCorrectlyConverted() {
307 return array(
308 'empty 1' => array('::', str_pad('', 16, "\x00")),
309 'empty 2, already normalized' => array('0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")),
310 'empty 3, already normalized' => array('0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"),
311 'expansion in middle 1' => array('1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"),
312 'expansion in middle 2' => array('beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"),
313 );
314 }
315
316 /**
317 * @test
318 * @dataProvider IPv6Hex2BinDataProviderCorrectlyConverted
319 */
320 public function IPv6Hex2BinReturnsCorrectBinaryHosts($inputIP, $binary) {
321 $this->assertTrue(t3lib_div::IPv6Hex2Bin($inputIP) === $binary);
322 }
323
324 /////////////////////////////////
325 // Tests concerning normalizeIPv6
326 /////////////////////////////////
327
328 /**
329 * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat
330 *
331 * @return array Data sets
332 */
333 public static function normalizeIPv6DataProviderCorrectlyNormalized() {
334 return array(
335 'empty' => array('::', '0000:0000:0000:0000:0000:0000:0000:0000'),
336 'localhost' => array('::1', '0000:0000:0000:0000:0000:0000:0000:0001'),
337 'some address on right side' => array('::F0F', '0000:0000:0000:0000:0000:0000:0000:0F0F'),
338 'expansion in middle 1' => array('1::2', '0001:0000:0000:0000:0000:0000:0000:0002'),
339 'expansion in middle 2' => array('1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'),
340 'expansion in middle 3' => array('1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'),
341 'expansion in middle 4' => array('1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005'),
342 );
343 }
344
345 /**
346 * @test
347 * @dataProvider normalizeIPv6DataProviderCorrectlyNormalized
348 */
349 public function normalizeIPv6ReturnsCorrectlyNormalizedFormat($inputIP, $normalized) {
350 $this->assertTrue(t3lib_div::normalizeIPv6($inputIP) === $normalized);
351 }
352
353 ///////////////////////////////
354 // Tests concerning validIP
355 ///////////////////////////////
356
357 /**
358 * Data provider for checkValidIpReturnsTrueForValidIp
359 *
360 * @return array Data sets
361 */
362 public static function validIpDataProvider() {
363 return array(
364 '0.0.0.0' => array('0.0.0.0'),
365 'private IPv4 class C' => array('192.168.0.1'),
366 'private IPv4 class A' => array('10.0.13.1'),
367 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
368 );
369 }
370
371 /**
372 * @test
373 * @dataProvider validIpDataProvider
374 */
375 public function validIpReturnsTrueForValidIp($ip) {
376 $this->assertTrue(t3lib_div::validIP($ip));
377 }
378
379 /**
380 * Data provider for checkValidIpReturnsFalseForInvalidIp
381 *
382 * @return array Data sets
383 */
384 public static function invalidIpDataProvider() {
385 return array(
386 'null' => array(NULL),
387 'zero' => array(0),
388 'string' => array('test'),
389 'string empty' => array(''),
390 'string NULL' => array('NULL'),
391 'out of bounds IPv4' => array('300.300.300.300'),
392 'dotted decimal notation with only two dots' => array('127.0.1'),
393 );
394 }
395
396 /**
397 * @test
398 * @dataProvider invalidIpDataProvider
399 */
400 public function validIpReturnsFalseForInvalidIp($ip) {
401 $this->assertFalse(t3lib_div::validIP($ip));
402 }
403
404 ///////////////////////////////
405 // Tests concerning cmpFQDN
406 ///////////////////////////////
407
408 /**
409 * Data provider for cmpFqdnReturnsTrue
410 *
411 * @return array Data sets
412 */
413 public static function cmpFqdnValidDataProvider() {
414 return array(
415 'localhost should usually resolve, IPv4' => array('127.0.0.1', '*'),
416 'localhost should usually resolve, IPv6' => array('::1', '*'),
417 // other testcases with resolving not possible since it would
418 // require a working IPv4/IPv6-connectivity
419 'aaa.bbb.ccc.ddd.eee, full' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee'),
420 'aaa.bbb.ccc.ddd.eee, wildcard first' => array('aaa.bbb.ccc.ddd.eee', '*.ccc.ddd.eee'),
421 'aaa.bbb.ccc.ddd.eee, wildcard last' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.*'),
422 'aaa.bbb.ccc.ddd.eee, wildcard middle' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.eee'),
423 'list-matches, 1' => array('aaa.bbb.ccc.ddd.eee', 'xxx, yyy, zzz, aaa.*.eee'),
424 'list-matches, 2' => array('aaa.bbb.ccc.ddd.eee', '127:0:0:1,,aaa.*.eee,::1'),
425 );
426 }
427
428 /**
429 * @test
430 * @dataProvider cmpFqdnValidDataProvider
431 */
432 public function cmpFqdnReturnsTrue($baseHost, $list) {
433 $this->assertTrue(t3lib_div::cmpFQDN($baseHost, $list));
434 }
435
436 /**
437 * Data provider for cmpFqdnReturnsFalse
438 *
439 * @return array Data sets
440 */
441 public static function cmpFqdnInvalidDataProvider() {
442 return array(
443 'num-parts of hostname to check can only be less or equal than hostname, 1' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee.fff'),
444 'num-parts of hostname to check can only be less or equal than hostname, 2' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.bbb.ccc.ddd.eee'),
445 );
446 }
447
448 /**
449 * @test
450 * @dataProvider cmpFqdnInvalidDataProvider
451 */
452 public function cmpFqdnReturnsFalse($baseHost, $list) {
453 $this->assertFalse(t3lib_div::cmpFQDN($baseHost, $list));
454 }
455
456
457 ///////////////////////////////
458 // Tests concerning testInt
459 ///////////////////////////////
460
461 /**
462 * Data provider for testIntReturnsTrue
463 *
464 * @return array Data sets
465 */
466 public function functionTestIntValidDataProvider() {
467 return array(
468 'int' => array(32425),
469 'negative int' => array(-32425),
470 'largest int' => array(PHP_INT_MAX),
471 'int as string' => array('32425'),
472 'negative int as string' => array('-32425'),
473 'zero' => array(0),
474 'zero as string' => array('0'),
475 );
476 }
477
478 /**
479 * @test
480 * @dataProvider functionTestIntValidDataProvider
481 */
482 public function testIntReturnsTrue($int) {
483 $this->assertTrue(t3lib_utility_Math::canBeInterpretedAsInteger($int));
484 }
485
486 /**
487 * Data provider for testIntReturnsFalse
488 *
489 * @return array Data sets
490 */
491 public function functionTestIntInvalidDataProvider() {
492 return array(
493 'int as string with leading zero' => array('01234'),
494 'positive int as string with plus modifier' => array('+1234'),
495 'negative int as string with leading zero' => array('-01234'),
496 'largest int plus one' => array(PHP_INT_MAX + 1),
497 'string' => array('testInt'),
498 'empty string' => array(''),
499 'int in string' => array('5 times of testInt'),
500 'int as string with space after' => array('5 '),
501 'int as string with space before' => array(' 5'),
502 'int as string with many spaces before' => array(' 5'),
503 'float' => array(3.14159),
504 'float as string' => array('3.14159'),
505 'float as string only a dot' => array('10.'),
506 'float as string trailing zero would evaluate to int 10' => array('10.0'),
507 'float as string trailing zeros would evaluate to int 10' => array('10.00'),
508 'null' => array(NULL),
509 'empty array' => array(array()),
510 'int in array' => array(array(32425)),
511 'int as string in array' => array(array('32425')),
512 );
513 }
514
515 /**
516 * @test
517 * @dataProvider functionTestIntInvalidDataProvider
518 */
519 public function testIntReturnsFalse($int) {
520 $this->assertFalse(t3lib_utility_Math::canBeInterpretedAsInteger($int));
521 }
522
523
524 ///////////////////////////////
525 // Tests concerning isFirstPartOfStr
526 ///////////////////////////////
527
528 /**
529 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
530 *
531 * @return array
532 */
533 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
534 return array(
535 'match first part of string' => array('hello world', 'hello'),
536 'match whole string' => array('hello', 'hello'),
537 'integer is part of string with same number' => array('24', 24),
538 'string is part of integer with same number' => array(24, '24'),
539 'integer is part of string starting with same number' => array('24 beer please', 24),
540 );
541 }
542
543 /**
544 * @test
545 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
546 */
547 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
548 $this->assertTrue(t3lib_div::isFirstPartOfStr($string, $part));
549 }
550
551 /**
552 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
553 *
554 * @return array
555 */
556 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
557 return array(
558 'no string match' => array('hello', 'bye'),
559 'no case sensitive string match' => array('hello world', 'Hello'),
560 'array is not part of string' => array('string', array()),
561 'string is not part of array' => array(array(), 'string'),
562 'NULL is not part of string' => array('string', NULL),
563 'string is not part of array' => array(NULL, 'string'),
564 'NULL is not part of array' => array(array(), NULL),
565 'array is not part of string' => array(NULL, array()),
566 'empty string is not part of empty string' => array('', ''),
567 'NULL is not part of empty string' => array('', NULL),
568 'false is not part of empty string' => array('', FALSE),
569 'empty string is not part of NULL' => array(NULL, ''),
570 'empty string is not part of false' => array(FALSE, ''),
571 'empty string is not part of zero integer' => array(0, ''),
572 'zero integer is not part of NULL' => array(NULL, 0),
573 'zero integer is not part of empty string' => array('', 0),
574 );
575 }
576
577 /**
578 * @test
579 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
580 */
581 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
582 $this->assertFalse(t3lib_div::isFirstPartOfStr($string, $part));
583 }
584
585
586 ///////////////////////////////
587 // Tests concerning splitCalc
588 ///////////////////////////////
589
590 /**
591 * Data provider for splitCalc
592 *
593 * @return array expected values, arithmetic expression
594 */
595 public function splitCalcDataProvider() {
596 return array(
597 'empty string returns empty array' => array(
598 array(),
599 '',
600 ),
601 'number without operator returns array with plus and number' => array(
602 array(array('+', 42)),
603 '42',
604 ),
605 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
606 array(array('+', 42), array('*', 31)),
607 '42 * 31',
608 ),
609 );
610 }
611
612 /**
613 * @test
614 * @dataProvider splitCalcDataProvider
615 */
616 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
617 $this->assertEquals($expected, t3lib_div::splitCalc($expression, '+-*/'));
618 }
619
620
621 //////////////////////////////////
622 // Tests concerning calcPriority
623 //////////////////////////////////
624
625 /**
626 * Data provider for calcPriority
627 *
628 * @return array expected values, arithmetic expression
629 */
630 public function calcPriorityDataProvider() {
631 return array(
632 'add' => array(9, '6 + 3'),
633 'substract with positive result' => array(3, '6 - 3'),
634 'substract with negative result' => array(-3, '3 - 6'),
635 'multiply' => array(6, '2 * 3'),
636 'divide' => array(2.5, '5 / 2'),
637 'modulus' => array(1, '5 % 2'),
638 'power' => array(8, '2 ^ 3'),
639 'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
640 'three operands with power' => array(14, '5 + 3 ^ 2'),
641 'three operads with modulus' => array(4, '5 % 2 + 3'),
642 'four operands' => array(3, '2 + 6 / 2 - 2'),
643 'division by zero when dividing' => array('ERROR: dividing by zero', '2 / 0'),
644 'division by zero with modulus' => array('ERROR: dividing by zero', '2 % 0')
645 );
646 }
647
648 /**
649 * @test
650 * @dataProvider calcPriorityDataProvider
651 */
652 public function calcPriorityCorrectlyCalculatesExpression($expected, $expression) {
653 $this->assertEquals($expected, t3lib_div::calcPriority($expression));
654 }
655
656 //////////////////////////////////
657 // Tests concerning calcParenthesis
658 //////////////////////////////////
659
660 /**
661 * Data provider for calcParenthesis
662 *
663 * @return array expected values, arithmetic expression
664 */
665 public function calcParenthesisDataProvider() {
666 return array(
667 'starts with parenthesis' => array(18, '(6 + 3) * 2'),
668 'ends with parenthesis' => array(6, '2 * (6 - 3)'),
669 'multiple parentheses' => array(-6, '(3 - 6) * (4 - 2)'),
670 'nested parentheses' => array(22, '2 * (3 + 2 + (3 * 2))'),
671 'parenthesis with division' => array(15, '5 / 2 * (3 * 2)'),
672 );
673 }
674
675 /**
676 * @test
677 * @dataProvider calcParenthesisDataProvider
678 */
679 public function calcParenthesisCorrectlyCalculatesExpression($expected, $expression) {
680 $this->assertEquals($expected, t3lib_div::calcParenthesis($expression));
681 }
682
683 //////////////////////////////////
684 // Tests concerning calcPriority
685 //////////////////////////////////
686
687 /**
688 * Data provider for valid validEmail's
689 *
690 * @return array Valid email addresses
691 */
692 public function validEmailValidDataProvider() {
693 return array(
694 'short mail address' => array('a@b.c'),
695 'simple mail address' => array('test@example.com'),
696 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
697 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
698 // 'equal sign in local part' => array('test=mail@example.com'),
699 'dash in local part' => array('test-mail@example.com'),
700 'plus in local part' => array('test+mail@example.com'),
701 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
702 // 'question mark in local part' => array('test?mail@example.com'),
703 'slash in local part' => array('foo/bar@example.com'),
704 'hash in local part' => array('foo#bar@example.com'),
705 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
706 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
707 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
708 // 'dash as local part' => array('-@foo.com'),
709 );
710 }
711
712 /**
713 * @test
714 * @dataProvider validEmailValidDataProvider
715 */
716 public function validEmailReturnsTrueForValidMailAddress($address) {
717 $this->assertTrue(t3lib_div::validEmail($address));
718 }
719
720 /**
721 * Data provider for invalid validEmail's
722 *
723 * @return array Invalid email addresses
724 */
725 public function validEmailInvalidDataProvider() {
726 return array(
727 '@ sign only' => array('@'),
728 'duplicate @' => array('test@@example.com'),
729 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
730 'opening parenthesis in local part' => array('foo(bar@example.com'),
731 'closing parenthesis in local part' => array('foo)bar@example.com'),
732 'opening square bracket in local part' => array('foo[bar@example.com'),
733 'closing square bracket as local part' => array(']@example.com'),
734 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
735 // 'top level domain only' => array('test@com'),
736 'dash as second level domain' => array('foo@-.com'),
737 'domain part starting with dash' => array('foo@-foo.com'),
738 'domain part ending with dash' => array('foo@foo-.com'),
739 'number as top level domain' => array('foo@bar.123'),
740 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
741 // 'dash as top level domain' => array('foo@bar.-'),
742 'dot at beginning of domain part' => array('test@.com'),
743 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
744 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
745 'trailing whitespace' => array('test@example.com '),
746 'trailing carriage return' => array('test@example.com' . CR),
747 'trailing linefeed' => array('test@example.com' . LF),
748 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
749 'trailing tab' => array('test@example.com' . TAB),
750 );
751 }
752
753 /**
754 * @test
755 * @dataProvider validEmailInvalidDataProvider
756 */
757 public function validEmailReturnsFalseForInvalidMailAddress($address) {
758 $this->assertFalse(t3lib_div::validEmail($address));
759 }
760
761
762 //////////////////////////////////
763 // Tests concerning intExplode
764 //////////////////////////////////
765
766 /**
767 * @test
768 */
769 public function intExplodeConvertsStringsToInteger() {
770 $testString = '1,foo,2';
771 $expectedArray = array(1, 0, 2);
772 $actualArray = t3lib_div::intExplode(',', $testString);
773
774 $this->assertEquals($expectedArray, $actualArray);
775 }
776
777 //////////////////////////////////
778 // Tests concerning intInRange
779 //////////////////////////////////
780 /**
781 * Data provider for intInRangeForcesIntegerIntoBoundaries
782 *
783 * @return array expected values, arithmetic expression
784 */
785 public function intInRangeForcesIntegerIntoDefaultBoundariesDataProvider() {
786 return array(
787 'negativeValue' => array(0, -10),
788 'normalValue' => array(30, 30),
789 'veryHighValue' => array(2000000000, 3000000001),
790 'zeroValue' => array(0, 0),
791 'anotherNormalValue' => array(12309, 12309)
792 );
793 }
794
795 /**
796 * @test
797 * @dataProvider intInRangeForcesIntegerIntoDefaultBoundariesDataProvider
798 */
799 public function intInRangeForcesIntegerIntoDefaultBoundaries($expected, $value) {
800 $this->assertEquals($expected, t3lib_div::intInRange($value, 0));
801 }
802
803 /**
804 * @test
805 */
806 public function intInRangeSetsDefaultValueIfZeroValueIsGiven() {
807 $this->assertEquals(42, t3lib_div::intInRange('', 0, 2000000000, 42));
808 }
809
810 //////////////////////////////////
811 // Tests concerning intval_positive
812 //////////////////////////////////
813 /**
814 * @test
815 */
816 public function intvalPositiveReturnsZeroForNegativeValues() {
817 $this->assertEquals(0, t3lib_div::intval_positive(-123));
818 }
819
820 /**
821 * @test
822 */
823 public function intvalPositiveReturnsTheInputValueForPositiveValues() {
824 $this->assertEquals(123, t3lib_div::intval_positive(123));
825 }
826
827 //////////////////////////////////
828 // Tests concerning int_from_ver
829 //////////////////////////////////
830 /**
831 * Data Provider for intFromVerConvertsVersionNumbersToIntegersDataProvider
832 *
833 * return array
834 */
835 public function intFromVerConvertsVersionNumbersToIntegersDataProvider() {
836 return array(
837 array('4003003', '4.3.3'),
838 array('4012003', '4.12.3'),
839 array('5000000', '5.0.0'),
840 array('3008001', '3.8.1'),
841 array('1012', '0.1.12')
842 );
843 }
844
845 /**
846 * @test
847 * @dataProvider intFromVerConvertsVersionNumbersToIntegersDataProvider
848 */
849 public function intFromVerConvertsVersionNumbersToIntegers($expected, $version) {
850 $this->assertEquals($expected, t3lib_div::int_from_ver($version));
851 }
852
853 //////////////////////////////////
854 // Tests concerning revExplode
855 //////////////////////////////////
856
857 /**
858 * @test
859 */
860 public function revExplodeExplodesString() {
861 $testString = 'my:words:here';
862 $expectedArray = array('my:words', 'here');
863 $actualArray = t3lib_div::revExplode(':', $testString, 2);
864
865 $this->assertEquals($expectedArray, $actualArray);
866 }
867
868
869 //////////////////////////////////
870 // Tests concerning trimExplode
871 //////////////////////////////////
872
873 /**
874 * @test
875 */
876 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
877 $testString = ' a , b , c ,d ,, e,f,';
878 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
879 $actualArray = t3lib_div::trimExplode(',', $testString);
880
881 $this->assertEquals($expectedArray, $actualArray);
882 }
883
884 /**
885 * @test
886 */
887 public function checkTrimExplodeRemovesNewLines() {
888 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
889 $expectedArray = array('a', 'b', 'd', 'e', 'f');
890 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
891
892 $this->assertEquals($expectedArray, $actualArray);
893 }
894
895 /**
896 * @test
897 */
898 public function checkTrimExplodeRemovesEmptyElements() {
899 $testString = 'a , b , c , ,d ,, ,e,f,';
900 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
901 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
902
903 $this->assertEquals($expectedArray, $actualArray);
904 }
905
906 /**
907 * @test
908 */
909 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
910 $testString = ' a , b , c , , d,, ,e ';
911 $expectedArray = array('a', 'b', 'c,,d,,,e');
912 // Limiting returns the rest of the string as the last element
913 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
914
915 $this->assertEquals($expectedArray, $actualArray);
916 }
917
918 /**
919 * @test
920 */
921 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
922 $testString = ' a , b , c , , d,, ,e ';
923 $expectedArray = array('a', 'b', 'c,d,e');
924 // Limiting returns the rest of the string as the last element
925 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
926
927 $this->assertEquals($expectedArray, $actualArray);
928 }
929
930 /**
931 * @test
932 */
933 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
934 $testString = ' a , b , c , d, ,e, f , , ';
935 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
936 // limiting returns the rest of the string as the last element
937 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
938
939 $this->assertEquals($expectedArray, $actualArray);
940 }
941
942 /**
943 * @test
944 */
945 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
946 $testString = ' a , b , c , d, ,e, f , , ';
947 $expectedArray = array('a', 'b', 'c');
948 // Limiting returns the rest of the string as the last element
949 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
950
951 $this->assertEquals($expectedArray, $actualArray);
952 }
953
954 /**
955 * @test
956 */
957 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
958 $testString = ' a , b , , c , , , ';
959 $expectedArray = array('a', 'b', 'c');
960 // Limiting returns the rest of the string as the last element
961 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
962
963 $this->assertEquals($expectedArray, $actualArray);
964 }
965
966 /**
967 * @test
968 */
969 public function checkTrimExplodeKeepsZeroAsString() {
970 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
971 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
972 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
973
974 $this->assertEquals($expectedArray, $actualArray);
975 }
976
977
978 //////////////////////////////////
979 // Tests concerning removeArrayEntryByValue
980 //////////////////////////////////
981
982 /**
983 * @test
984 */
985 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
986 $inputArray = array(
987 '0' => 'test1',
988 '1' => 'test2',
989 '2' => 'test3',
990 '3' => 'test2',
991 );
992 $compareValue = 'test2';
993 $expectedResult = array(
994 '0' => 'test1',
995 '2' => 'test3',
996 );
997 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
998 $this->assertEquals($expectedResult, $actualResult);
999 }
1000
1001 /**
1002 * @test
1003 */
1004 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
1005 $inputArray = array(
1006 '0' => 'foo',
1007 '1' => array(
1008 '10' => 'bar',
1009 ),
1010 '2' => 'bar',
1011 );
1012 $compareValue = 'bar';
1013 $expectedResult = array(
1014 '0' => 'foo',
1015 '1' => array(),
1016 );
1017 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1018 $this->assertEquals($expectedResult, $actualResult);
1019 }
1020
1021 /**
1022 * @test
1023 */
1024 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
1025 $inputArray = array(
1026 '0' => 'foo',
1027 '1' => '',
1028 '2' => 'bar',
1029 );
1030 $compareValue = '';
1031 $expectedResult = array(
1032 '0' => 'foo',
1033 '2' => 'bar',
1034 );
1035 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1036 $this->assertEquals($expectedResult, $actualResult);
1037 }
1038
1039 //////////////////////////////////
1040 // Tests concerning getBytesFromSizeMeasurement
1041 //////////////////////////////////
1042
1043 /**
1044 * Data provider for getBytesFromSizeMeasurement
1045 *
1046 * @return array expected value, input string
1047 */
1048 public function getBytesFromSizeMeasurementDataProvider() {
1049 return array(
1050 '100 kilo Bytes' => array('102400', '100k'),
1051 '100 mega Bytes' => array('104857600', '100m'),
1052 '100 giga Bytes' => array('107374182400', '100g'),
1053 );
1054 }
1055
1056 /**
1057 * @test
1058 * @dataProvider getBytesFromSizeMeasurementDataProvider
1059 */
1060 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
1061 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
1062 }
1063
1064
1065 //////////////////////////////////
1066 // Tests concerning getIndpEnv
1067 //////////////////////////////////
1068
1069 /**
1070 * @test
1071 */
1072 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
1073 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
1074 }
1075
1076 /**
1077 * @test
1078 */
1079 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
1080 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1081 $this->assertEquals('/', $result[0]);
1082 }
1083
1084 /**
1085 * @test
1086 */
1087 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
1088 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1089 $this->assertEquals('/', $result[strlen($result) - 1]);
1090 }
1091
1092 /**
1093 * @return array
1094 */
1095 public static function hostnameAndPortDataProvider() {
1096 return array(
1097 'localhost ipv4 without port' => array('127.0.0.1', '127.0.0.1', ''),
1098 'localhost ipv4 with port' => array('127.0.0.1:81', '127.0.0.1', '81'),
1099 'localhost ipv6 without port' => array('[::1]', '[::1]', ''),
1100 'localhost ipv6 with port' => array('[::1]:81', '[::1]', '81'),
1101 'ipv6 without port' => array('[2001:DB8::1]', '[2001:DB8::1]', ''),
1102 'ipv6 with port' => array('[2001:DB8::1]:81', '[2001:DB8::1]', '81'),
1103 'hostname without port' => array('lolli.did.this', 'lolli.did.this', ''),
1104 'hostname with port' => array('lolli.did.this:42', 'lolli.did.this', '42'),
1105 );
1106 }
1107
1108 /**
1109 * @test
1110 * @dataProvider hostnameAndPortDataProvider
1111 */
1112 public function getIndpEnvTypo3HostOnlyParsesHostnamesAndIpAdresses($httpHost, $expectedIp) {
1113 $_SERVER['HTTP_HOST'] = $httpHost;
1114 $this->assertEquals($expectedIp, t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'));
1115 }
1116
1117 /**
1118 * @test
1119 * @dataProvider hostnameAndPortDataProvider
1120 */
1121 public function getIndpEnvTypo3PortParsesHostnamesAndIpAdresses($httpHost, $dummy, $expectedPort) {
1122 $_SERVER['HTTP_HOST'] = $httpHost;
1123 $this->assertEquals($expectedPort, t3lib_div::getIndpEnv('TYPO3_PORT'));
1124 }
1125
1126
1127 //////////////////////////////////
1128 // Tests concerning underscoredToUpperCamelCase
1129 //////////////////////////////////
1130
1131 /**
1132 * Data provider for underscoredToUpperCamelCase
1133 *
1134 * @return array expected, input string
1135 */
1136 public function underscoredToUpperCamelCaseDataProvider() {
1137 return array(
1138 'single word' => array('Blogexample', 'blogexample'),
1139 'multiple words' => array('BlogExample', 'blog_example'),
1140 );
1141 }
1142
1143 /**
1144 * @test
1145 * @dataProvider underscoredToUpperCamelCaseDataProvider
1146 */
1147 public function underscoredToUpperCamelCase($expected, $inputString) {
1148 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
1149 }
1150
1151
1152 //////////////////////////////////
1153 // Tests concerning underscoredToLowerCamelCase
1154 //////////////////////////////////
1155
1156 /**
1157 * Data provider for underscoredToLowerCamelCase
1158 *
1159 * @return array expected, input string
1160 */
1161 public function underscoredToLowerCamelCaseDataProvider() {
1162 return array(
1163 'single word' => array('minimalvalue', 'minimalvalue'),
1164 'multiple words' => array('minimalValue', 'minimal_value'),
1165 );
1166 }
1167
1168 /**
1169 * @test
1170 * @dataProvider underscoredToLowerCamelCaseDataProvider
1171 */
1172 public function underscoredToLowerCamelCase($expected, $inputString) {
1173 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
1174 }
1175
1176 //////////////////////////////////
1177 // Tests concerning camelCaseToLowerCaseUnderscored
1178 //////////////////////////////////
1179
1180 /**
1181 * Data provider for camelCaseToLowerCaseUnderscored
1182 *
1183 * @return array expected, input string
1184 */
1185 public function camelCaseToLowerCaseUnderscoredDataProvider() {
1186 return array(
1187 'single word' => array('blogexample', 'blogexample'),
1188 'single word starting upper case' => array('blogexample', 'Blogexample'),
1189 'two words starting lower case' => array('minimal_value', 'minimalValue'),
1190 'two words starting upper case' => array('blog_example', 'BlogExample'),
1191 );
1192 }
1193
1194 /**
1195 * @test
1196 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
1197 */
1198 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
1199 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
1200 }
1201
1202
1203 //////////////////////////////////
1204 // Tests concerning lcFirst
1205 //////////////////////////////////
1206
1207 /**
1208 * Data provider for lcFirst
1209 *
1210 * @return array expected, input string
1211 */
1212 public function lcfirstDataProvider() {
1213 return array(
1214 'single word' => array('blogexample', 'blogexample'),
1215 'single Word starting upper case' => array('blogexample', 'Blogexample'),
1216 'two words' => array('blogExample', 'BlogExample'),
1217 );
1218 }
1219
1220 /**
1221 * @test
1222 * @dataProvider lcfirstDataProvider
1223 */
1224 public function lcFirst($expected, $inputString) {
1225 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
1226 }
1227
1228
1229 //////////////////////////////////
1230 // Tests concerning encodeHeader
1231 //////////////////////////////////
1232
1233 /**
1234 * @test
1235 */
1236 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
1237 $this->assertEquals(
1238 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
1239 t3lib_div::encodeHeader(
1240 "We test whether the copyright character \xc2\xa9 is encoded correctly",
1241 'quoted-printable',
1242 'utf-8'
1243 )
1244 );
1245 }
1246
1247 /**
1248 * @test
1249 */
1250 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
1251 $this->assertEquals(
1252 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
1253 t3lib_div::encodeHeader(
1254 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
1255 'quoted-printable',
1256 'utf-8'
1257 )
1258 );
1259 }
1260
1261
1262 //////////////////////////////////
1263 // Tests concerning isValidUrl
1264 //////////////////////////////////
1265
1266 /**
1267 * Data provider for valid isValidUrl's
1268 *
1269 * @return array Valid ressource
1270 */
1271 public function validUrlValidRessourceDataProvider() {
1272 return array(
1273 'http' => array('http://www.example.org/'),
1274 'http without trailing slash' => array('http://qwe'),
1275 'http directory with trailing slash' => array('http://www.example/img/dir/'),
1276 'http directory without trailing slash' => array('http://www.example/img/dir'),
1277 'http index.html' => array('http://example.com/index.html'),
1278 'http index.php' => array('http://www.example.com/index.php'),
1279 'http test.png' => array('http://www.example/img/test.png'),
1280 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
1281 'file' => array('file:///tmp/test.c'),
1282 'file directory' => array('file://foo/bar'),
1283 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
1284 'mailto' => array('mailto:foo@bar.com'),
1285 'news' => array('news:news.php.net'),
1286 'telnet'=> array('telnet://192.0.2.16:80/'),
1287 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
1288 );
1289 }
1290
1291 /**
1292 * @test
1293 * @dataProvider validUrlValidRessourceDataProvider
1294 */
1295 public function validURLReturnsTrueForValidRessource($url) {
1296 $this->assertTrue(t3lib_div::isValidUrl($url));
1297 }
1298
1299 /**
1300 * Data provider for invalid isValidUrl's
1301 *
1302 * @return array Invalid ressource
1303 */
1304 public function isValidUrlInvalidRessourceDataProvider() {
1305 return array(
1306 'http missing colon' => array('http//www.example/wrong/url/'),
1307 'http missing slash' => array('http:/www.example'),
1308 'hostname only' => array('www.example.org/'),
1309 'file missing protocol specification' => array('/tmp/test.c'),
1310 'slash only' => array('/'),
1311 'string http://' => array('http://'),
1312 'string http:/' => array('http:/'),
1313 'string http:' => array('http:'),
1314 'string http' => array('http'),
1315 'empty string' => array(''),
1316 'string -1' => array('-1'),
1317 'string array()' => array('array()'),
1318 'random string' => array('qwe'),
1319 );
1320 }
1321
1322 /**
1323 * @test
1324 * @dataProvider isValidUrlInvalidRessourceDataProvider
1325 */
1326 public function validURLReturnsFalseForInvalidRessoure($url) {
1327 $this->assertFalse(t3lib_div::isValidUrl($url));
1328 }
1329
1330
1331 //////////////////////////////////
1332 // Tests concerning isOnCurrentHost
1333 //////////////////////////////////
1334
1335 /**
1336 * @test
1337 */
1338 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
1339 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
1340 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
1341 }
1342
1343 /**
1344 * Data provider for invalid isOnCurrentHost's
1345 *
1346 * @return array Invalid Hosts
1347 */
1348 public function checkisOnCurrentHostInvalidHosts() {
1349 return array(
1350 'empty string' => array(''),
1351 'arbitrary string' => array('arbitrary string'),
1352 'localhost IP' => array('127.0.0.1'),
1353 'relative path' => array('./relpath/file.txt'),
1354 'absolute path' => array('/abspath/file.txt?arg=value'),
1355 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
1356 );
1357 }
1358
1359
1360 ////////////////////////////////////////
1361 // Tests concerning sanitizeLocalUrl
1362 ////////////////////////////////////////
1363
1364 /**
1365 * Data provider for valid sanitizeLocalUrl's
1366 *
1367 * @return array Valid url
1368 */
1369 public function sanitizeLocalUrlValidUrlDataProvider() {
1370 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1371 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1372 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
1373
1374 return array(
1375 'alt_intro.php' => array('alt_intro.php'),
1376 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1377 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1378 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1379 '../index.php' => array('../index.php'),
1380 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1381 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1382 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1383 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
1384 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1385 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
1386 );
1387 }
1388
1389 /**
1390 * @test
1391 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1392 */
1393 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1394 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
1395 }
1396
1397 /**
1398 * @test
1399 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1400 */
1401 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
1402 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1403 }
1404
1405 /**
1406 * Data provider for invalid sanitizeLocalUrl's
1407 *
1408 * @return array Valid url
1409 */
1410 public function sanitizeLocalUrlInvalidDataProvider() {
1411 return array(
1412 'empty string' => array(''),
1413 'http domain' => array('http://www.google.de/'),
1414 'https domain' => array('https://www.google.de/'),
1415 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
1416 );
1417 }
1418
1419 /**
1420 * @test
1421 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1422 */
1423 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
1424 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
1425 }
1426
1427 /**
1428 * @test
1429 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1430 */
1431 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
1432 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1433 }
1434
1435
1436 //////////////////////////////////////
1437 // Tests concerning addSlashesOnArray
1438 //////////////////////////////////////
1439
1440 /**
1441 * @test
1442 */
1443 public function addSlashesOnArrayAddsSlashesRecursive() {
1444 $inputArray = array(
1445 'key1' => array(
1446 'key11' => "val'ue1",
1447 'key12' => 'val"ue2',
1448 ),
1449 'key2' => 'val\ue3',
1450 );
1451 $expectedResult = array(
1452 'key1' => array(
1453 'key11' => "val\'ue1",
1454 'key12' => 'val\"ue2',
1455 ),
1456 'key2' => 'val\\\\ue3',
1457 );
1458 t3lib_div::addSlashesOnArray($inputArray);
1459 $this->assertEquals(
1460 $expectedResult,
1461 $inputArray
1462 );
1463 }
1464
1465
1466 //////////////////////////////////////
1467 // Tests concerning addSlashesOnArray
1468 //////////////////////////////////////
1469
1470 /**
1471 * @test
1472 */
1473 public function stripSlashesOnArrayStripsSlashesRecursive() {
1474 $inputArray = array(
1475 'key1' => array(
1476 'key11' => "val\'ue1",
1477 'key12' => 'val\"ue2',
1478 ),
1479 'key2' => 'val\\\\ue3',
1480 );
1481 $expectedResult = array(
1482 'key1' => array(
1483 'key11' => "val'ue1",
1484 'key12' => 'val"ue2',
1485 ),
1486 'key2' => 'val\ue3',
1487 );
1488 t3lib_div::stripSlashesOnArray($inputArray);
1489 $this->assertEquals(
1490 $expectedResult,
1491 $inputArray
1492 );
1493 }
1494
1495
1496 //////////////////////////////////////
1497 // Tests concerning arrayDiffAssocRecursive
1498 //////////////////////////////////////
1499
1500 /**
1501 * @test
1502 */
1503 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1504 $array1 = array(
1505 'key1' => 'value1',
1506 'key2' => 'value2',
1507 'key3' => 'value3',
1508 );
1509 $array2 = array(
1510 'key1' => 'value1',
1511 'key3' => 'value3',
1512 );
1513 $expectedResult = array(
1514 'key2' => 'value2',
1515 );
1516 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1517 $this->assertEquals($expectedResult, $actualResult);
1518 }
1519
1520 /**
1521 * @test
1522 */
1523 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1524 $array1 = array(
1525 'key1' => 'value1',
1526 'key2' => array(
1527 'key21' => 'value21',
1528 'key22' => 'value22',
1529 'key23' => array(
1530 'key231' => 'value231',
1531 'key232' => 'value232',
1532 ),
1533 ),
1534 );
1535 $array2 = array(
1536 'key1' => 'value1',
1537 'key2' => array(
1538 'key21' => 'value21',
1539 'key23' => array(
1540 'key231' => 'value231',
1541 ),
1542 ),
1543 );
1544 $expectedResult = array(
1545 'key2' => array(
1546 'key22' => 'value22',
1547 'key23' => array(
1548 'key232' => 'value232',
1549 ),
1550 ),
1551 );
1552 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1553 $this->assertEquals($expectedResult, $actualResult);
1554 }
1555
1556 /**
1557 * @test
1558 */
1559 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1560 $array1 = array(
1561 'key1' => array(
1562 'key11' => 'value11',
1563 'key12' => 'value12',
1564 ),
1565 'key2' => 'value2',
1566 'key3' => 'value3',
1567 );
1568 $array2 = array(
1569 'key1' => 'value1',
1570 'key2' => array(
1571 'key21' => 'value21',
1572 ),
1573 );
1574 $expectedResult = array(
1575 'key3' => 'value3',
1576 );
1577 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1578 $this->assertEquals($expectedResult, $actualResult);
1579 }
1580
1581
1582 //////////////////////////////////////
1583 // Tests concerning removeDotsFromTS
1584 //////////////////////////////////////
1585
1586 /**
1587 * @test
1588 */
1589 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1590 $typoScript = array(
1591 'propertyA.' => array(
1592 'keyA.' => array(
1593 'valueA' => 1,
1594 ),
1595 'keyB' => 2,
1596 ),
1597 'propertyB' => 3,
1598 );
1599
1600 $expectedResult = array(
1601 'propertyA' => array(
1602 'keyA' => array(
1603 'valueA' => 1,
1604 ),
1605 'keyB' => 2,
1606 ),
1607 'propertyB' => 3,
1608 );
1609
1610 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1611 }
1612
1613 /**
1614 * @test
1615 */
1616 public function removeDotsFromTypoScriptOverridesSubArray() {
1617 $typoScript = array(
1618 'propertyA.' => array(
1619 'keyA' => 'getsOverridden',
1620 'keyA.' => array(
1621 'valueA' => 1,
1622 ),
1623 'keyB' => 2,
1624 ),
1625 'propertyB' => 3,
1626 );
1627
1628 $expectedResult = array(
1629 'propertyA' => array(
1630 'keyA' => array(
1631 'valueA' => 1,
1632 ),
1633 'keyB' => 2,
1634 ),
1635 'propertyB' => 3,
1636 );
1637
1638 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1639 }
1640
1641 /**
1642 * @test
1643 */
1644 public function removeDotsFromTypoScriptOverridesWithScalar() {
1645 $typoScript = array(
1646 'propertyA.' => array(
1647 'keyA.' => array(
1648 'valueA' => 1,
1649 ),
1650 'keyA' => 'willOverride',
1651 'keyB' => 2,
1652 ),
1653 'propertyB' => 3,
1654 );
1655
1656 $expectedResult = array(
1657 'propertyA' => array(
1658 'keyA' => 'willOverride',
1659 'keyB' => 2,
1660 ),
1661 'propertyB' => 3,
1662 );
1663
1664 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1665 }
1666
1667 //////////////////////////////////////
1668 // Tests concerning naturalKeySortRecursive
1669 //////////////////////////////////////
1670
1671 /**
1672 * @test
1673 */
1674 public function naturalKeySortRecursiveReturnsFalseIfInputIsNotAnArray() {
1675 $testValues = array(
1676 1,
1677 'string',
1678 FALSE
1679 );
1680 foreach($testValues as $testValue) {
1681 $this->assertFalse(t3lib_div::naturalKeySortRecursive($testValue));
1682 }
1683 }
1684
1685 /**
1686 * @test
1687 */
1688 public function naturalKeySortRecursiveSortsOneDimensionalArrayByNaturalOrder() {
1689 $testArray = array(
1690 'bb' => 'bb',
1691 'ab' => 'ab',
1692 '123' => '123',
1693 'aaa' => 'aaa',
1694 'abc' => 'abc',
1695 '23' => '23',
1696 'ba' => 'ba',
1697 'bad' => 'bad',
1698 '2' => '2',
1699 'zap' => 'zap',
1700 '210' => '210'
1701 );
1702 $expectedResult = array(
1703 '2',
1704 '23',
1705 '123',
1706 '210',
1707 'aaa',
1708 'ab',
1709 'abc',
1710 'ba',
1711 'bad',
1712 'bb',
1713 'zap'
1714 );
1715 t3lib_div::naturalKeySortRecursive($testArray);
1716 $this->assertEquals($expectedResult, array_values($testArray));
1717 }
1718
1719 /**
1720 * @test
1721 */
1722 public function naturalKeySortRecursiveSortsMultiDimensionalArrayByNaturalOrder() {
1723 $testArray = array(
1724 '2' => '2',
1725 'bb' => 'bb',
1726 'ab' => 'ab',
1727 '23' => '23',
1728 'aaa' => array(
1729 'bb' => 'bb',
1730 'ab' => 'ab',
1731 '123' => '123',
1732 'aaa' => 'aaa',
1733 '2' => '2',
1734 'abc' => 'abc',
1735 'ba' => 'ba',
1736 '23' => '23',
1737 'bad' => array(
1738 'bb' => 'bb',
1739 'ab' => 'ab',
1740 '123' => '123',
1741 'aaa' => 'aaa',
1742 'abc' => 'abc',
1743 '23' => '23',
1744 'ba' => 'ba',
1745 'bad' => 'bad',
1746 '2' => '2',
1747 'zap' => 'zap',
1748 '210' => '210'
1749 ),
1750 '210' => '210',
1751 'zap' => 'zap'
1752 ),
1753 'abc' => 'abc',
1754 'ba' => 'ba',
1755 '210' => '210',
1756 'bad' => 'bad',
1757 '123' => '123',
1758 'zap' => 'zap'
1759 );
1760
1761 $expectedResult = array(
1762 '2',
1763 '23',
1764 '123',
1765 '210',
1766 'aaa',
1767 'ab',
1768 'abc',
1769 'ba',
1770 'bad',
1771 'bb',
1772 'zap'
1773 );
1774 t3lib_div::naturalKeySortRecursive($testArray);
1775
1776 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa']['bad'])));
1777 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
1778 $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
1779 }
1780
1781 //////////////////////////////////////
1782 // Tests concerning get_dirs
1783 //////////////////////////////////////
1784
1785 /**
1786 * @test
1787 */
1788 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1789 $path = PATH_t3lib;
1790 $directories = t3lib_div::get_dirs($path);
1791
1792 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $directories);
1793 }
1794
1795 /**
1796 * @test
1797 */
1798 public function getDirsReturnsStringErrorOnPathFailure() {
1799 $path = 'foo';
1800 $result = t3lib_div::get_dirs($path);
1801 $expectedResult = 'error';
1802
1803 $this->assertEquals($expectedResult, $result);
1804 }
1805
1806
1807 //////////////////////////////////
1808 // Tests concerning hmac
1809 //////////////////////////////////
1810
1811 /**
1812 * @test
1813 */
1814 public function hmacReturnsHashOfProperLength() {
1815 $hmac = t3lib_div::hmac('message');
1816 $this->assertTrue(!empty($hmac) && is_string($hmac));
1817 $this->assertTrue(strlen($hmac) == 40);
1818 }
1819
1820 /**
1821 * @test
1822 */
1823 public function hmacReturnsEqualHashesForEqualInput() {
1824 $msg0 = 'message';
1825 $msg1 = 'message';
1826 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1827 }
1828
1829 /**
1830 * @test
1831 */
1832 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1833 $msg0 = 'message0';
1834 $msg1 = 'message1';
1835 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1836 }
1837
1838
1839 //////////////////////////////////
1840 // Tests concerning quoteJSvalue
1841 //////////////////////////////////
1842
1843 /**
1844 * @test
1845 */
1846 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1847 $this->assertContains(
1848 '&gt;',
1849 t3lib_div::quoteJSvalue('>')
1850 );
1851 }
1852
1853 /**
1854 * @test
1855 */
1856 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1857 $this->assertContains(
1858 '&gt;',
1859 t3lib_div::quoteJSvalue('>', FALSE)
1860 );
1861 }
1862
1863 /**
1864 * @test
1865 */
1866 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1867 $this->assertContains(
1868 '>',
1869 t3lib_div::quoteJSvalue('>', TRUE)
1870 );
1871 }
1872
1873 /**
1874 * @test
1875 */
1876 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1877 $this->assertEquals(
1878 "''",
1879 t3lib_div::quoteJSvalue("", TRUE)
1880 );
1881 }
1882
1883 /**
1884 * @test
1885 */
1886 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1887 $this->assertEquals(
1888 "'Hello world!'",
1889 t3lib_div::quoteJSvalue("Hello world!", TRUE)
1890 );
1891 }
1892
1893 /**
1894 * @test
1895 */
1896 public function quoteJSvalueEscapesSingleQuote() {
1897 $this->assertEquals(
1898 "'\\''",
1899 t3lib_div::quoteJSvalue("'", TRUE)
1900 );
1901 }
1902
1903 /**
1904 * @test
1905 */
1906 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1907 $this->assertEquals(
1908 "'\\\"'",
1909 t3lib_div::quoteJSvalue('"', TRUE)
1910 );
1911 }
1912
1913 /**
1914 * @test
1915 */
1916 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1917 $this->assertEquals(
1918 "'\\&quot;'",
1919 t3lib_div::quoteJSvalue('"', FALSE)
1920 );
1921 }
1922
1923 /**
1924 * @test
1925 */
1926 public function quoteJSvalueEscapesTab() {
1927 $this->assertEquals(
1928 "'" . '\t' . "'",
1929 t3lib_div::quoteJSvalue(TAB)
1930 );
1931 }
1932
1933 /**
1934 * @test
1935 */
1936 public function quoteJSvalueEscapesLinefeed() {
1937 $this->assertEquals(
1938 "'" . '\n' . "'",
1939 t3lib_div::quoteJSvalue(LF)
1940 );
1941 }
1942
1943 /**
1944 * @test
1945 */
1946 public function quoteJSvalueEscapesCarriageReturn() {
1947 $this->assertEquals(
1948 "'" . '\r' . "'",
1949 t3lib_div::quoteJSvalue(CR)
1950 );
1951 }
1952
1953 /**
1954 * @test
1955 */
1956 public function quoteJSvalueEscapesBackslah() {
1957 $this->assertEquals(
1958 "'\\\\'",
1959 t3lib_div::quoteJSvalue('\\')
1960 );
1961 }
1962
1963 //////////////////////////////////
1964 // Tests concerning readLLfile
1965 //////////////////////////////////
1966
1967 /**
1968 * @test
1969 */
1970 public function readLLfileHandlesLocallangXMLOverride() {
1971 $unique = uniqid('locallangXMLOverrideTest');
1972
1973 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
1974 <T3locallang>
1975 <data type="array">
1976 <languageKey index="default" type="array">
1977 <label index="buttons.logout">EXIT</label>
1978 </languageKey>
1979 </data>
1980 </T3locallang>';
1981
1982 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
1983 t3lib_div::writeFileToTypo3tempDir($file, $xml);
1984
1985 // Make sure there is no cached version of the label
1986 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
1987
1988 // Get default value
1989 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1990
1991 // Clear language cache again
1992 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
1993
1994 // Set override file
1995 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
1996
1997 /** @var $store t3lib_l10n_Store */
1998 $store = t3lib_div::makeInstance('t3lib_l10n_Store');
1999 $store->flushData('EXT:lang/locallang_core.xml');
2000
2001 // Get override value
2002 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
2003
2004 // Clean up again
2005 unlink($file);
2006
2007 $this->assertNotEquals($overrideLL['default']['buttons.logout'][0]['target'], '');
2008 $this->assertNotEquals($defaultLL['default']['buttons.logout'][0]['target'], $overrideLL['default']['buttons.logout'][0]['target']);
2009 $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
2010 }
2011
2012
2013 ///////////////////////////////
2014 // Tests concerning _GETset()
2015 ///////////////////////////////
2016
2017 /**
2018 * @test
2019 */
2020 public function getSetWritesArrayToGetSystemVariable() {
2021 $_GET = array();
2022 $GLOBALS['HTTP_GET_VARS'] = array();
2023
2024 $getParameters = array('foo' => 'bar');
2025 t3lib_div::_GETset($getParameters);
2026 $this->assertSame($getParameters, $_GET);
2027 }
2028
2029 /**
2030 * @test
2031 */
2032 public function getSetWritesArrayToGlobalsHttpGetVars() {
2033 $_GET = array();
2034 $GLOBALS['HTTP_GET_VARS'] = array();
2035
2036 $getParameters = array('foo' => 'bar');
2037 t3lib_div::_GETset($getParameters);
2038 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
2039 }
2040
2041 /**
2042 * @test
2043 */
2044 public function getSetForArrayDropsExistingValues() {
2045 $_GET = array();
2046 $GLOBALS['HTTP_GET_VARS'] = array();
2047
2048 t3lib_div::_GETset(array('foo' => 'bar'));
2049
2050 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
2051
2052 $this->assertEquals(
2053 array('oneKey' => 'oneValue'),
2054 $GLOBALS['HTTP_GET_VARS']
2055 );
2056 }
2057
2058 /**
2059 * @test
2060 */
2061 public function getSetAssignsOneValueToOneKey() {
2062 $_GET = array();
2063 $GLOBALS['HTTP_GET_VARS'] = array();
2064
2065 t3lib_div::_GETset('oneValue', 'oneKey');
2066
2067 $this->assertEquals(
2068 'oneValue',
2069 $GLOBALS['HTTP_GET_VARS']['oneKey']
2070 );
2071 }
2072
2073 /**
2074 * @test
2075 */
2076 public function getSetForOneValueDoesNotDropUnrelatedValues() {
2077 $_GET = array();
2078 $GLOBALS['HTTP_GET_VARS'] = array();
2079
2080 t3lib_div::_GETset(array('foo' => 'bar'));
2081 t3lib_div::_GETset('oneValue', 'oneKey');
2082
2083 $this->assertEquals(
2084 array('foo' => 'bar', 'oneKey' => 'oneValue'),
2085 $GLOBALS['HTTP_GET_VARS']
2086 );
2087 }
2088
2089 /**
2090 * @test
2091 */
2092 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
2093 $_GET = array();
2094 $GLOBALS['HTTP_GET_VARS'] = array();
2095
2096 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
2097
2098 $this->assertEquals(
2099 array('parentKey' => array('childKey' => 'oneValue')),
2100 $GLOBALS['HTTP_GET_VARS']
2101 );
2102 }
2103
2104 /**
2105 * @test
2106 */
2107 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
2108 $_GET = array();
2109 $GLOBALS['HTTP_GET_VARS'] = array();
2110
2111 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
2112
2113 $this->assertEquals(
2114 array('parentKey' => array('childKey' => 'oneValue')),
2115 $GLOBALS['HTTP_GET_VARS']
2116 );
2117 }
2118
2119 /**
2120 * @test
2121 */
2122 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
2123 $_GET = array();
2124 $GLOBALS['HTTP_GET_VARS'] = array();
2125
2126 t3lib_div::_GETset(
2127 array('key1' => 'value1', 'key2' => 'value2'),
2128 'parentKey|childKey'
2129 );
2130
2131 $this->assertEquals(
2132 array(
2133 'parentKey' => array(
2134 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
2135 )
2136 ),
2137 $GLOBALS['HTTP_GET_VARS']
2138 );
2139 }
2140
2141
2142 ///////////////////////////////
2143 // Tests concerning fixPermissions
2144 ///////////////////////////////
2145
2146 /**
2147 * @test
2148 */
2149 public function fixPermissionsSetsGroup() {
2150 if (TYPO3_OS == 'WIN') {
2151 $this->markTestSkipped('fixPermissionsSetsGroup() tests not available on Windows');
2152 }
2153 if (!function_exists('posix_getegid')) {
2154 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsSetsGroup() tests skipped');
2155 }
2156 if (posix_getegid() === -1) {
2157 $this->markTestSkipped(
2158 'The fixPermissionsSetsGroup() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
2159 );
2160 }
2161
2162 // Create and prepare test file
2163 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2164 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2165
2166 $currentGroupId = posix_getegid();
2167
2168 // Set target group and run method
2169 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
2170 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2171
2172 clearstatcache();
2173 $resultFileGroup = filegroup($filename);
2174 unlink($filename);
2175
2176 $this->assertEquals($resultFileGroup, $currentGroupId);
2177 }
2178
2179 /**
2180 * @test
2181 */
2182 public function fixPermissionsSetsPermissionsToFile() {
2183 if (TYPO3_OS == 'WIN') {
2184 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2185 }
2186
2187 // Create and prepare test file
2188 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2189 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2190 chmod($filename, 0742);
2191
2192 // Set target permissions and run method
2193 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2194 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2195
2196 // Get actual permissions and clean up
2197 clearstatcache();
2198 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2199 unlink($filename);
2200
2201 // Test if everything was ok
2202 $this->assertTrue($fixPermissionsResult);
2203 $this->assertEquals($resultFilePermissions, '0660');
2204 }
2205
2206 /**
2207 * @test
2208 */
2209 public function fixPermissionsSetsPermissionsToHiddenFile() {
2210 if (TYPO3_OS == 'WIN') {
2211 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2212 }
2213
2214 // Create and prepare test file
2215 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
2216 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2217 chmod($filename, 0742);
2218
2219 // Set target permissions and run method
2220 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2221 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2222
2223 // Get actual permissions and clean up
2224 clearstatcache();
2225 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2226 unlink($filename);
2227
2228 // Test if everything was ok
2229 $this->assertTrue($fixPermissionsResult);
2230 $this->assertEquals($resultFilePermissions, '0660');
2231 }
2232
2233 /**
2234 * @test
2235 */
2236 public function fixPermissionsSetsPermissionsToDirectory() {
2237 if (TYPO3_OS == 'WIN') {
2238 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2239 }
2240
2241 // Create and prepare test directory
2242 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2243 t3lib_div::mkdir($directory);
2244 chmod($directory, 1551);
2245
2246 // Set target permissions and run method
2247 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2248 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2249
2250 // Get actual permissions and clean up
2251 clearstatcache();
2252 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2253 t3lib_div::rmdir($directory);
2254
2255 // Test if everything was ok
2256 $this->assertTrue($fixPermissionsResult);
2257 $this->assertEquals($resultDirectoryPermissions, '0770');
2258 }
2259
2260 /**
2261 * @test
2262 */
2263 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
2264 if (TYPO3_OS == 'WIN') {
2265 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2266 }
2267
2268 // Create and prepare test directory
2269 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2270 t3lib_div::mkdir($directory);
2271 chmod($directory, 1551);
2272
2273 // Set target permissions and run method
2274 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2275 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
2276
2277 // Get actual permissions and clean up
2278 clearstatcache();
2279 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2280 t3lib_div::rmdir($directory);
2281
2282 // Test if everything was ok
2283 $this->assertTrue($fixPermissionsResult);
2284 $this->assertEquals($resultDirectoryPermissions, '0770');
2285 }
2286
2287 /**
2288 * @test
2289 */
2290 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
2291 if (TYPO3_OS == 'WIN') {
2292 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2293 }
2294
2295 // Create and prepare test directory
2296 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2297 t3lib_div::mkdir($directory);
2298 chmod($directory, 1551);
2299
2300 // Set target permissions and run method
2301 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2302 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2303
2304 // Get actual permissions and clean up
2305 clearstatcache();
2306 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2307 t3lib_div::rmdir($directory);
2308
2309 // Test if everything was ok
2310 $this->assertTrue($fixPermissionsResult);
2311 $this->assertEquals($resultDirectoryPermissions, '0770');
2312 }
2313
2314 /**
2315 * @test
2316 */
2317 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
2318 if (TYPO3_OS == 'WIN') {
2319 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2320 }
2321
2322 // Create and prepare test directory and file structure
2323 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
2324 t3lib_div::mkdir($baseDirectory);
2325 chmod($baseDirectory, 1751);
2326 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
2327 chmod($baseDirectory . '/file', 0742);
2328 t3lib_div::mkdir($baseDirectory . '/foo');
2329 chmod($baseDirectory . '/foo', 1751);
2330 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
2331 chmod($baseDirectory . '/foo/file', 0742);
2332 t3lib_div::mkdir($baseDirectory . '/.bar');
2333 chmod($baseDirectory . '/.bar', 1751);
2334 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
2335 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
2336 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
2337 touch($baseDirectory . '/.bar/.file', '42');
2338 chmod($baseDirectory . '/.bar/.file', 0742);
2339 touch($baseDirectory . '/.bar/..file2', '42');
2340 chmod($baseDirectory . '/.bar/..file2', 0742);
2341
2342 // Set target permissions and run method
2343 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2344 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2345 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
2346
2347 // Get actual permissions
2348 clearstatcache();
2349 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
2350 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
2351 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
2352 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
2353 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
2354 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
2355 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
2356
2357 // Clean up
2358 unlink($baseDirectory . '/file');
2359 unlink($baseDirectory . '/foo/file');
2360 unlink($baseDirectory . '/.bar/.file');
2361 unlink($baseDirectory . '/.bar/..file2');
2362 t3lib_div::rmdir($baseDirectory . '/foo');
2363 t3lib_div::rmdir($baseDirectory . '/.bar');
2364 t3lib_div::rmdir($baseDirectory);
2365
2366 // Test if everything was ok
2367 $this->assertTrue($fixPermissionsResult);
2368 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
2369 $this->assertEquals($resultBaseFilePermissions, '0660');
2370 $this->assertEquals($resultFooDirectoryPermissions, '0770');
2371 $this->assertEquals($resultFooFilePermissions, '0660');
2372 $this->assertEquals($resultBarDirectoryPermissions, '0770');
2373 $this->assertEquals($resultBarFilePermissions, '0660');
2374 $this->assertEquals($resultBarFile2Permissions, '0660');
2375 }
2376
2377 /**
2378 * @test
2379 */
2380 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
2381 if (TYPO3_OS == 'WIN') {
2382 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2383 }
2384
2385 // Create and prepare test file
2386 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
2387 touch($filename);
2388 chmod($filename, 0742);
2389
2390 // Set target permissions and run method
2391 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2392 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2393
2394 // Get actual permissions and clean up
2395 clearstatcache();
2396 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2397 unlink($filename);
2398
2399 // Test if everything was ok
2400 $this->assertFalse($fixPermissionsResult);
2401 }
2402
2403 /**
2404 * @test
2405 */
2406 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
2407 if (TYPO3_OS == 'WIN') {
2408 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2409 }
2410
2411 $filename = 'typo3temp/' . uniqid('test_');
2412 t3lib_div::writeFileToTypo3tempDir(PATH_site . $filename, '42');
2413 chmod(PATH_site . $filename, 0742);
2414
2415 // Set target permissions and run method
2416 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2417 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2418
2419 // Get actual permissions and clean up
2420 clearstatcache();
2421 $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2);
2422 unlink(PATH_site . $filename);
2423
2424 // Test if everything was ok
2425 $this->assertTrue($fixPermissionsResult);
2426 $this->assertEquals($resultFilePermissions, '0660');
2427 }
2428
2429
2430 ///////////////////////////////
2431 // Tests concerning mkdir
2432 ///////////////////////////////
2433
2434 /**
2435 * @test
2436 */
2437 public function mkdirCreatesDirectory() {
2438 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2439 $mkdirResult = t3lib_div::mkdir($directory);
2440 clearstatcache();
2441 $directoryCreated = is_dir($directory);
2442 @rmdir($directory);
2443 $this->assertTrue($mkdirResult);
2444 $this->assertTrue($directoryCreated);
2445 }
2446
2447 /**
2448 * @test
2449 */
2450 public function mkdirCreatesHiddenDirectory() {
2451 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2452 $mkdirResult = t3lib_div::mkdir($directory);
2453 clearstatcache();
2454 $directoryCreated = is_dir($directory);
2455 @rmdir($directory);
2456 $this->assertTrue($mkdirResult);
2457 $this->assertTrue($directoryCreated);
2458 }
2459
2460 /**
2461 * @test
2462 */
2463 public function mkdirCreatesDirectoryWithTrailingSlash() {
2464 $directory = PATH_site . 'typo3temp/' . uniqid('test_') . '/';
2465 $mkdirResult = t3lib_div::mkdir($directory);
2466 clearstatcache();
2467 $directoryCreated = is_dir($directory);
2468 @rmdir($directory);
2469 $this->assertTrue($mkdirResult);
2470 $this->assertTrue($directoryCreated);
2471 }
2472
2473 /**
2474 * @test
2475 */
2476 public function mkdirSetsPermissionsOfCreatedDirectory() {
2477 if (TYPO3_OS == 'WIN') {
2478 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
2479 }
2480
2481 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2482 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2483 t3lib_div::mkdir($directory);
2484 clearstatcache();
2485 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2486 rmdir($directory);
2487 $this->assertEquals($resultDirectoryPermissions, '0770');
2488 }
2489
2490
2491 ///////////////////////////////
2492 // Tests concerning mkdir_deep
2493 ///////////////////////////////
2494
2495 /**
2496 * @test
2497 */
2498 public function mkdirDeepCreatesDirectory() {
2499 $directory = 'typo3temp/' . uniqid('test_');
2500 t3lib_div::mkdir_deep(PATH_site, $directory);
2501 $isDirectoryCreated = is_dir(PATH_site . $directory);
2502 rmdir(PATH_site . $directory);
2503 $this->assertTrue($isDirectoryCreated);
2504 }
2505
2506 /**
2507 * @test
2508 */
2509 public function mkdirDeepCreatesSubdirectoriesRecursive() {
2510 $directory = 'typo3temp/' . uniqid('test_');
2511 $subDirectory = $directory . '/foo';
2512 t3lib_div::mkdir_deep(PATH_site, $subDirectory);
2513 $isDirectoryCreated = is_dir(PATH_site . $subDirectory);
2514 rmdir(PATH_site . $subDirectory);
2515 rmdir(PATH_site . $directory);
2516 $this->assertTrue($isDirectoryCreated);
2517 }
2518
2519 /**
2520 * @test
2521 */
2522 public function mkdirDeepFixesPermissionsOnNewDirectory() {
2523 if (TYPO3_OS == 'WIN') {
2524 $this->markTestSkipped('mkdirDeepFixesPermissionsOnNewDirectory() test not available on Windows.');
2525 }
2526
2527 $directory = uniqid('mkdirdeeptest_');
2528 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0750';
2529 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2530 clearstatcache();
2531 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2532 @rmdir(PATH_site . 'typo3temp/' . $directory);
2533 $this->assertEquals($resultDirectoryPermissions, '750');
2534 }
2535
2536 /**
2537 * @test
2538 */
2539 public function mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() {
2540 if (TYPO3_OS == 'WIN') {
2541 $this->markTestSkipped('mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() test not available on Windows.');
2542 }
2543
2544 $baseDirectory = PATH_site . 'typo3temp/';
2545 $existingDirectory = uniqid('test_existing_') . '/';
2546 $newSubDirectory = uniqid('test_new_');
2547 @mkdir($baseDirectory . $existingDirectory);
2548 chmod($baseDirectory . $existingDirectory, 0742);
2549 t3lib_div::mkdir_deep($baseDirectory, $existingDirectory . $newSubDirectory);
2550 $resultExistingDirectoryPermissions = substr(decoct(fileperms($baseDirectory . $existingDirectory)), 2);
2551 @rmdir($baseDirectory, $existingDirectory . $newSubDirectory);
2552 @rmdir($baseDirectory, $existingDirectory);
2553 $this->assertEquals($resultExistingDirectoryPermissions, '0742');
2554 }
2555
2556 /**
2557 * @test
2558 */
2559 public function mkdirDeepCreatesDirectoryInVfsStream() {
2560 if (!class_exists('\vfsStreamWrapper')) {
2561 $this->markTestSkipped('mkdirDeepCreatesDirectoryInVfsStream() test not available with this phpunit version.');
2562 }
2563
2564 \vfsStreamWrapper::register();
2565 $baseDirectory = uniqid('test_');
2566 \vfsStreamWrapper::setRoot(new \vfsStreamDirectory($baseDirectory));
2567 t3lib_div::mkdir_deep('vfs://' . $baseDirectory . '/', 'sub');
2568 $this->assertTrue(is_dir('vfs://' . $baseDirectory . '/sub'));
2569 }
2570
2571 /**
2572 * @test
2573 * @expectedException \RuntimeException
2574 */
2575 public function mkdirDeepThrowsExceptionIfDirectoryCreationFails() {
2576 t3lib_div::mkdir_deep('http://localhost');
2577 }
2578
2579 /**
2580 * @test
2581 * @expectedException \InvalidArgumentException
2582 */
2583 public function mkdirDeepThrowsExceptionIfBaseDirectoryIsNotOfTypeString() {
2584 t3lib_div::mkdir_deep(array());
2585 }
2586
2587 /**
2588 * @test
2589 * @expectedException \InvalidArgumentException
2590 */
2591 public function mkdirDeepThrowsExceptionIfDeepDirectoryIsNotOfTypeString() {
2592 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/foo', array());
2593 }
2594
2595
2596 ///////////////////////////////
2597 // Tests concerning unQuoteFilenames
2598 ///////////////////////////////
2599
2600 /**
2601 * Data provider for ImageMagick shell commands
2602 * @see explodeAndUnquoteImageMagickCommands
2603 */
2604 public function imageMagickCommandsDataProvider() {
2605 return array(
2606 // Some theoretical tests first
2607 array(
2608 'aa bb "cc" "dd"',
2609 array('aa', 'bb', '"cc"', '"dd"'),
2610 array('aa', 'bb', 'cc', 'dd'),
2611 ),
2612 array(
2613 'aa bb "cc dd"',
2614 array('aa', 'bb', '"cc dd"'),
2615 array('aa', 'bb', 'cc dd'),
2616 ),
2617 array(
2618 '\'aa bb\' "cc dd"',
2619 array('\'aa bb\'', '"cc dd"'),
2620 array('aa bb', 'cc dd'),
2621 ),
2622 array(
2623 '\'aa bb\' cc "dd"',
2624 array('\'aa bb\'', 'cc', '"dd"'),
2625 array('aa bb', 'cc', 'dd'),
2626 ),
2627 // Now test against some real world examples
2628 array(
2629 '/opt/local/bin/gm.exe convert +profile \'*\' -geometry 170x136! -negate "C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2630 array(
2631 '/opt/local/bin/gm.exe',
2632 'convert',
2633 '+profile',
2634 '\'*\'',
2635 '-geometry',
2636 '170x136!',
2637 '-negate',
2638 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2639 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2640 ),
2641 array(
2642 '/opt/local/bin/gm.exe',
2643 'convert',
2644 '+profile',
2645 '*',
2646 '-geometry',
2647 '170x136!',
2648 '-negate',
2649 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2650 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2651 ),
2652 ),
2653 array(
2654 'C:/opt/local/bin/gm.exe convert +profile \'*\' -geometry 170x136! -negate "C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2655 array(
2656 'C:/opt/local/bin/gm.exe',
2657 'convert',
2658 '+profile',
2659 '\'*\'',
2660 '-geometry',
2661 '170x136!',
2662 '-negate',
2663 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2664 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2665 ),
2666 array(
2667 'C:/opt/local/bin/gm.exe',
2668 'convert',
2669 '+profile',
2670 '*',
2671 '-geometry',
2672 '170x136!',
2673 '-negate',
2674 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2675 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2676 ),
2677 ),
2678 array(
2679 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate "/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2680 array(
2681 '/usr/bin/gm',
2682 'convert',
2683 '+profile',
2684 '\'*\'',
2685 '-geometry',
2686 '170x136!',
2687 '-negate',
2688 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2689 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2690 ),
2691 array(
2692 '/usr/bin/gm',
2693 'convert',
2694 '+profile',
2695 '*',
2696 '-geometry',
2697 '170x136!',
2698 '-negate',
2699 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2700 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2701 ),
2702 ),
2703 array(
2704 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate "/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2705 array(
2706 '/usr/bin/gm',
2707 'convert',
2708 '+profile',
2709 '\'*\'',
2710 '-geometry',
2711 '170x136!',
2712 '-negate',
2713 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2714 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2715 ),
2716 array(
2717 '/usr/bin/gm',
2718 'convert',
2719 '+profile',
2720 '*',
2721 '-geometry',
2722 '170x136!',
2723 '-negate',
2724 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2725 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2726 ),
2727 ),
2728 array(
2729 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate \'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\' \'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\'',
2730 array(
2731 '/usr/bin/gm',
2732 'convert',
2733 '+profile',
2734 '\'*\'',
2735 '-geometry',
2736 '170x136!',
2737 '-negate',
2738 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2739 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2740 ),
2741 array(
2742 '/usr/bin/gm',
2743 'convert',
2744 '+profile',
2745 '*',
2746 '-geometry',
2747 '170x136!',
2748 '-negate',
2749 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2750 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2751 ),
2752 ),
2753 );
2754 }
2755
2756 /**
2757 * Tests if the commands are exploded and unquoted correctly
2758 *
2759 * @dataProvider imageMagickCommandsDataProvider
2760 * @test
2761 */
2762 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2763 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2764 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2765
2766 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2767 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2768 }
2769
2770
2771 ///////////////////////////////
2772 // Tests concerning split_fileref
2773 ///////////////////////////////
2774
2775 /**
2776 * @test
2777 */
2778 public function splitFileRefReturnsFileTypeNotForFolders(){
2779 $directoryName = uniqid('test_') . '.com';
2780 $directoryPath = PATH_site . 'typo3temp/';
2781 $directory = $directoryPath . $directoryName;
2782 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
2783
2784 $fileInfo = t3lib_div::split_fileref($directory);
2785
2786 $directoryCreated = is_dir($directory);
2787 rmdir($directory);
2788
2789 $this->assertTrue($directoryCreated);
2790 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2791 $this->assertEquals($directoryPath, $fileInfo['path']);
2792 $this->assertEquals($directoryName, $fileInfo['file']);
2793 $this->assertEquals($directoryName, $fileInfo['filebody']);
2794 $this->assertEquals('', $fileInfo['fileext']);
2795 $this->assertArrayNotHasKey('realFileext', $fileInfo);
2796 }
2797
2798 /**
2799 * @test
2800 */
2801 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
2802 $testFile = 'fileadmin/media/someFile.png';
2803
2804 $fileInfo = t3lib_div::split_fileref($testFile);
2805 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2806 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
2807 $this->assertEquals('someFile.png', $fileInfo['file']);
2808 $this->assertEquals('someFile', $fileInfo['filebody']);
2809 $this->assertEquals('png', $fileInfo['fileext']);
2810 }
2811
2812
2813 /////////////////////////////
2814 // Tests concerning dirname
2815 /////////////////////////////
2816
2817 /**
2818 * @see dirnameWithDataProvider
2819 *
2820 * @return array<array>
2821 */
2822 public function dirnameDataProvider() {
2823 return array(
2824 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
2825 'absolute path with one part' => array('/dir1/', '/dir1'),
2826 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
2827 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
2828 'relative one-character path with one part and file' => array('d/script.php', 'd'),
2829 'absolute zero-part path with file' => array('/script.php', ''),
2830 'empty string' => array('', ''),
2831 );
2832 }
2833
2834 /**
2835 * @test
2836 *
2837 * @dataProvider dirnameDataProvider
2838 *
2839 * @param string $input the input for dirname
2840 * @param string $expectedValue the expected return value expected from dirname
2841 */
2842 public function dirnameWithDataProvider($input, $expectedValue) {
2843 $this->assertEquals(
2844 $expectedValue,
2845 t3lib_div::dirname($input)
2846 );
2847 }
2848
2849
2850 /////////////////////////////////////
2851 // Tests concerning resolveBackPath
2852 /////////////////////////////////////
2853
2854 /**
2855 * @see resolveBackPathWithDataProvider
2856 *
2857 * @return array<array>
2858 */
2859 public function resolveBackPathDataProvider() {
2860 return array(
2861 'empty path' => array('', ''),
2862 'this directory' => array('./', './'),
2863 'relative directory without ..' => array('dir1/dir2/dir3/', 'dir1/dir2/dir3/'),
2864 'relative path without ..' => array('dir1/dir2/script.php', 'dir1/dir2/script.php'),
2865 'absolute directory without ..' => array('/dir1/dir2/dir3/', '/dir1/dir2/dir3/'),
2866 'absolute path without ..' => array('/dir1/dir2/script.php', '/dir1/dir2/script.php'),
2867 'only one directory upwards without trailing slash' => array('..', '..'),
2868 'only one directory upwards with trailing slash' => array('../', '../'),
2869 'one level with trailing ..' => array('dir1/..', ''),
2870 'one level with trailing ../' => array('dir1/../', ''),
2871 'two levels with trailing ..' => array('dir1/dir2/..', 'dir1'),
2872 'two levels with trailing ../' => array('dir1/dir2/../', 'dir1/'),
2873 'leading ../ without trailing /' => array('../dir1', '../dir1'),
2874 'leading ../ with trailing /' => array('../dir1/', '../dir1/'),
2875 'leading ../ and inside path' => array('../dir1/dir2/../dir3/', '../dir1/dir3/'),
2876 'one times ../ in relative directory' => array('dir1/../dir2/', 'dir2/'),
2877 'one times ../ in absolute directory' => array('/dir1/../dir2/', '/dir2/'),
2878 'one times ../ in relative path' => array('dir1/../dir2/script.php', 'dir2/script.php'),
2879 'one times ../ in absolute path' => array('/dir1/../dir2/script.php', '/dir2/script.php'),
2880 'consecutive ../' => array('dir1/dir2/dir3/../../../dir4', 'dir4'),
2881 'distrubuted ../ with trailing /' => array('dir1/../dir2/dir3/../', 'dir2/'),
2882 'distributed ../ without trailing /' => array('dir1/../dir2/dir3/..', 'dir2'),
2883 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2884 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2885 'dirname with leading ..' => array('dir1/..dir2/dir3/', 'dir1/..dir2/dir3/'),
2886 'dirname with trailing ..' => array('dir1/dir2../dir3/', 'dir1/dir2../dir3/'),
2887 'more times upwards than downwards in directory' => array('dir1/../../', '../'),
2888 'more times upwards than downwards in path' => array('dir1/../../script.php', '../script.php'),
2889 );
2890 }
2891
2892 /**
2893 * @test
2894 *
2895 * @dataProvider resolveBackPathDataProvider
2896 *
2897 * @param string $input the input for resolveBackPath
2898 * @param $expectedValue the expected return value from resolveBackPath
2899 */
2900 public function resolveBackPathWithDataProvider($input, $expectedValue) {
2901 $this->assertEquals(
2902 $expectedValue,
2903 t3lib_div::resolveBackPath($input)
2904 );
2905 }
2906
2907
2908 /////////////////////////////////////////////////////////////////////////////////////
2909 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
2910 /////////////////////////////////////////////////////////////////////////////////////
2911
2912 /**
2913 * @test
2914 * @expectedException InvalidArgumentException
2915 */
2916 public function makeInstanceWithEmptyClassNameThrowsException() {
2917 t3lib_div::makeInstance('');
2918 }
2919
2920 /**
2921 * @test
2922 * @expectedException InvalidArgumentException
2923 */
2924 public function makeInstanceWithNullClassNameThrowsException() {
2925 t3lib_div::makeInstance(NULL);
2926 }
2927
2928 /**
2929 * @test
2930 * @expectedException InvalidArgumentException
2931 */
2932 public function makeInstanceWithZeroStringClassNameThrowsException() {
2933 t3lib_div::makeInstance(0);
2934 }
2935
2936 /**
2937 * @test
2938 * @expectedException InvalidArgumentException
2939 */
2940 public function makeInstanceWithEmptyArrayThrowsException() {
2941 t3lib_div::makeInstance(array());
2942 }
2943
2944 /**
2945 * @test
2946 * @expectedException InvalidArgumentException
2947 */
2948 public function makeInstanceWithNonEmptyArrayThrowsException() {
2949 t3lib_div::makeInstance(array('foo'));
2950 }
2951
2952 /**
2953 * @test
2954 */
2955 public function makeInstanceReturnsClassInstance() {
2956 $className = get_class($this->getMock('foo'));
2957
2958 $this->assertTrue(
2959 t3lib_div::makeInstance($className) instanceof $className
2960 );
2961 }
2962
2963 /**
2964 * @test
2965 */
2966 public function makeInstancePassesParametersToConstructor() {
2967 $className = 'testingClass' . uniqid();
2968 if (!class_exists($className, FALSE)) {
2969 eval(
2970 'class ' . $className . ' {' .
2971 ' public $constructorParameter1;' .
2972 ' public $constructorParameter2;' .
2973 ' public function __construct($parameter1, $parameter2) {' .
2974 ' $this->constructorParameter1 = $parameter1;' .
2975 ' $this->constructorParameter2 = $parameter2;' .
2976 ' }' .
2977 '}'
2978 );
2979 }
2980
2981 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
2982
2983 $this->assertEquals(
2984 'one parameter',
2985 $instance->constructorParameter1,
2986 'The first constructor parameter has not been set.'
2987 );
2988 $this->assertEquals(
2989 'another parameter',
2990 $instance->constructorParameter2,
2991 'The second constructor parameter has not been set.'
2992 );
2993 }
2994
2995 /**
2996 * @test
2997 */
2998 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
2999 $className = get_class($this->getMock('foo'));
3000
3001 $this->assertNotSame(
3002 t3lib_div::makeInstance($className),
3003 t3lib_div::makeInstance($className)
3004 );
3005 }
3006
3007 /**
3008 * @test
3009 */
3010 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
3011 $className = get_class($this->getMock('t3lib_Singleton'));
3012
3013 $this->assertSame(
3014 t3lib_div::makeInstance($className),
3015 t3lib_div::makeInstance($className)
3016 );
3017 }
3018
3019 /**
3020 * @test
3021 */
3022 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
3023 $className = get_class($this->getMock('t3lib_Singleton'));
3024
3025 $instance = t3lib_div::makeInstance($className);
3026 t3lib_div::purgeInstances();
3027
3028 $this->assertNotSame(
3029 $instance,
3030 t3lib_div::makeInstance($className)
3031 );
3032 }
3033
3034 /**
3035 * @test
3036 * @expectedException InvalidArgumentException
3037 */
3038 public function setSingletonInstanceForEmptyClassNameThrowsException() {
3039 $instance = $this->getMock('t3lib_Singleton');
3040
3041 t3lib_div::setSingletonInstance('', $instance);
3042 }
3043
3044 /**
3045 * @test
3046 * @expectedException InvalidArgumentException
3047 */
3048 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3049 $instance = $this->getMock('t3lib_Singleton', array('foo'));
3050 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
3051
3052 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3053 }
3054
3055 /**
3056 * @test
3057 */
3058 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
3059 $instance = $this->getMock('t3lib_Singleton');
3060 $singletonClassName = get_class($instance);
3061
3062 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3063
3064 $this->assertSame(
3065 $instance,
3066 t3lib_div::makeInstance($singletonClassName)
3067 );
3068 }
3069
3070 /**
3071 * @test
3072 */
3073 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
3074 $instance1 = $this->getMock('t3lib_Singleton');
3075 $singletonClassName = get_class($instance1);
3076 $instance2 = new $singletonClassName();
3077
3078 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
3079 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
3080
3081 $this->assertSame(
3082 $instance2,
3083 t3lib_div::makeInstance($singletonClassName)
3084 );
3085 }
3086
3087 /**
3088 * @test
3089 * @expectedException InvalidArgumentException
3090 */
3091 public function addInstanceForEmptyClassNameThrowsException() {
3092 $instance = $this->getMock('foo');
3093
3094 t3lib_div::addInstance('', $instance);
3095 }
3096
3097 /**
3098 * @test
3099 * @expectedException InvalidArgumentException
3100 */
3101 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3102 $instance = $this->getMock('foo', array('bar'));
3103 $singletonClassName = get_class($this->getMock('foo'));
3104
3105 t3lib_div::addInstance($singletonClassName, $instance);
3106 }
3107
3108 /**
3109 * @test
3110 * @expectedException InvalidArgumentException
3111 */
3112 public function addInstanceWithSingletonInstanceThrowsException() {
3113 $instance = $this->getMock('t3lib_Singleton');
3114
3115 t3lib_div::addInstance(get_class($instance), $instance);
3116 }
3117
3118 /**
3119 * @test
3120 */
3121 public function addInstanceMakesMakeInstanceReturnThatInstance() {
3122 $instance = $this->getMock('foo');
3123 $className = get_class($instance);
3124
3125 t3lib_div::addInstance($className, $instance);
3126
3127 $this->assertSame(
3128 $instance,
3129 t3lib_div::makeInstance($className)
3130 );
3131 }
3132
3133 /**
3134 * @test
3135 */
3136 public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
3137 $instance = $this->getMock('foo');
3138 $className = get_class($instance);
3139
3140 t3lib_div::addInstance($className, $instance);
3141
3142 $this->assertNotSame(
3143 t3lib_div::makeInstance($className),
3144 t3lib_div::makeInstance($className)
3145 );
3146 }
3147
3148 /**
3149 * @test
3150 */
3151 public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
3152 $instance1 = $this->getMock('foo');
3153 $className = get_class($instance1);
3154 t3lib_div::addInstance($className, $instance1);
3155
3156 $instance2 = new $className();
3157 t3lib_div::addInstance($className, $instance2);
3158
3159 $this->assertSame(
3160 $instance1,
3161 t3lib_div::makeInstance($className),
3162 'The first returned instance does not match the first added instance.'
3163 );
3164 $this->assertSame(
3165 $instance2,
3166 t3lib_div::makeInstance($className),
3167 'The second returned instance does not match the second added instance.'
3168 );
3169 }
3170
3171 /**
3172 * @test
3173 */
3174 public function purgeInstancesDropsAddedInstance() {
3175 $instance = $this->getMock('foo');
3176 $className = get_class($instance);
3177
3178 t3lib_div::addInstance($className, $instance);
3179 t3lib_div::purgeInstances();
3180
3181 $this->assertNotSame(
3182 $instance,
3183 t3lib_div::makeInstance($className)
3184 );
3185 }
3186
3187 /**
3188 * Data provider for validPathStrDetectsInvalidCharacters.
3189 *
3190 * @return array
3191 */
3192 public function validPathStrInvalidCharactersDataProvider() {
3193 return array(
3194 'double slash in path' => array('path//path'),
3195 'backslash in path' => array('path\\path'),
3196 'directory up in path' => array('path/../path'),
3197 'directory up at the beginning' => array('../path'),
3198 'NUL character in path' => array("path\x00path"),
3199 'BS character in path' => array("path\x08path"),
3200 );
3201 }
3202
3203 /**
3204 * Tests whether invalid characters are detected.
3205 *
3206 * @param string $path
3207 * @dataProvider validPathStrInvalidCharactersDataProvider
3208 * @test
3209 */
3210 public function validPathStrDetectsInvalidCharacters($path) {
3211 $this->assertNull(t3lib_div::validPathStr($path));
3212 }
3213
3214 /**
3215 * Tests whether verifyFilenameAgainstDenyPattern detects the NULL character.
3216 *
3217 * @test
3218 */
3219 public function verifyFilenameAgainstDenyPatternDetectsNullCharacter() {
3220 $this->assertFalse(t3lib_div::verifyFilenameAgainstDenyPattern("image\x00.gif"));
3221 }
3222
3223
3224 /////////////////////////////////////////////////////////////////////////////////////
3225 // Tests concerning sysLog
3226 /////////////////////////////////////////////////////////////////////////////////////
3227
3228 /**
3229 * @test
3230 */
3231 public function syslogFixesPermissionsOnFileIfUsingFileLogging() {
3232 if (TYPO3_OS == 'WIN') {
3233 $this->markTestSkipped('syslogFixesPermissionsOnFileIfUsingFileLogging() test not available on Windows.');
3234 }
3235
3236 // Fake all required settings
3237 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel'] = 0;
3238 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit'] = TRUE;
3239 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']);
3240 $testLogFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.txt';
3241 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'] = 'file,' . $testLogFilename . ',0';
3242 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
3243
3244 // Call method, get actual permissions and clean up
3245 t3lib_div::syslog('testLog', 'test', 1);
3246 clearstatcache();
3247 $resultFilePermissions = substr(decoct(fileperms($testLogFilename)), 2);
3248 t3lib_div::unlink_tempfile($testLogFilename);
3249
3250 $this->assertEquals($resultFilePermissions, '0777');
3251 }
3252
3253 /**
3254 * @test
3255 */
3256 public function deprecationLogFixesPermissionsOnLogFile() {
3257 if (TYPO3_OS == 'WIN') {
3258 $this->markTestSkipped('deprecationLogFixesPermissionsOnLogFile() test not available on Windows.');
3259 }
3260
3261 // Fake all required settings and get an unique logfilename
3262 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = uniqid('test_');
3263 $deprecationLogFilename = t3lib_div::getDeprecationLogFileName();
3264 $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = TRUE;
3265 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
3266
3267 // Call method, get actual permissions and clean up
3268 t3lib_div::deprecationLog('foo');
3269 clearstatcache();
3270 $resultFilePermissions = substr(decoct(fileperms($deprecationLogFilename)), 2);
3271 @unlink($deprecationLogFilename);
3272
3273 $this->assertEquals($resultFilePermissions, '0777');
3274 }
3275
3276 ///////////////////////////////////////////////////
3277 // Tests concerning hasValidClassPrefix
3278 ///////////////////////////////////////////////////
3279
3280 /**
3281 * @return array
3282 */
3283 public function validClassPrefixDataProvider() {
3284 return array(
3285 array('tx_foo'),
3286 array('tx_foo_bar'),
3287 array('Tx_foo'),
3288 array($GLOBALS['TYPO3_CONF_VARS']['FE']['userFuncClassPrefix'] . 'foo'),
3289 );
3290 }
3291
3292 /**
3293 * @test
3294 * @dataProvider validClassPrefixDataProvider
3295 * @param string $className Class name to test
3296 */
3297 public function hasValidClassPrefixAcceptsValidPrefixes($className) {
3298 $this->assertTrue(
3299 t3lib_div::hasValidClassPrefix($className)
3300 );
3301 }
3302
3303 /**
3304 * @return array
3305 */
3306 public function invalidClassPrefixDataProvider() {
3307 return array(
3308