PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/t3lib/t3lib_divTest.php

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