Fixes #42. Updated Sanitize::clean() with 'remove_html' option. Updated Sanitize::html() to accept new options. Updated test cases.

Signed-off-by: Mark Story <mark@mark-story.com>
This commit is contained in:
tPl0ch 2010-01-07 21:15:10 +01:00 committed by Mark Story
parent 5ae0164574
commit 61079f6317
2 changed files with 49 additions and 16 deletions

View file

@ -79,22 +79,40 @@ class Sanitize {
/** /**
* Returns given string safe for display as HTML. Renders entities. * Returns given string safe for display as HTML. Renders entities.
*
* strip_tags() is not validating HTML, so it might strip whole passages
* with broken HTML.
* *
* @param string $string String from where to strip tags * @param string $string String from where to strip tags
* @param boolean $remove If true, the string is stripped of all HTML tags * @param array $options
*
* possible options:
*
* - remove (boolean) if true strips all HTML tags before encoding
* - charset (string) the charset used to encode the string
* - quotes (int) see http://php.net/manual/en/function.htmlentities.php
*
* @return string Sanitized string * @return string Sanitized string
* @access public * @access public
* @static * @static
*/ */
function html($string, $remove = false) { function html($string, $options = array()) {
if ($remove) { $default = array(
'remove' => false,
'charset' => 'UTF-8',
'quotes' => ENT_QUOTES
);
$options = array_merge($default, $options);
if ($options['remove']) {
$string = strip_tags($string); $string = strip_tags($string);
} else {
$patterns = array('&', '%', '<', '>', '"', "'", '(', ')', '+', '-');
$replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
$string = str_replace($patterns, $replacements, $string);
} }
return $string; $encoding = Configure::read('App.encoding');
if (empty($encoding)) {
$encoding = $options['charset'];
}
return htmlentities($string, $options['quotes'], $encoding);
} }
/** /**
@ -198,6 +216,7 @@ class Sanitize {
$options = array_merge(array( $options = array_merge(array(
'connection' => 'default', 'connection' => 'default',
'odd_spaces' => true, 'odd_spaces' => true,
'remove_html' => false,
'encode' => true, 'encode' => true,
'dollar' => true, 'dollar' => true,
'carriage' => true, 'carriage' => true,
@ -216,7 +235,7 @@ class Sanitize {
$data = str_replace(chr(0xCA), '', str_replace(' ', ' ', $data)); $data = str_replace(chr(0xCA), '', str_replace(' ', ' ', $data));
} }
if ($options['encode']) { if ($options['encode']) {
$data = Sanitize::html($data); $data = Sanitize::html($data, array('remove' => $options['remove_html']));
} }
if ($options['dollar']) { if ($options['dollar']) {
$data = str_replace("\\\$", "$", $data); $data = str_replace("\\\$", "$", $data);

View file

@ -145,7 +145,7 @@ class SanitizeTest extends CakeTestCase {
*/ */
function testClean() { function testClean() {
$string = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line'; $string = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line';
$expected = 'test &amp; &quot;quote&quot; &#39;other&#39; ;.$ symbol.another line'; $expected = 'test &amp; &quot;quote&quot; &#039;other&#039; ;.$ symbol.another line';
$result = Sanitize::clean($string, array('connection' => 'test_suite')); $result = Sanitize::clean($string, array('connection' => 'test_suite'));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
@ -170,7 +170,7 @@ class SanitizeTest extends CakeTestCase {
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$array = array(array('test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line')); $array = array(array('test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line'));
$expected = array(array('test &amp; &quot;quote&quot; &#39;other&#39; ;.$ symbol.another line')); $expected = array(array('test &amp; &quot;quote&quot; &#039;other&#039; ;.$ symbol.another line'));
$result = Sanitize::clean($array, array('connection' => 'test_suite')); $result = Sanitize::clean($array, array('connection' => 'test_suite'));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
@ -179,8 +179,8 @@ class SanitizeTest extends CakeTestCase {
$result = Sanitize::clean($array, array('encode' => false, 'escape' => false, 'connection' => 'test_suite')); $result = Sanitize::clean($array, array('encode' => false, 'escape' => false, 'connection' => 'test_suite'));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$array = array(array('test odd '.chr(0xCA).' spaces'.chr(0xCA))); $array = array(array('test odd Ä spacesé'));
$expected = array(array('test odd '.chr(0xCA).' spaces'.chr(0xCA))); $expected = array(array('test odd &Auml; spaces&eacute;'));
$result = Sanitize::clean($array, array('odd_spaces' => false, 'escape' => false, 'connection' => 'test_suite')); $result = Sanitize::clean($array, array('odd_spaces' => false, 'escape' => false, 'connection' => 'test_suite'));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
@ -203,12 +203,26 @@ class SanitizeTest extends CakeTestCase {
*/ */
function testHtml() { function testHtml() {
$string = '<p>This is a <em>test string</em> & so is this</p>'; $string = '<p>This is a <em>test string</em> & so is this</p>';
$expected = 'This is a test string & so is this'; $expected = 'This is a test string &amp; so is this';
$result = Sanitize::html($string, true); $result = Sanitize::html($string, array('remove' => true));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$string = 'The "lazy" dog \'jumped\' & flew over the moon. If (1+1) = 2 <em>is</em> true, (2-1) = 1 is also true'; $string = 'The "lazy" dog \'jumped\' & flew over the moon. If (1+1) = 2 <em>is</em> true, (2-1) = 1 is also true';
$expected = 'The &quot;lazy&quot; dog &#39;jumped&#39; &amp; flew over the moon. If &#40;1&#43;1&#41; = 2 &lt;em&gt;is&lt;/em&gt; true, &#40;2&#45;1&#41; = 1 is also true'; $expected = 'The &quot;lazy&quot; dog &#039;jumped&#039; &amp; flew over the moon. If (1+1) = 2 &lt;em&gt;is&lt;/em&gt; true, (2-1) = 1 is also true';
$result = Sanitize::html($string);
$this->assertEqual($result, $expected);
$string = 'The "lazy" dog \'jumped\'';
$expected = 'The &quot;lazy&quot; dog \'jumped\'';
$result = Sanitize::html($string, array('quotes' => ENT_COMPAT));
$this->assertEqual($result, $expected);
$string = 'The "lazy" dog \'jumped\'';
$result = Sanitize::html($string, array('quotes' => ENT_NOQUOTES));
$this->assertEqual($result, $string);
$string = 'The "lazy" dog \'jumped\' & flew over the moon. If (1+1) = 2 <em>is</em> true, (2-1) = 1 is also true';
$expected = 'The &quot;lazy&quot; dog &#039;jumped&#039; &amp; flew over the moon. If (1+1) = 2 &lt;em&gt;is&lt;/em&gt; true, (2-1) = 1 is also true';
$result = Sanitize::html($string); $result = Sanitize::html($string);
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }