Fixed bug #16795: t3lib_div::unQuoteFilenames fails to detect quotes properly
[Packages/TYPO3.CMS.git] / tests / t3lib / t3lib_divTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2010 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 $fixtureGifFile = dirname(__FILE__) . '/fixtures/clear.gif';
73
74 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
75
76 // Copy file to unique filename in typo3temp, set target permissions and run method
77 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
78 @copy($fixtureGifFile, $testFilename);
79 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
80 t3lib_div::gif_compress($testFilename, 'IM');
81
82 // Get actual permissions and clean up
83 clearstatcache();
84 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
85 t3lib_div::unlink_tempfile($testFilename);
86
87 $this->assertEquals($resultFilePermissions, '0777');
88 }
89
90 /**
91 * @test
92 */
93 public function gifCompressFixesPermissionOfConvertedFileIfUsingGd() {
94 if (TYPO3_OS == 'WIN') {
95 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
96 }
97
98 $fixtureGifFile = dirname(__FILE__) . '/fixtures/clear.gif';
99
100 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] = TRUE;
101 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] = FALSE;
102
103 // Copy file to unique filename in typo3temp, set target permissions and run method
104 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
105 @copy($fixtureGifFile, $testFilename);
106 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
107 t3lib_div::gif_compress($testFilename, 'GD');
108
109 // Get actual permissions and clean up
110 clearstatcache();
111 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
112 t3lib_div::unlink_tempfile($testFilename);
113
114 $this->assertEquals($resultFilePermissions, '0777');
115 }
116
117 ///////////////////////////////
118 // Tests concerning png_to_gif_by_imagemagick
119 ///////////////////////////////
120
121 /**
122 * @test
123 */
124 public function pngToGifByImagemagickFixesPermissionsOfConvertedFile() {
125 if (TYPO3_OS == 'WIN') {
126 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available on Windows.');
127 }
128
129 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
130 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
131 }
132
133 $fixturePngFile = dirname(__FILE__) . '/fixtures/clear.png';
134
135 $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] = TRUE;
136
137 // Copy file to unique filename in typo3temp, set target permissions and run method
138 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.png';
139 @copy($fixturePngFile, $testFilename);
140 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
141 $newGifFile = t3lib_div::png_to_gif_by_imagemagick($testFilename);
142
143 // Get actual permissions and clean up
144 clearstatcache();
145 $resultFilePermissions = substr(decoct(fileperms($newGifFile)), 2);
146 t3lib_div::unlink_tempfile($newGifFile);
147
148 $this->assertEquals($resultFilePermissions, '0777');
149 }
150
151 ///////////////////////////////
152 // Tests concerning read_png_gif
153 ///////////////////////////////
154
155 /**
156 * @test
157 */
158 public function readPngGifFixesPermissionsOfConvertedFile() {
159 if (TYPO3_OS == 'WIN') {
160 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available on Windows.');
161 }
162
163 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
164 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
165 }
166
167 $testGifFile = dirname(__FILE__) . '/fixtures/clear.gif';
168
169 // Set target permissions and run method
170 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
171 $newPngFile = t3lib_div::read_png_gif($testGifFile, TRUE);
172
173 // Get actual permissions and clean up
174 clearstatcache();
175 $resultFilePermissions = substr(decoct(fileperms($newPngFile)), 2);
176 t3lib_div::unlink_tempfile($newPngFile);
177
178 $this->assertEquals($resultFilePermissions, '0777');
179 }
180
181 ///////////////////////////////
182 // Tests concerning validIP
183 ///////////////////////////////
184
185 /**
186 * Data provider for checkValidIpReturnsTrueForValidIp
187 *
188 * @return array Data sets
189 */
190 public static function validIpDataProvider() {
191 return array(
192 '0.0.0.0' => array('0.0.0.0'),
193 'private IPv4 class C' => array('192.168.0.1'),
194 'private IPv4 class A' => array('10.0.13.1'),
195 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
196 );
197 }
198
199 /**
200 * @test
201 * @dataProvider validIpDataProvider
202 */
203 public function validIpReturnsTrueForValidIp($ip) {
204 $this->assertTrue(t3lib_div::validIP($ip));
205 }
206
207 /**
208 * Data provider for checkValidIpReturnsFalseForInvalidIp
209 *
210 * @return array Data sets
211 */
212 public static function invalidIpDataProvider() {
213 return array(
214 'null' => array(null),
215 'zero' => array(0),
216 'string' => array('test'),
217 'string empty' => array(''),
218 'string null' => array('null'),
219 'out of bounds IPv4' => array('300.300.300.300'),
220 'dotted decimal notation with only two dots' => array('127.0.1'),
221 );
222 }
223
224 /**
225 * @test
226 * @dataProvider invalidIpDataProvider
227 */
228 public function validIpReturnsFalseForInvalidIp($ip) {
229 $this->assertFalse(t3lib_div::validIP($ip));
230 }
231
232
233 ///////////////////////////////
234 // Tests concerning testInt
235 ///////////////////////////////
236
237 /**
238 * Data provider for testIntReturnsTrue
239 *
240 * @return array Data sets
241 */
242 public function functionTestIntValidDataProvider() {
243 return array(
244 'int' => array(32425),
245 'negative int' => array(-32425),
246 'largest int' => array(PHP_INT_MAX),
247 'int as string' => array('32425'),
248 'negative int as string' => array('-32425'),
249 'zero' => array(0),
250 'zero as string' => array('0'),
251 );
252 }
253
254 /**
255 * @test
256 * @dataProvider functionTestIntValidDataProvider
257 */
258 public function testIntReturnsTrue($int) {
259 $this->assertTrue(t3lib_div::testInt($int));
260 }
261
262 /**
263 * Data provider for testIntReturnsFalse
264 *
265 * @return array Data sets
266 */
267 public function functionTestIntInvalidDataProvider() {
268 return array(
269 'int as string with leading zero' => array('01234'),
270 'positive int as string with plus modifier' => array('+1234'),
271 'negative int as string with leading zero' => array('-01234'),
272 'largest int plus one' => array(PHP_INT_MAX + 1),
273 'string' => array('testInt'),
274 'empty string' => array(''),
275 'int in string' => array('5 times of testInt'),
276 'int as string with space after' => array('5 '),
277 'int as string with space before' => array(' 5'),
278 'int as string with many spaces before' => array(' 5'),
279 'float' => array(3.14159),
280 'float as string' => array('3.14159'),
281 'float as string only a dot' => array('10.'),
282 'float as string trailing zero would evaluate to int 10' => array('10.0'),
283 'float as string trailing zeros would evaluate to int 10' => array('10.00'),
284 'null' => array(NULL),
285 'empty array' => array(array()),
286 'int in array' => array(array(32425)),
287 'int as string in array' => array(array('32425')),
288 );
289 }
290
291 /**
292 * @test
293 * @dataProvider functionTestIntInvalidDataProvider
294 */
295 public function testIntReturnsFalse($int) {
296 $this->assertFalse(t3lib_div::testInt($int));
297 }
298
299
300 ///////////////////////////////
301 // Tests concerning isFirstPartOfStr
302 ///////////////////////////////
303
304 /**
305 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
306 *
307 * @return array
308 */
309 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
310 return array(
311 'match first part of string' => array('hello world', 'hello'),
312 'match whole string' => array('hello', 'hello'),
313 'integer is part of string with same number' => array('24', 24),
314 'string is part of integer with same number' => array(24, '24'),
315 'integer is part of string starting with same number' => array('24 beer please', 24),
316 );
317 }
318
319 /**
320 * @test
321 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
322 */
323 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
324 $this->assertTrue(t3lib_div::isFirstPartOfStr($string, $part));
325 }
326
327 /**
328 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
329 *
330 * @return array
331 */
332 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
333 return array(
334 'no string match' => array('hello', 'bye'),
335 'no case sensitive string match' => array('hello world', 'Hello'),
336 'array is not part of string' => array('string', array()),
337 'string is not part of array' => array(array(), 'string'),
338 'null is not part of string' => array('string', NULL),
339 'string is not part of array' => array(NULL, 'string'),
340 'null is not part of array' => array(array(), NULL),
341 'array is not part of string' => array(NULL, array()),
342 'empty string is not part of empty string' => array('', ''),
343 'null is not part of empty string' => array('', NULL),
344 'false is not part of empty string' => array('', FALSE),
345 'empty string is not part of null' => array(NULL, ''),
346 'empty string is not part of false' => array(FALSE, ''),
347 'empty string is not part of zero integer' => array(0, ''),
348 'zero integer is not part of null' => array(NULL, 0),
349 'zero integer is not part of empty string' => array('', 0),
350 );
351 }
352
353 /**
354 * @test
355 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
356 */
357 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
358 $this->assertFalse(t3lib_div::isFirstPartOfStr($string, $part));
359 }
360
361
362 ///////////////////////////////
363 // Tests concerning splitCalc
364 ///////////////////////////////
365
366 /**
367 * Data provider for splitCalc
368 *
369 * @return array expected values, arithmetic expression
370 */
371 public function splitCalcDataProvider() {
372 return array(
373 'empty string returns empty array' => array(
374 array(),
375 '',
376 ),
377 'number without operator returns array with plus and number' => array(
378 array(array('+', 42)),
379 '42',
380 ),
381 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
382 array(array('+', 42), array('*', 31)),
383 '42 * 31',
384 ),
385 );
386 }
387
388 /**
389 * @test
390 * @dataProvider splitCalcDataProvider
391 */
392 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
393 $this->assertEquals($expected, t3lib_div::splitCalc($expression, '+-*/'));
394 }
395
396
397 //////////////////////////////////
398 // Tests concerning calcPriority
399 //////////////////////////////////
400
401 /**
402 * Data provider for calcPriority
403 *
404 * @return array expected values, arithmetic expression
405 */
406 public function calcPriorityDataProvider() {
407 return array(
408 'add' => array(9, '6 + 3'),
409 'substract with positive result' => array(3, '6 - 3'),
410 'substract with negative result' => array(-3, '3 - 6'),
411 'multiply' => array(6, '2 * 3'),
412 'divide' => array(2.5, '5 / 2'),
413 'modulus' => array(1, '5 % 2'),
414 'power' => array(8, '2 ^ 3'),
415 'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
416 'three operands with power' => array(14, '5 + 3 ^ 2'),
417 'three operads with modulus' => array(4, '5 % 2 + 3'),
418 'four operands' => array(3, '2 + 6 / 2 - 2'),
419 );
420 }
421
422 /**
423 * @test
424 * @dataProvider calcPriorityDataProvider
425 */
426 public function calcPriorityCorrectlyCalculatesExpression($expected, $expression) {
427 $this->assertEquals($expected, t3lib_div::calcPriority($expression));
428 }
429
430
431 //////////////////////////////////
432 // Tests concerning calcPriority
433 //////////////////////////////////
434
435 /**
436 * Data provider for valid validEmail's
437 *
438 * @return array Valid email addresses
439 */
440 public function validEmailValidDataProvider() {
441 return array(
442 'short mail address' => array('a@b.c'),
443 'simple mail address' => array('test@example.com'),
444 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
445 // 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
446 // 'equal sign in local part' => array('test=mail@example.com'),
447 'dash in local part' => array('test-mail@example.com'),
448 'plus in local part' => array('test+mail@example.com'),
449 // 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
450 // 'question mark in local part' => array('test?mail@example.com'),
451 'slash in local part' => array('foo/bar@example.com'),
452 'hash in local part' => array('foo#bar@example.com'),
453 // 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
454 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
455 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
456 // 'dash as local part' => array('-@foo.com'),
457 );
458 }
459
460 /**
461 * @test
462 * @dataProvider validEmailValidDataProvider
463 */
464 public function validEmailReturnsTrueForValidMailAddress($address) {
465 $this->assertTrue(t3lib_div::validEmail($address));
466 }
467
468 /**
469 * Data provider for invalid validEmail's
470 *
471 * @return array Invalid email addresses
472 */
473 public function validEmailInvalidDataProvider() {
474 return array(
475 '@ sign only' => array('@'),
476 'duplicate @' => array('test@@example.com'),
477 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
478 'opening parenthesis in local part' => array('foo(bar@example.com'),
479 'closing parenthesis in local part' => array('foo)bar@example.com'),
480 'opening square bracket in local part' => array('foo[bar@example.com'),
481 'closing square bracket as local part' => array(']@example.com'),
482 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
483 // 'top level domain only' => array('test@com'),
484 'dash as second level domain' => array('foo@-.com'),
485 'domain part starting with dash' => array('foo@-foo.com'),
486 'domain part ending with dash' => array('foo@foo-.com'),
487 'number as top level domain' => array('foo@bar.123'),
488 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
489 // 'dash as top level domain' => array('foo@bar.-'),
490 'dot at beginning of domain part' => array('test@.com'),
491 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
492 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
493 'trailing whitespace' => array('test@example.com '),
494 'trailing carriage return' => array('test@example.com' . CR),
495 'trailing linefeed' => array('test@example.com' . LF),
496 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
497 'trailing tab' => array('test@example.com' . TAB),
498 );
499 }
500
501 /**
502 * @test
503 * @dataProvider validEmailInvalidDataProvider
504 */
505 public function validEmailReturnsFalseForInvalidMailAddress($address) {
506 $this->assertFalse(t3lib_div::validEmail($address));
507 }
508
509
510 //////////////////////////////////
511 // Tests concerning intExplode
512 //////////////////////////////////
513
514 /**
515 * @test
516 */
517 public function intExplodeConvertsStringsToInteger() {
518 $testString = '1,foo,2';
519 $expectedArray = array(1, 0, 2);
520 $actualArray = t3lib_div::intExplode(',', $testString);
521
522 $this->assertEquals($expectedArray, $actualArray);
523 }
524
525
526 //////////////////////////////////
527 // Tests concerning revExplode
528 //////////////////////////////////
529
530 /**
531 * @test
532 */
533 public function revExplodeExplodesString() {
534 $testString = 'my:words:here';
535 $expectedArray = array('my:words', 'here');
536 $actualArray = t3lib_div::revExplode(':', $testString, 2);
537
538 $this->assertEquals($expectedArray, $actualArray);
539 }
540
541
542 //////////////////////////////////
543 // Tests concerning trimExplode
544 //////////////////////////////////
545
546 /**
547 * @test
548 */
549 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
550 $testString = ' a , b , c ,d ,, e,f,';
551 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
552 $actualArray = t3lib_div::trimExplode(',', $testString);
553
554 $this->assertEquals($expectedArray, $actualArray);
555 }
556
557 /**
558 * @test
559 */
560 public function checkTrimExplodeRemovesNewLines() {
561 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
562 $expectedArray = array('a', 'b', 'd', 'e', 'f');
563 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
564
565 $this->assertEquals($expectedArray, $actualArray);
566 }
567
568 /**
569 * @test
570 */
571 public function checkTrimExplodeRemovesEmptyElements() {
572 $testString = 'a , b , c , ,d ,, ,e,f,';
573 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
574 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
575
576 $this->assertEquals($expectedArray, $actualArray);
577 }
578
579 /**
580 * @test
581 */
582 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
583 $testString = ' a , b , c , , d,, ,e ';
584 $expectedArray = array('a', 'b', 'c,,d,,,e');
585 // Limiting returns the rest of the string as the last element
586 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
587
588 $this->assertEquals($expectedArray, $actualArray);
589 }
590
591 /**
592 * @test
593 */
594 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
595 $testString = ' a , b , c , , d,, ,e ';
596 $expectedArray = array('a', 'b', 'c,d,e');
597 // Limiting returns the rest of the string as the last element
598 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
599
600 $this->assertEquals($expectedArray, $actualArray);
601 }
602
603 /**
604 * @test
605 */
606 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
607 $testString = ' a , b , c , d, ,e, f , , ';
608 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
609 // limiting returns the rest of the string as the last element
610 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
611
612 $this->assertEquals($expectedArray, $actualArray);
613 }
614
615 /**
616 * @test
617 */
618 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
619 $testString = ' a , b , c , d, ,e, f , , ';
620 $expectedArray = array('a', 'b', 'c');
621 // Limiting returns the rest of the string as the last element
622 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
623
624 $this->assertEquals($expectedArray, $actualArray);
625 }
626
627 /**
628 * @test
629 */
630 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
631 $testString = ' a , b , , c , , , ';
632 $expectedArray = array('a', 'b', 'c');
633 // Limiting returns the rest of the string as the last element
634 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
635
636 $this->assertEquals($expectedArray, $actualArray);
637 }
638
639 /**
640 * @test
641 */
642 public function checkTrimExplodeKeepsZeroAsString() {
643 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
644 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
645 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
646
647 $this->assertEquals($expectedArray, $actualArray);
648 }
649
650
651 //////////////////////////////////
652 // Tests concerning removeArrayEntryByValue
653 //////////////////////////////////
654
655 /**
656 * @test
657 */
658 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
659 $inputArray = array(
660 '0' => 'test1',
661 '1' => 'test2',
662 '2' => 'test3',
663 '3' => 'test2',
664 );
665 $compareValue = 'test2';
666 $expectedResult = array(
667 '0' => 'test1',
668 '2' => 'test3',
669 );
670 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
671 $this->assertEquals($expectedResult, $actualResult);
672 }
673
674 /**
675 * @test
676 */
677 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
678 $inputArray = array(
679 '0' => 'foo',
680 '1' => array(
681 '10' => 'bar',
682 ),
683 '2' => 'bar',
684 );
685 $compareValue = 'bar';
686 $expectedResult = array(
687 '0' => 'foo',
688 '1' => array(),
689 );
690 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
691 $this->assertEquals($expectedResult, $actualResult);
692 }
693
694 /**
695 * @test
696 */
697 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
698 $inputArray = array(
699 '0' => 'foo',
700 '1' => '',
701 '2' => 'bar',
702 );
703 $compareValue = '';
704 $expectedResult = array(
705 '0' => 'foo',
706 '2' => 'bar',
707 );
708 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
709 $this->assertEquals($expectedResult, $actualResult);
710 }
711
712 //////////////////////////////////
713 // Tests concerning getBytesFromSizeMeasurement
714 //////////////////////////////////
715
716 /**
717 * Data provider for getBytesFromSizeMeasurement
718 *
719 * @return array expected value, input string
720 */
721 public function getBytesFromSizeMeasurementDataProvider() {
722 return array(
723 '100 kilo Bytes' => array('102400', '100k'),
724 '100 mega Bytes' => array('104857600', '100m'),
725 '100 giga Bytes' => array('107374182400', '100g'),
726 );
727 }
728
729 /**
730 * @test
731 * @dataProvider getBytesFromSizeMeasurementDataProvider
732 */
733 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
734 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
735 }
736
737
738 //////////////////////////////////
739 // Tests concerning getIndpEnv
740 //////////////////////////////////
741
742 /**
743 * @test
744 */
745 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
746 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
747 }
748
749 /**
750 * @test
751 */
752 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
753 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
754 $this->assertEquals('/', $result[0]);
755 }
756
757 /**
758 * @test
759 */
760 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
761 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
762 $this->assertEquals('/', $result[strlen($result) - 1]);
763 }
764
765
766 //////////////////////////////////
767 // Tests concerning underscoredToUpperCamelCase
768 //////////////////////////////////
769
770 /**
771 * Data provider for underscoredToUpperCamelCase
772 *
773 * @return array expected, input string
774 */
775 public function underscoredToUpperCamelCaseDataProvider() {
776 return array(
777 'single word' => array('Blogexample', 'blogexample'),
778 'multiple words' => array('BlogExample', 'blog_example'),
779 );
780 }
781
782 /**
783 * @test
784 * @dataProvider underscoredToUpperCamelCaseDataProvider
785 */
786 public function underscoredToUpperCamelCase($expected, $inputString) {
787 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
788 }
789
790
791 //////////////////////////////////
792 // Tests concerning underscoredToLowerCamelCase
793 //////////////////////////////////
794
795 /**
796 * Data provider for underscoredToLowerCamelCase
797 *
798 * @return array expected, input string
799 */
800 public function underscoredToLowerCamelCaseDataProvider() {
801 return array(
802 'single word' => array('minimalvalue', 'minimalvalue'),
803 'multiple words' => array('minimalValue', 'minimal_value'),
804 );
805 }
806
807 /**
808 * @test
809 * @dataProvider underscoredToLowerCamelCaseDataProvider
810 */
811 public function underscoredToLowerCamelCase($expected, $inputString) {
812 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
813 }
814
815 //////////////////////////////////
816 // Tests concerning camelCaseToLowerCaseUnderscored
817 //////////////////////////////////
818
819 /**
820 * Data provider for camelCaseToLowerCaseUnderscored
821 *
822 * @return array expected, input string
823 */
824 public function camelCaseToLowerCaseUnderscoredDataProvider() {
825 return array(
826 'single word' => array('blogexample', 'blogexample'),
827 'single word starting upper case' => array('blogexample', 'Blogexample'),
828 'two words starting lower case' => array('minimal_value', 'minimalValue'),
829 'two words starting upper case' => array('blog_example', 'BlogExample'),
830 );
831 }
832
833 /**
834 * @test
835 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
836 */
837 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
838 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
839 }
840
841
842 //////////////////////////////////
843 // Tests concerning lcFirst
844 //////////////////////////////////
845
846 /**
847 * Data provider for lcFirst
848 *
849 * @return array expected, input string
850 */
851 public function lcfirstDataProvider() {
852 return array(
853 'single word' => array('blogexample', 'blogexample'),
854 'single Word starting upper case' => array('blogexample', 'Blogexample'),
855 'two words' => array('blogExample', 'BlogExample'),
856 );
857 }
858
859 /**
860 * @test
861 * @dataProvider lcfirstDataProvider
862 */
863 public function lcFirst($expected, $inputString) {
864 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
865 }
866
867
868 //////////////////////////////////
869 // Tests concerning encodeHeader
870 //////////////////////////////////
871
872 /**
873 * @test
874 */
875 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
876 $this->assertEquals(
877 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
878 t3lib_div::encodeHeader(
879 "We test whether the copyright character \xc2\xa9 is encoded correctly",
880 'quoted-printable',
881 'utf-8'
882 )
883 );
884 }
885
886 /**
887 * @test
888 */
889 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
890 $this->assertEquals(
891 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
892 t3lib_div::encodeHeader(
893 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
894 'quoted-printable',
895 'utf-8'
896 )
897 );
898 }
899
900
901 //////////////////////////////////
902 // Tests concerning isValidUrl
903 //////////////////////////////////
904
905 /**
906 * Data provider for valid isValidUrl's
907 *
908 * @return array Valid ressource
909 */
910 public function validUrlValidRessourceDataProvider() {
911 return array(
912 'http' => array('http://www.example.org/'),
913 'http without trailing slash' => array('http://qwe'),
914 'http directory with trailing slash' => array('http://www.example/img/dir/'),
915 'http directory without trailing slash' => array('http://www.example/img/dir'),
916 'http index.html' => array('http://example.com/index.html'),
917 'http index.php' => array('http://www.example.com/index.php'),
918 'http test.png' => array('http://www.example/img/test.png'),
919 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
920 'file' => array('file:///tmp/test.c'),
921 'file directory' => array('file://foo/bar'),
922 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
923 'mailto' => array('mailto:foo@bar.com'),
924 'news' => array('news:news.php.net'),
925 'telnet'=> array('telnet://192.0.2.16:80/'),
926 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
927 );
928 }
929
930 /**
931 * @test
932 * @dataProvider validUrlValidRessourceDataProvider
933 */
934 public function validURLReturnsTrueForValidRessource($url) {
935 $this->assertTrue(t3lib_div::isValidUrl($url));
936 }
937
938 /**
939 * Data provider for invalid isValidUrl's
940 *
941 * @return array Invalid ressource
942 */
943 public function isValidUrlInvalidRessourceDataProvider() {
944 return array(
945 'http missing colon' => array('http//www.example/wrong/url/'),
946 'http missing slash' => array('http:/www.example'),
947 'hostname only' => array('www.example.org/'),
948 'file missing protocol specification' => array('/tmp/test.c'),
949 'slash only' => array('/'),
950 'string http://' => array('http://'),
951 'string http:/' => array('http:/'),
952 'string http:' => array('http:'),
953 'string http' => array('http'),
954 'empty string' => array(''),
955 'string -1' => array('-1'),
956 'string array()' => array('array()'),
957 'random string' => array('qwe'),
958 );
959 }
960
961 /**
962 * @test
963 * @dataProvider isValidUrlInvalidRessourceDataProvider
964 */
965 public function validURLReturnsFalseForInvalidRessoure($url) {
966 $this->assertFalse(t3lib_div::isValidUrl($url));
967 }
968
969
970 //////////////////////////////////
971 // Tests concerning isOnCurrentHost
972 //////////////////////////////////
973
974 /**
975 * @test
976 */
977 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
978 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
979 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
980 }
981
982 /**
983 * Data provider for invalid isOnCurrentHost's
984 *
985 * @return array Invalid Hosts
986 */
987 public function checkisOnCurrentHostInvalidHosts() {
988 return array(
989 'empty string' => array(''),
990 'arbitrary string' => array('arbitrary string'),
991 'localhost IP' => array('127.0.0.1'),
992 'relative path' => array('./relpath/file.txt'),
993 'absolute path' => array('/abspath/file.txt?arg=value'),
994 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
995 );
996 }
997
998
999 ////////////////////////////////////////
1000 // Tests concerning sanitizeLocalUrl
1001 ////////////////////////////////////////
1002
1003 /**
1004 * Data provider for valid sanitizeLocalUrl's
1005 *
1006 * @return array Valid url
1007 */
1008 public function sanitizeLocalUrlValidUrlDataProvider() {
1009 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1010 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1011 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
1012
1013 return array(
1014 'alt_intro.php' => array('alt_intro.php'),
1015 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1016 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1017 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1018 '../index.php' => array('../index.php'),
1019 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1020 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1021 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1022 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
1023 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1024 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
1025 );
1026 }
1027
1028 /**
1029 * @test
1030 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1031 */
1032 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1033 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
1034 }
1035
1036 /**
1037 * @test
1038 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1039 */
1040 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
1041 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1042 }
1043
1044 /**
1045 * Data provider for invalid sanitizeLocalUrl's
1046 *
1047 * @return array Valid url
1048 */
1049 public function sanitizeLocalUrlInvalidDataProvider() {
1050 return array(
1051 'empty string' => array(''),
1052 'http domain' => array('http://www.google.de/'),
1053 'https domain' => array('https://www.google.de/'),
1054 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
1055 );
1056 }
1057
1058 /**
1059 * @test
1060 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1061 */
1062 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
1063 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
1064 }
1065
1066 /**
1067 * @test
1068 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1069 */
1070 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
1071 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1072 }
1073
1074
1075 //////////////////////////////////////
1076 // Tests concerning arrayDiffAssocRecursive
1077 //////////////////////////////////////
1078
1079 /**
1080 * @test
1081 */
1082 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1083 $array1 = array(
1084 'key1' => 'value1',
1085 'key2' => 'value2',
1086 'key3' => 'value3',
1087 );
1088 $array2 = array(
1089 'key1' => 'value1',
1090 'key3' => 'value3',
1091 );
1092 $expectedResult = array(
1093 'key2' => 'value2',
1094 );
1095 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1096 $this->assertEquals($expectedResult, $actualResult);
1097 }
1098
1099 /**
1100 * @test
1101 */
1102 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1103 $array1 = array(
1104 'key1' => 'value1',
1105 'key2' => array(
1106 'key21' => 'value21',
1107 'key22' => 'value22',
1108 'key23' => array(
1109 'key231' => 'value231',
1110 'key232' => 'value232',
1111 ),
1112 ),
1113 );
1114 $array2 = array(
1115 'key1' => 'value1',
1116 'key2' => array(
1117 'key21' => 'value21',
1118 'key23' => array(
1119 'key231' => 'value231',
1120 ),
1121 ),
1122 );
1123 $expectedResult = array(
1124 'key2' => array(
1125 'key22' => 'value22',
1126 'key23' => array(
1127 'key232' => 'value232',
1128 ),
1129 ),
1130 );
1131 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1132 $this->assertEquals($expectedResult, $actualResult);
1133 }
1134
1135 /**
1136 * @test
1137 */
1138 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1139 $array1 = array(
1140 'key1' => array(
1141 'key11' => 'value11',
1142 'key12' => 'value12',
1143 ),
1144 'key2' => 'value2',
1145 'key3' => 'value3',
1146 );
1147 $array2 = array(
1148 'key1' => 'value1',
1149 'key2' => array(
1150 'key21' => 'value21',
1151 ),
1152 );
1153 $expectedResult = array(
1154 'key3' => 'value3',
1155 );
1156 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1157 $this->assertEquals($expectedResult, $actualResult);
1158 }
1159
1160
1161 //////////////////////////////////////
1162 // Tests concerning removeDotsFromTS
1163 //////////////////////////////////////
1164
1165 /**
1166 * @test
1167 */
1168 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1169 $typoScript = array(
1170 'propertyA.' => array(
1171 'keyA.' => array(
1172 'valueA' => 1,
1173 ),
1174 'keyB' => 2,
1175 ),
1176 'propertyB' => 3,
1177 );
1178
1179 $expectedResult = array(
1180 'propertyA' => array(
1181 'keyA' => array(
1182 'valueA' => 1,
1183 ),
1184 'keyB' => 2,
1185 ),
1186 'propertyB' => 3,
1187 );
1188
1189 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1190 }
1191
1192 /**
1193 * @test
1194 */
1195 public function removeDotsFromTypoScriptOverridesSubArray() {
1196 $typoScript = array(
1197 'propertyA.' => array(
1198 'keyA' => 'getsOverridden',
1199 'keyA.' => array(
1200 'valueA' => 1,
1201 ),
1202 'keyB' => 2,
1203 ),
1204 'propertyB' => 3,
1205 );
1206
1207 $expectedResult = array(
1208 'propertyA' => array(
1209 'keyA' => array(
1210 'valueA' => 1,
1211 ),
1212 'keyB' => 2,
1213 ),
1214 'propertyB' => 3,
1215 );
1216
1217 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1218 }
1219
1220 /**
1221 * @test
1222 */
1223 public function removeDotsFromTypoScriptOverridesWithScalar() {
1224 $typoScript = array(
1225 'propertyA.' => array(
1226 'keyA.' => array(
1227 'valueA' => 1,
1228 ),
1229 'keyA' => 'willOverride',
1230 'keyB' => 2,
1231 ),
1232 'propertyB' => 3,
1233 );
1234
1235 $expectedResult = array(
1236 'propertyA' => array(
1237 'keyA' => 'willOverride',
1238 'keyB' => 2,
1239 ),
1240 'propertyB' => 3,
1241 );
1242
1243 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1244 }
1245
1246
1247 //////////////////////////////////////
1248 // Tests concerning get_dirs
1249 //////////////////////////////////////
1250
1251 /**
1252 * @test
1253 */
1254 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1255 $path = PATH_t3lib;
1256 $directories = t3lib_div::get_dirs($path);
1257
1258 $this->assertType('array', $directories);
1259 }
1260
1261 /**
1262 * @test
1263 */
1264 public function getDirsReturnsStringErrorOnPathFailure() {
1265 $path = 'foo';
1266 $result = t3lib_div::get_dirs($path);
1267 $expectedResult = 'error';
1268
1269 $this->assertEquals($expectedResult, $result);
1270 }
1271
1272
1273 //////////////////////////////////
1274 // Tests concerning hmac
1275 //////////////////////////////////
1276
1277 /**
1278 * @test
1279 */
1280 public function hmacReturnsHashOfProperLength() {
1281 $hmac = t3lib_div::hmac('message');
1282 $this->assertTrue(!empty($hmac) && is_string($hmac));
1283 $this->assertTrue(strlen($hmac) == 40);
1284 }
1285
1286 /**
1287 * @test
1288 */
1289 public function hmacReturnsEqualHashesForEqualInput() {
1290 $msg0 = 'message';
1291 $msg1 = 'message';
1292 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1293 }
1294
1295 /**
1296 * @test
1297 */
1298 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1299 $msg0 = 'message0';
1300 $msg1 = 'message1';
1301 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1302 }
1303
1304
1305 //////////////////////////////////
1306 // Tests concerning quoteJSvalue
1307 //////////////////////////////////
1308
1309 /**
1310 * @test
1311 */
1312 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1313 $this->assertContains(
1314 '&gt;',
1315 t3lib_div::quoteJSvalue('>')
1316 );
1317 }
1318
1319 /**
1320 * @test
1321 */
1322 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1323 $this->assertContains(
1324 '&gt;',
1325 t3lib_div::quoteJSvalue('>', false)
1326 );
1327 }
1328
1329 /**
1330 * @test
1331 */
1332 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1333 $this->assertContains(
1334 '>',
1335 t3lib_div::quoteJSvalue('>', true)
1336 );
1337 }
1338
1339 /**
1340 * @test
1341 */
1342 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1343 $this->assertEquals(
1344 "''",
1345 t3lib_div::quoteJSvalue("", true)
1346 );
1347 }
1348
1349 /**
1350 * @test
1351 */
1352 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1353 $this->assertEquals(
1354 "'Hello world!'",
1355 t3lib_div::quoteJSvalue("Hello world!", true)
1356 );
1357 }
1358
1359 /**
1360 * @test
1361 */
1362 public function quoteJSvalueEscapesSingleQuote() {
1363 $this->assertEquals(
1364 "'\\''",
1365 t3lib_div::quoteJSvalue("'", true)
1366 );
1367 }
1368
1369 /**
1370 * @test
1371 */
1372 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1373 $this->assertEquals(
1374 "'\\\"'",
1375 t3lib_div::quoteJSvalue('"', true)
1376 );
1377 }
1378
1379 /**
1380 * @test
1381 */
1382 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1383 $this->assertEquals(
1384 "'\\&quot;'",
1385 t3lib_div::quoteJSvalue('"', false)
1386 );
1387 }
1388
1389 /**
1390 * @test
1391 */
1392 public function quoteJSvalueEscapesTab() {
1393 $this->assertEquals(
1394 "'" . '\t' . "'",
1395 t3lib_div::quoteJSvalue(TAB)
1396 );
1397 }
1398
1399 /**
1400 * @test
1401 */
1402 public function quoteJSvalueEscapesLinefeed() {
1403 $this->assertEquals(
1404 "'" . '\n' . "'",
1405 t3lib_div::quoteJSvalue(LF)
1406 );
1407 }
1408
1409 /**
1410 * @test
1411 */
1412 public function quoteJSvalueEscapesCarriageReturn() {
1413 $this->assertEquals(
1414 "'" . '\r' . "'",
1415 t3lib_div::quoteJSvalue(CR)
1416 );
1417 }
1418
1419 /**
1420 * @test
1421 */
1422 public function quoteJSvalueEscapesBackslah() {
1423 $this->assertEquals(
1424 "'\\\\'",
1425 t3lib_div::quoteJSvalue('\\')
1426 );
1427 }
1428
1429 //////////////////////////////////
1430 // Tests concerning readLLfile
1431 //////////////////////////////////
1432
1433 /**
1434 * @test
1435 */
1436 public function readLLfileHandlesLocallangXMLOverride() {
1437 $unique = uniqid('locallangXMLOverrideTest');
1438
1439 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
1440 <T3locallang>
1441 <data type="array">
1442 <languageKey index="default" type="array">
1443 <label index="buttons.logout">EXIT</label>
1444 </languageKey>
1445 </data>
1446 </T3locallang>';
1447
1448 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
1449 t3lib_div::writeFileToTypo3tempDir($file, $xml);
1450
1451 // Get default value
1452 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1453
1454 // Set override file
1455 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
1456
1457 // Get override value
1458 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1459
1460 // Clean up again
1461 unlink($file);
1462
1463 $this->assertNotEquals($overrideLL['default']['buttons.logout'], '');
1464 $this->assertNotEquals($defaultLL['default']['buttons.logout'], $overrideLL['default']['buttons.logout']);
1465 $this->assertEquals($overrideLL['default']['buttons.logout'], 'EXIT');
1466 }
1467
1468
1469 ///////////////////////////////
1470 // Tests concerning _GETset()
1471 ///////////////////////////////
1472
1473 /**
1474 * @test
1475 */
1476 public function getSetWritesArrayToGetSystemVariable() {
1477 $_GET = array();
1478 $GLOBALS['HTTP_GET_VARS'] = array();
1479
1480 $getParameters = array('foo' => 'bar');
1481 t3lib_div::_GETset($getParameters);
1482 $this->assertSame($getParameters, $_GET);
1483 }
1484
1485 /**
1486 * @test
1487 */
1488 public function getSetWritesArrayToGlobalsHttpGetVars() {
1489 $_GET = array();
1490 $GLOBALS['HTTP_GET_VARS'] = array();
1491
1492 $getParameters = array('foo' => 'bar');
1493 t3lib_div::_GETset($getParameters);
1494 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
1495 }
1496
1497 /**
1498 * @test
1499 */
1500 public function getSetForArrayDropsExistingValues() {
1501 $_GET = array();
1502 $GLOBALS['HTTP_GET_VARS'] = array();
1503
1504 t3lib_div::_GETset(array('foo' => 'bar'));
1505
1506 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
1507
1508 $this->assertEquals(
1509 array('oneKey' => 'oneValue'),
1510 $GLOBALS['HTTP_GET_VARS']
1511 );
1512 }
1513
1514 /**
1515 * @test
1516 */
1517 public function getSetAssignsOneValueToOneKey() {
1518 $_GET = array();
1519 $GLOBALS['HTTP_GET_VARS'] = array();
1520
1521 t3lib_div::_GETset('oneValue', 'oneKey');
1522
1523 $this->assertEquals(
1524 'oneValue',
1525 $GLOBALS['HTTP_GET_VARS']['oneKey']
1526 );
1527 }
1528
1529 /**
1530 * @test
1531 */
1532 public function getSetForOneValueDoesNotDropUnrelatedValues() {
1533 $_GET = array();
1534 $GLOBALS['HTTP_GET_VARS'] = array();
1535
1536 t3lib_div::_GETset(array('foo' => 'bar'));
1537 t3lib_div::_GETset('oneValue', 'oneKey');
1538
1539 $this->assertEquals(
1540 array('foo' => 'bar', 'oneKey' => 'oneValue'),
1541 $GLOBALS['HTTP_GET_VARS']
1542 );
1543 }
1544
1545 /**
1546 * @test
1547 */
1548 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
1549 $_GET = array();
1550 $GLOBALS['HTTP_GET_VARS'] = array();
1551
1552 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
1553
1554 $this->assertEquals(
1555 array('parentKey' => array('childKey' => 'oneValue')),
1556 $GLOBALS['HTTP_GET_VARS']
1557 );
1558 }
1559
1560 /**
1561 * @test
1562 */
1563 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
1564 $_GET = array();
1565 $GLOBALS['HTTP_GET_VARS'] = array();
1566
1567 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
1568
1569 $this->assertEquals(
1570 array('parentKey' => array('childKey' => 'oneValue')),
1571 $GLOBALS['HTTP_GET_VARS']
1572 );
1573 }
1574
1575 /**
1576 * @test
1577 */
1578 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
1579 $_GET = array();
1580 $GLOBALS['HTTP_GET_VARS'] = array();
1581
1582 t3lib_div::_GETset(
1583 array('key1' => 'value1', 'key2' => 'value2'),
1584 'parentKey|childKey'
1585 );
1586
1587 $this->assertEquals(
1588 array(
1589 'parentKey' => array(
1590 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
1591 )
1592 ),
1593 $GLOBALS['HTTP_GET_VARS']
1594 );
1595 }
1596
1597
1598 ///////////////////////////////
1599 // Tests concerning fixPermissions
1600 ///////////////////////////////
1601
1602 /**
1603 * @test
1604 */
1605 public function fixPermissionsCorrectlySetsPermissionsToFile() {
1606 if (TYPO3_OS == 'WIN') {
1607 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1608 }
1609
1610 // Create and prepare test file
1611 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
1612 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1613 chmod($filename, 0742);
1614
1615 // Set target permissions and run method
1616 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1617 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1618 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1619
1620 // Get actual permissions and clean up
1621 clearstatcache();
1622 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1623 $resultFileGroup = filegroup($filename);
1624 unlink($filename);
1625
1626 // Test if everything was ok
1627 $this->assertTrue($fixPermissionsResult);
1628 $this->assertEquals($resultFilePermissions, '0660');
1629 $this->assertEquals($resultFileGroup, posix_getegid());
1630 }
1631
1632 /**
1633 * @test
1634 */
1635 public function fixPermissionsCorrectlySetsPermissionsToHiddenFile() {
1636 if (TYPO3_OS == 'WIN') {
1637 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1638 }
1639
1640 // Create and prepare test file
1641 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
1642 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1643 chmod($filename, 0742);
1644
1645 // Set target permissions and run method
1646 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1647 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1648 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1649
1650 // Get actual permissions and clean up
1651 clearstatcache();
1652 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1653 $resultFileGroup = filegroup($filename);
1654 unlink($filename);
1655
1656 // Test if everything was ok
1657 $this->assertTrue($fixPermissionsResult);
1658 $this->assertEquals($resultFilePermissions, '0660');
1659 $this->assertEquals($resultFileGroup, posix_getegid());
1660 }
1661
1662 /**
1663 * @test
1664 */
1665 public function fixPermissionsCorrectlySetsPermissionsToDirectory() {
1666 if (TYPO3_OS == 'WIN') {
1667 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1668 }
1669
1670 // Create and prepare test directory
1671 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1672 t3lib_div::mkdir($directory);
1673 chmod($directory, 1551);
1674
1675 // Set target permissions and run method
1676 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1677 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1678 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
1679
1680 // Get actual permissions and clean up
1681 clearstatcache();
1682 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1683 $resultDirectoryGroup = filegroup($directory);
1684 t3lib_div::rmdir($directory);
1685
1686 // Test if everything was ok
1687 $this->assertTrue($fixPermissionsResult);
1688 $this->assertEquals($resultDirectoryPermissions, '0770');
1689 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1690 }
1691
1692 /**
1693 * @test
1694 */
1695 public function fixPermissionsCorrectlySetsPermissionsToHiddenDirectory() {
1696 if (TYPO3_OS == 'WIN') {
1697 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1698 }
1699
1700 // Create and prepare test directory
1701 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1702 t3lib_div::mkdir($directory);
1703 chmod($directory, 1551);
1704
1705 // Set target permissions and run method
1706 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1707 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1708 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
1709
1710 // Get actual permissions and clean up
1711 clearstatcache();
1712 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1713 $resultDirectoryGroup = filegroup($directory);
1714 t3lib_div::rmdir($directory);
1715
1716 // Test if everything was ok
1717 $this->assertTrue($fixPermissionsResult);
1718 $this->assertEquals($resultDirectoryPermissions, '0770');
1719 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1720 }
1721
1722 /**
1723 * @test
1724 */
1725 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
1726 if (TYPO3_OS == 'WIN') {
1727 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1728 }
1729
1730 // Create and prepare test directory and file structure
1731 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
1732 t3lib_div::mkdir($baseDirectory);
1733 chmod($baseDirectory, 1751);
1734 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
1735 chmod($baseDirectory . '/file', 0742);
1736 t3lib_div::mkdir($baseDirectory . '/foo');
1737 chmod($baseDirectory . '/foo', 1751);
1738 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
1739 chmod($baseDirectory . '/foo/file', 0742);
1740 t3lib_div::mkdir($baseDirectory . '/.bar');
1741 chmod($baseDirectory . '/.bar', 1751);
1742 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
1743 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
1744 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
1745 touch($baseDirectory . '/.bar/.file', '42');
1746 chmod($baseDirectory . '/.bar/.file', 0742);
1747 touch($baseDirectory . '/.bar/..file2', '42');
1748 chmod($baseDirectory . '/.bar/..file2', 0742);
1749
1750 // Set target permissions and run method
1751 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1752 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1753 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1754 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
1755
1756 // Get actual permissions
1757 clearstatcache();
1758 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
1759 $resultBaseDirectoryGroup = filegroup($baseDirectory);
1760 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
1761 $resultBaseFileGroup = filegroup($baseDirectory . '/file');
1762 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
1763 $resultFooDirectoryGroup = filegroup($baseDirectory . '/foo');
1764 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
1765 $resultFooFileGroup = filegroup($baseDirectory . '/foo/file');
1766 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
1767 $resultBarDirectoryGroup = filegroup($baseDirectory . '/.bar');
1768 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
1769 $resultBarFileGroup = filegroup($baseDirectory . '/.bar/.file');
1770 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
1771 $resultBarFile2Group = filegroup($baseDirectory . '/.bar/..file2');
1772
1773 // Clean up
1774 unlink($baseDirectory . '/file');
1775 unlink($baseDirectory . '/foo/file');
1776 unlink($baseDirectory . '/.bar/.file');
1777 unlink($baseDirectory . '/.bar/..file2');
1778 t3lib_div::rmdir($baseDirectory . '/foo');
1779 t3lib_div::rmdir($baseDirectory . '/.bar');
1780 t3lib_div::rmdir($baseDirectory);
1781
1782 // Test if everything was ok
1783 $this->assertTrue($fixPermissionsResult);
1784 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
1785 $this->assertEquals($resultBaseDirectoryGroup, posix_getegid());
1786 $this->assertEquals($resultBaseFilePermissions, '0660');
1787 $this->assertEquals($resultBaseFileGroup, posix_getegid());
1788 $this->assertEquals($resultFooDirectoryPermissions, '0770');
1789 $this->assertEquals($resultFooDirectoryGroup, posix_getegid());
1790 $this->assertEquals($resultFooFilePermissions, '0660');
1791 $this->assertEquals($resultFooFileGroup, posix_getegid());
1792 $this->assertEquals($resultBarDirectoryPermissions, '0770');
1793 $this->assertEquals($resultBarDirectoryGroup, posix_getegid());
1794 $this->assertEquals($resultBarFilePermissions, '0660');
1795 $this->assertEquals($resultBarFileGroup, posix_getegid());
1796 $this->assertEquals($resultBarFile2Permissions, '0660');
1797 $this->assertEquals($resultBarFile2Group, posix_getegid());
1798 }
1799
1800 /**
1801 * @test
1802 */
1803 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
1804 if (TYPO3_OS == 'WIN') {
1805 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1806 }
1807
1808 // Create and prepare test file
1809 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
1810 touch($filename);
1811 chmod($filename, 0742);
1812
1813 // Set target permissions and run method
1814 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1815 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1816
1817 // Get actual permissions and clean up
1818 clearstatcache();
1819 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1820 unlink($filename);
1821
1822 // Test if everything was ok
1823 $this->assertFalse($fixPermissionsResult);
1824 $this->assertEquals($resultFilePermissions, '0742');
1825 }
1826
1827
1828 ///////////////////////////////
1829 // Tests concerning mkdir
1830 ///////////////////////////////
1831
1832 /**
1833 * @test
1834 */
1835 public function mkdirCorrectlyCreatesDirectory() {
1836 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1837 $mkdirResult = t3lib_div::mkdir($directory);
1838 $directoryCreated = is_dir($directory);
1839 t3lib_div::rmdir($directory);
1840 $this->assertTrue($mkdirResult);
1841 $this->assertTrue($directoryCreated);
1842 }
1843
1844 /**
1845 * @test
1846 */
1847 public function mkdirCorrectlyCreatesHiddenDirectory() {
1848 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1849 $mkdirResult = t3lib_div::mkdir($directory);
1850 $directoryCreated = is_dir($directory);
1851 t3lib_div::rmdir($directory);
1852 $this->assertTrue($mkdirResult);
1853 $this->assertTrue($directoryCreated);
1854 }
1855
1856 /**
1857 * @test
1858 */
1859 public function mkdirCorrectlyCreatesDirectoryWithTrailingSlash() {
1860 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1861 $mkdirResult = t3lib_div::mkdir($directory);
1862 $directoryCreated = is_dir($directory);
1863 t3lib_div::rmdir($directory);
1864 $this->assertTrue($mkdirResult);
1865 $this->assertTrue($directoryCreated);
1866 }
1867
1868 /**
1869 * Data provider for ImageMagick shell commands
1870 * @see explodeAndUnquoteImageMagickCommands
1871 */
1872 public function imageMagickCommandsDataProvider() {
1873 return array(
1874 // Some theoretical tests first
1875 array(
1876 'aa bb "cc" "dd"',
1877 array('aa', 'bb', '"cc"', '"dd"'),
1878 array('aa', 'bb', 'cc', 'dd'),
1879 ),
1880 array(
1881 'aa bb "cc dd"',
1882 array('aa', 'bb', '"cc dd"'),
1883 array('aa', 'bb', 'cc dd'),
1884 ),
1885 array(
1886 '\'aa bb\' "cc dd"',
1887 array('\'aa bb\'', '"cc dd"'),
1888 array('aa bb', 'cc dd'),
1889 ),
1890 array(
1891 '\'aa bb\' cc "dd"',
1892 array('\'aa bb\'', 'cc', '"dd"'),
1893 array('aa bb', 'cc', 'dd'),
1894 ),
1895 // Now test against some real world examples
1896 array(
1897 '/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"',
1898 array(
1899 '/opt/local/bin/gm.exe',
1900 'convert',
1901 '+profile',
1902 '\'*\'',
1903 '-geometry',
1904 '170x136!',
1905 '-negate',
1906 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
1907 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
1908 ),
1909 array(
1910 '/opt/local/bin/gm.exe',
1911 'convert',
1912 '+profile',
1913 '*',
1914 '-geometry',
1915 '170x136!',
1916 '-negate',
1917 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
1918 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
1919 ),
1920 ),
1921 array(
1922 '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"',
1923 array(
1924 'C:/opt/local/bin/gm.exe',
1925 'convert',
1926 '+profile',
1927 '\'*\'',
1928 '-geometry',
1929 '170x136!',
1930 '-negate',
1931 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
1932 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
1933 ),
1934 array(
1935 'C:/opt/local/bin/gm.exe',
1936 'convert',
1937 '+profile',
1938 '*',
1939 '-geometry',
1940 '170x136!',
1941 '-negate',
1942 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
1943 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
1944 ),
1945 ),
1946 array(
1947 '/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"',
1948 array(
1949 '/usr/bin/gm',
1950 'convert',
1951 '+profile',
1952 '\'*\'',
1953 '-geometry',
1954 '170x136!',
1955 '-negate',
1956 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
1957 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
1958 ),
1959 array(
1960 '/usr/bin/gm',
1961 'convert',
1962 '+profile',
1963 '*',
1964 '-geometry',
1965 '170x136!',
1966 '-negate',
1967 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
1968 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
1969 ),
1970 ),
1971 array(
1972 '/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"',
1973 array(
1974 '/usr/bin/gm',
1975 'convert',
1976 '+profile',
1977 '\'*\'',
1978 '-geometry',
1979 '170x136!',
1980 '-negate',
1981 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
1982 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
1983 ),
1984 array(
1985 '/usr/bin/gm',
1986 'convert',
1987 '+profile',
1988 '*',
1989 '-geometry',
1990 '170x136!',
1991 '-negate',
1992 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
1993 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
1994 ),
1995 ),
1996 array(
1997 '/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\'',
1998 array(
1999 '/usr/bin/gm',
2000 'convert',
2001 '+profile',
2002 '\'*\'',
2003 '-geometry',
2004 '170x136!',
2005 '-negate',
2006 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2007 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2008 ),
2009 array(
2010 '/usr/bin/gm',
2011 'convert',
2012 '+profile',
2013 '*',
2014 '-geometry',
2015 '170x136!',
2016 '-negate',
2017 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2018 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2019 ),
2020 ),
2021 );
2022 }
2023
2024 /**
2025 * Tests if the commands are exploded and unquoted correctly
2026 *
2027 * @dataProvider imageMagickCommandsDataProvider
2028 * @test
2029 */
2030 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2031 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2032 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2033
2034 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2035 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2036 }
2037
2038
2039 ///////////////////////////////
2040 // Tests concerning split_fileref
2041 ///////////////////////////////
2042
2043 /**
2044 * @test
2045 */
2046 public function splitFileRefReturnsFileTypeNotForFolders(){
2047 $directoryName = uniqid('test_') . '.com';
2048 $directoryPath = PATH_site . 'typo3temp/';
2049 $directory = $directoryPath . $directoryName;
2050 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
2051
2052 $fileInfo = t3lib_div::split_fileref($directory);
2053
2054 $directoryCreated = is_dir($directory);
2055 rmdir($directory);
2056
2057 $this->assertTrue($directoryCreated);
2058 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2059 $this->assertEquals($directoryPath, $fileInfo['path']);
2060 $this->assertEquals($directoryName, $fileInfo['file']);
2061 $this->assertEquals($directoryName, $fileInfo['filebody']);
2062 $this->assertEquals('', $fileInfo['fileext']);
2063 $this->assertArrayNotHasKey('realFileext', $fileInfo);
2064 }
2065
2066 /**
2067 * @test
2068 */
2069 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
2070 $testFile = 'fileadmin/media/someFile.png';
2071
2072 $fileInfo = t3lib_div::split_fileref($testFile);
2073 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2074 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
2075 $this->assertEquals('someFile.png', $fileInfo['file']);
2076 $this->assertEquals('someFile', $fileInfo['filebody']);
2077 $this->assertEquals('png', $fileInfo['fileext']);
2078 }
2079
2080
2081 /////////////////////////////
2082 // Tests concerning dirname
2083 /////////////////////////////
2084
2085 /**
2086 * @see dirnameWithDataProvider
2087 *
2088 * @return array<array>
2089 */
2090 public function dirnameDataProvider() {
2091 return array(
2092 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
2093 'absolute path with one part' => array('/dir1/', '/dir1'),
2094 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
2095 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
2096 'relative one-character path with one part and file' => array('d/script.php', 'd'),
2097 'absolute zero-part path with file' => array('/script.php', ''),
2098 'empty string' => array('', ''),
2099 );
2100 }
2101
2102 /**
2103 * @test
2104 *
2105 * @dataProvider dirnameDataProvider
2106 *
2107 * @param string $input the input for dirname
2108 * @param string $expectedValue the expected return value expected from dirname
2109 */
2110 public function dirnameWithDataProvider($input, $expectedValue) {
2111 $this->assertEquals(
2112 $expectedValue,
2113 t3lib_div::dirname($input)
2114 );
2115 }
2116
2117
2118 /////////////////////////////////////////////////////////////////////////////////////
2119 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
2120 /////////////////////////////////////////////////////////////////////////////////////
2121
2122 /**
2123 * @test
2124 *
2125 * @expectedException InvalidArgumentException
2126 */
2127 public function makeInstanceWithEmptyClassNameThrowsException() {
2128 t3lib_div::makeInstance('');
2129 }
2130
2131 /**
2132 * @test
2133 */
2134 public function makeInstanceReturnsClassInstance() {
2135 $className = get_class($this->getMock('foo'));
2136
2137 $this->assertTrue(
2138 t3lib_div::makeInstance($className) instanceof $className
2139 );
2140 }
2141
2142 /**
2143 * @test
2144 */
2145 public function makeInstancePassesParametersToConstructor() {
2146 $className = 'testingClass' . uniqid();
2147 if (!class_exists($className, FALSE)) {
2148 eval(
2149 'class ' . $className . ' {' .
2150 ' public $constructorParameter1;' .
2151 ' public $constructorParameter2;' .
2152 ' public function __construct($parameter1, $parameter2) {' .
2153 ' $this->constructorParameter1 = $parameter1;' .
2154 ' $this->constructorParameter2 = $parameter2;' .
2155 ' }' .
2156 '}'
2157 );
2158 }
2159
2160 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
2161
2162 $this->assertEquals(
2163 'one parameter',
2164 $instance->constructorParameter1,
2165 'The first constructor parameter has not been set.'
2166 );
2167 $this->assertEquals(
2168 'another parameter',
2169 $instance->constructorParameter2,
2170 'The second constructor parameter has not been set.'
2171 );
2172 }
2173
2174 /**
2175 * @test
2176 */
2177 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
2178 $className = get_class($this->getMock('foo'));
2179
2180 $this->assertNotSame(
2181 t3lib_div::makeInstance($className),
2182 t3lib_div::makeInstance($className)
2183 );
2184 }
2185
2186 /**
2187 * @test
2188 */
2189 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
2190 $className = get_class($this->getMock('t3lib_Singleton'));
2191
2192 $this->assertSame(
2193 t3lib_div::makeInstance($className),
2194 t3lib_div::makeInstance($className)
2195 );
2196 }
2197
2198 /**
2199 * @test
2200 */
2201 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
2202 $className = get_class($this->getMock('t3lib_Singleton'));
2203
2204 $instance = t3lib_div::makeInstance($className);
2205 t3lib_div::purgeInstances();
2206
2207 $this->assertNotSame(
2208 $instance,
2209 t3lib_div::makeInstance($className)
2210 );
2211 }
2212
2213 /**
2214 * @test
2215 * @expectedException InvalidArgumentException
2216 */
2217 public function setSingletonInstanceForEmptyClassNameThrowsException() {
2218 $instance = $this->getMock('t3lib_Singleton');
2219
2220 t3lib_div::setSingletonInstance('', $instance);
2221 }
2222
2223 /**
2224 * @test
2225 * @expectedException InvalidArgumentException
2226 */
2227 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
2228 $instance = $this->getMock('t3lib_Singleton', array('foo'));
2229 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
2230
2231 t3lib_div::setSingletonInstance($singletonClassName, $instance);
2232 }
2233
2234 /**
2235 * @test
2236 */
2237 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
2238 $instance = $this->getMock('t3lib_Singleton');
2239 $singletonClassName = get_class($instance);
2240
2241 t3lib_div::setSingletonInstance($singletonClassName, $instance);
2242
2243 $this->assertSame(
2244 $instance,
2245 t3lib_div::makeInstance($singletonClassName)
2246 );
2247 }
2248
2249 /**
2250 * @test
2251 */
2252 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
2253 $instance1 = $this->getMock('t3lib_Singleton');
2254 $singletonClassName = get_class($instance1);
2255 $instance2 = new $singletonClassName();
2256
2257 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
2258 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
2259
2260 $this->assertSame(
2261 $instance2,
2262 t3lib_div::makeInstance($singletonClassName)
2263 );
2264 }
2265
2266 /**
2267 * @test
2268 * @expectedException InvalidArgumentException
2269 */
2270 public function addInstanceForEmptyClassNameThrowsException() {
2271 $instance = $this->getMock('foo');
2272
2273 t3lib_div::addInstance('', $instance);
2274 }
2275
2276 /**
2277 * @test
2278 * @expectedException InvalidArgumentException
2279 */
2280 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
2281 $instance = $this->getMock('foo', array('bar'));
2282 $singletonClassName = get_class($this->getMock('foo'));
2283
2284 t3lib_div::addInstance($singletonClassName, $instance);
2285 }
2286
2287 /**
2288 * @test
2289 * @expectedException InvalidArgumentException
2290 */
2291 public function addInstanceWithSingletonInstanceThrowsException() {
2292 $instance = $this->getMock('t3lib_Singleton');
2293
2294 t3lib_div::addInstance(get_class($instance), $instance);
2295 }
2296
2297 /**
2298 * @test
2299 */
2300 public function addInstanceMakesMakeInstanceReturnThatInstance() {
2301 $instance = $this->getMock('foo');
2302 $className = get_class($instance);
2303
2304 t3lib_div::addInstance($className, $instance);
2305
2306 $this->assertSame(
2307 $instance,
2308 t3lib_div::makeInstance($className)
2309 );
2310 }
2311
2312 /**
2313 * @test
2314 */
2315 public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
2316 $instance = $this->getMock('foo');
2317 $className = get_class($instance);
2318
2319 t3lib_div::addInstance($className, $instance);
2320
2321 $this->assertNotSame(
2322 t3lib_div::makeInstance($className),
2323 t3lib_div::makeInstance($className)
2324 );
2325 }
2326
2327 /**
2328 * @test
2329 */
2330 public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
2331 $instance1 = $this->getMock('foo');
2332 $className = get_class($instance1);
2333 t3lib_div::addInstance($className, $instance1);
2334
2335 $instance2 = new $className();
2336 t3lib_div::addInstance($className, $instance2);
2337
2338 $this->assertSame(
2339 $instance1,
2340 t3lib_div::makeInstance($className),
2341 'The first returned instance does not match the first added instance.'
2342 );
2343 $this->assertSame(
2344 $instance2,
2345 t3lib_div::makeInstance($className),
2346 'The second returned instance does not match the second added instance.'
2347 );
2348 }
2349
2350 /**
2351 * @test
2352 */
2353 public function purgeInstancesDropsAddedInstance() {
2354 $instance = $this->getMock('foo');
2355 $className = get_class($instance);
2356
2357 t3lib_div::addInstance($className, $instance);
2358 t3lib_div::purgeInstances();
2359
2360 $this->assertNotSame(
2361 $instance,
2362 t3lib_div::makeInstance($className)
2363 );
2364 }
2365
2366 /**
2367 * Data provider for validPathStrDetectsInvalidCharacters.
2368 *
2369 * @return array
2370 */
2371 public function validPathStrInvalidCharactersDataProvider() {
2372 return array(
2373 'double slash in path' => array('path//path'),
2374 'backslash in path' => array('path\\path'),
2375 'directory up in path' => array('path/../path'),
2376 'directory up at the beginning' => array('../path'),
2377 'NUL character in path' => array("path\x00path"),
2378 'BS character in path' => array("path\x08path"),
2379 );
2380 }
2381
2382 /**
2383 * Tests whether invalid characters are detected.
2384 *
2385 * @param string $path
2386 * @dataProvider validPathStrInvalidCharactersDataProvider
2387 * @test
2388 */
2389 public function validPathStrDetectsInvalidCharacters($path) {
2390 $this->assertNull(t3lib_div::validPathStr($path));
2391 }
2392
2393 /**
2394 * Tests whether verifyFilenameAgainstDenyPattern detects the null character.
2395 *
2396 * @test
2397 */
2398 public function verifyFilenameAgainstDenyPatternDetectsNullCharacter() {
2399 $this->assertFalse(t3lib_div::verifyFilenameAgainstDenyPattern("image\x00.gif"));
2400 }
2401
2402
2403 /////////////////////////////////////////////////////////////////////////////////////
2404 // Tests concerning sysLog
2405 /////////////////////////////////////////////////////////////////////////////////////
2406
2407 /**
2408 * @test
2409 */
2410 public function syslogFixesPermissionsOnFileIfUsingFileLogging() {
2411 if (TYPO3_OS == 'WIN') {
2412 $this->markTestSkipped('syslogFixesPermissionsOnFileIfUsingFileLogging() test not available on Windows.');
2413 }
2414
2415 // Fake all required settings
2416 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel'] = 0;
2417 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit'] = TRUE;
2418 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']);
2419 $testLogFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.txt';
2420 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'] = 'file,' . $testLogFilename . ',0';
2421 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
2422
2423 // Call method, get actual permissions and clean up
2424 t3lib_div::syslog('testLog', 'test', 1);
2425 clearstatcache();
2426 $resultFilePermissions = substr(decoct(fileperms($testLogFilename)), 2);
2427 t3lib_div::unlink_tempfile($testLogFilename);
2428
2429 $this->assertEquals($resultFilePermissions, '0777');
2430 }
2431
2432 /**
2433 * @test
2434 */
2435 public function deprecationLogFixesPermissionsOnLogFile() {
2436 if (TYPO3_OS == 'WIN') {
2437 $this->markTestSkipped('deprecationLogFixesPermissionsOnLogFile() test not available on Windows.');
2438 }
2439
2440 // Fake all required settings and get an unique logfilename
2441 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = uniqid('test_');
2442 $deprecationLogFilename = t3lib_div::getDeprecationLogFileName();
2443 print_r($deprecationLogFilename);
2444 $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = TRUE;
2445 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
2446
2447 // Call method, get actual permissions and clean up
2448 t3lib_div::deprecationLog('foo');
2449 clearstatcache();
2450 $resultFilePermissions = substr(decoct(fileperms($deprecationLogFilename)), 2);
2451 @unlink($deprecationLogFilename);
2452
2453 $this->assertEquals($resultFilePermissions, '0777');
2454 }
2455 }
2456 ?>