Enhance phpunit tests

This commit is contained in:
ldestailleur
2025-03-09 21:26:51 +01:00
parent af82f5f1eb
commit 202ffe732e
3 changed files with 276 additions and 33 deletions

View File

@@ -2082,7 +2082,14 @@ function dolPrintText($s)
*/ */
function dolPrintHTML($s, $allowiframe = 0) function dolPrintHTML($s, $allowiframe = 0)
{ {
return dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($s), 1, 1, 1, $allowiframe)), 1, 1, 'common', 0, 1); // If text is already HTML, we want to escape only dangerous chars else we want to escape all content.
//$isAlreadyHTML = dol_textishtml($s);
// dol_htmlentitiesbr encode all chars except "'" if string is not already HTML, but
// encode only special char like é but not &, <, >, ", ' if already HTML.
$stringWithEntitesForSpecialChar = dol_htmlentitiesbr($s);
return dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags($stringWithEntitesForSpecialChar, 1, 1, 1, $allowiframe)), 1, 1, 'common', 0, 1);
} }
/** /**
@@ -2143,7 +2150,7 @@ function dolPrintHTMLForTextArea($s, $allowiframe = 0)
*/ */
function dolPrintPassword($s) function dolPrintPassword($s)
{ {
return htmlspecialchars($s, ENT_COMPAT, 'UTF-8'); return htmlspecialchars($s, ENT_HTML5, 'UTF-8');
} }
@@ -2151,8 +2158,8 @@ function dolPrintPassword($s)
* Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input fields. * Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input fields.
* When we need to output strings on pages, we should use: * When we need to output strings on pages, we should use:
* - dolPrintLabel... * - dolPrintLabel...
* - dolPrintHTML... that is dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr(), 1, 1, 1)), 1, 1) for notes or descriptions into textarea, add 'common' if into a html content * - dolPrintHTML... that is dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr(...), 1, 1, 1, 0)), 1, 1, 'common', 0, 1) for notes or descriptions into textarea, add 'common' if into a html content
* - dolPrintPassword that is abelhtmlspecialchars( , ENT_COMPAT, 'UTF-8') for passwords. * - dolPrintPassword that is a simple htmlspecialchars(... , ENT_COMPAT, 'UTF-8') for passwords.
* *
* @param string $stringtoescape String to escape * @param string $stringtoescape String to escape
* @param int $keepb 1=Replace b tags with escaped value (except if in $noescapetags), 0=Remove them completely * @param int $keepb 1=Replace b tags with escaped value (except if in $noescapetags), 0=Remove them completely
@@ -2254,12 +2261,13 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
} while ($diff); } while ($diff);
} }
$tmp = str_ireplace('&amp', '__ANDNOSEMICOLON__', $tmp);
$tmp = str_ireplace('&quot', '__DOUBLEQUOTENOSEMICOLON__', $tmp); $tmp = str_ireplace('&quot', '__DOUBLEQUOTENOSEMICOLON__', $tmp);
$tmp = str_ireplace('&lt', '__LESSTHAN__', $tmp); $tmp = str_ireplace('&lt', '__LESSTHAN__', $tmp);
$tmp = str_ireplace('&gt', '__GREATERTHAN__', $tmp); $tmp = str_ireplace('&gt', '__GREATERTHAN__', $tmp);
} }
// Warning: htmlentities encode HTML tags like <abc> & into &amp; and more (but not &lt; &gt; &quotes; &apos; &#39; &amp; that remains untouched). // Warning: htmlentities encode all special chars that remains (except "'" with ENT_COMPAT).
$result = htmlentities($tmp, ENT_COMPAT, 'UTF-8'); $result = htmlentities($tmp, ENT_COMPAT, 'UTF-8');
//print $result; //print $result;
@@ -2276,6 +2284,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
$result = str_ireplace('__DOUBLEQUOTE__', '"', $result); $result = str_ireplace('__DOUBLEQUOTE__', '"', $result);
$result = str_ireplace('__ANDNOSEMICOLON__', '&amp', $result);
$result = str_ireplace('__DOUBLEQUOTENOSEMICOLON__', '&quot', $result); $result = str_ireplace('__DOUBLEQUOTENOSEMICOLON__', '&quot', $result);
$result = str_ireplace('__LESSTHAN__', '&lt', $result); $result = str_ireplace('__LESSTHAN__', '&lt', $result);
$result = str_ireplace('__GREATERTHAN__', '&gt', $result); $result = str_ireplace('__GREATERTHAN__', '&gt', $result);
@@ -8527,7 +8536,7 @@ function dol_nl2br($stringtoencode, $nl2brmode = 0, $forxml = false)
} }
/** /**
* Sanitize a HTML to remove js, dangerous content and external link. * Sanitize a HTML to remove js, dangerous content and external links.
* This function is used by dolPrintHTML... function for example. * This function is used by dolPrintHTML... function for example.
* *
* @param string $stringtoencode String to encode * @param string $stringtoencode String to encode
@@ -8588,6 +8597,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
// Tidy can't be used for restricthtmlallowunvalid and restricthtmlallowlinkscript // Tidy can't be used for restricthtmlallowunvalid and restricthtmlallowlinkscript
// TODO Try to implement a hack for restricthtmlallowlinkscript by renaming tag <link> and <script> ? // TODO Try to implement a hack for restricthtmlallowlinkscript by renaming tag <link> and <script> ?
try { try {
//var_dump($out);
// Try cleaning using tidy // Try cleaning using tidy
if (extension_loaded('tidy') && class_exists("tidy")) { if (extension_loaded('tidy') && class_exists("tidy")) {
//print "aaa".$out."\n"; //print "aaa".$out."\n";
@@ -8602,7 +8613,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
"indent-attributes" => false, "indent-attributes" => false,
"vertical-space" => false, "vertical-space" => false,
//'ident' => false, // Not always supported //'ident' => false, // Not always supported
"wrap" => 0 "wrap" => 0,
'preserve-entities' => true
// HTML5 tags // HTML5 tags
//'new-blocklevel-tags' => 'article aside audio bdi canvas details dialog figcaption figure footer header hgroup main menu menuitem nav section source summary template track video', //'new-blocklevel-tags' => 'article aside audio bdi canvas details dialog figcaption figure footer header hgroup main menu menuitem nav section source summary template track video',
//'new-blocklevel-tags' => 'footer header section menu menuitem' //'new-blocklevel-tags' => 'footer header section menu menuitem'
@@ -8616,6 +8628,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
//print "xxx".$out;exit; //print "xxx".$out;exit;
} }
//var_dump($out);
} catch (Exception $e) { } catch (Exception $e) {
// If error, invalid HTML string with no way to clean it // If error, invalid HTML string with no way to clean it
//print $e->getMessage(); //print $e->getMessage();
@@ -8629,8 +8643,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
// Clean some html entities that are useless so text is cleaner // Clean some html entities that are useless so text is cleaner
$out = preg_replace('/&(tab|newline);/i', ' ', $out); $out = preg_replace('/&(tab|newline);/i', ' ', $out);
// Ckeditor uses the numeric entity for apostrophe so we force it to text entity (all other special chars are // Ckeditor uses the numeric entity for apostrophe, so we force it to
// encoded using text entities) so we can then exclude all numeric entities. // the text entity (all other special chars are encoded using text entities) so we can then exclude all numeric entities.
$out = preg_replace('/&#39;/i', '&apos;', $out); $out = preg_replace('/&#39;/i', '&apos;', $out);
// We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step (preg_replace). // We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step (preg_replace).
@@ -8669,7 +8683,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
$out = dol_string_onlythesehtmlattributes($out); $out = dol_string_onlythesehtmlattributes($out);
} }
// Restore entity &apos; into &#39; (restricthtml is for html content so we can use html entity) // Restore entity &apos; into &#39; (restricthtml is for html content so we can use html entity) because it is
// compatible with HTML 4 used y CKEditor, and HTML 5 (when &apos; works only with HTML5).
$out = preg_replace('/&apos;/i', "&#39;", $out); $out = preg_replace('/&apos;/i', "&#39;", $out);
// Now remove js // Now remove js
@@ -8726,8 +8741,8 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
} }
/** /**
* This function is called to encode a string into a HTML string but differs from htmlentities because * This function is called to encode a string into a HTML string but differs from htmlentities because a detection is
* a detection is done before to see if text is already HTML or not. Also, all entities but &,<,>," are converted. * done before to see if text is already HTML or not. Also, all entities but &,<,>," (because protected by code) and ' (because not included by the ENT_COMPAT mode) are converted.
* This permits to encode special chars to entities with no double encoding for already encoded HTML strings. * This permits to encode special chars to entities with no double encoding for already encoded HTML strings.
* This function also remove last EOL or BR if $removelasteolbr=1 (default). * This function also remove last EOL or BR if $removelasteolbr=1 (default).
* For PDF usage, you can show text by 2 ways: * For PDF usage, you can show text by 2 ways:
@@ -8736,7 +8751,7 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
* Because writeHTMLCell convert also \n into <br>, if function is used to build PDF, nl2brmode must be 1. * Because writeHTMLCell convert also \n into <br>, if function is used to build PDF, nl2brmode must be 1.
* Note: When we output string on pages, we should use * Note: When we output string on pages, we should use
* - dolPrintHTML... that is dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr(), 1, 1, 1), 1, 1) for notes or descriptions, * - dolPrintHTML... that is dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr(), 1, 1, 1), 1, 1) for notes or descriptions,
* - dolPrintPassword that is abelhtmlspecialchars( , ENT_COMPAT, 'UTF-8') for passwords. * - dolPrintPassword that is a simple htmlspecialchars( , ENT_COMPAT, 'UTF-8') for passwords.
* *
* @param string $stringtoencode String to encode * @param string $stringtoencode String to encode
* @param int $nl2brmode 0=Adding br before \n, 1=Replacing \n by br (for use with FPDF writeHTMLCell function for example) * @param int $nl2brmode 0=Adding br before \n, 1=Replacing \n by br (for use with FPDF writeHTMLCell function for example)

View File

@@ -80,7 +80,7 @@ function getArrayOfEmoji()
* Return the real char for a numeric entities. * Return the real char for a numeric entities.
* WARNING: This function is required by testSqlAndScriptInject() and the GETPOST 'restricthtml'. Regex calling must be similar. * WARNING: This function is required by testSqlAndScriptInject() and the GETPOST 'restricthtml'. Regex calling must be similar.
* *
* @param array<int,string> $matches Array with a decimal numeric entity into key 0, value without the &# into the key 1 * @param array<int,string> $matches Array with a decimal numeric entity like '&#x2f;' into key 0, value without the &# like 'x2f;' into the key 1
* @return string New value * @return string New value
*/ */
function realCharForNumericEntities($matches) function realCharForNumericEntities($matches)
@@ -94,8 +94,8 @@ function realCharForNumericEntities($matches)
$newstringnumentity = (int) $newstringnumentity; $newstringnumentity = (int) $newstringnumentity;
} }
// The numeric values we don't want as entities because they encode ascii char, and why using html entities on ascii except for haking ? // The numeric values we don't want as entities because they encode ascii char, and why using html entities on ascii except for hacking ?
if (($newstringnumentity >= 65 && $newstringnumentity <= 90) || ($newstringnumentity >= 97 && $newstringnumentity <= 122)) { if (($newstringnumentity >= 47 && $newstringnumentity <= 59) || ($newstringnumentity >= 65 && $newstringnumentity <= 90) || ($newstringnumentity >= 97 && $newstringnumentity <= 122)) {
return chr((int) $newstringnumentity); return chr((int) $newstringnumentity);
} }

View File

@@ -25,7 +25,7 @@
* \remarks To run this script as CLI: phpunit filename.php * \remarks To run this script as CLI: phpunit filename.php
*/ */
global $conf,$user,$langs,$db; global $conf, $user, $langs, $db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver //define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php'; //require_once 'PHPUnit/Autoload.php';
@@ -67,6 +67,7 @@ if (empty($user->id)) {
$conf->global->MAIN_DISABLE_ALL_MAILS = 1; $conf->global->MAIN_DISABLE_ALL_MAILS = 1;
/** /**
* Class for PHPUnit tests * Class for PHPUnit tests
* *
@@ -769,6 +770,33 @@ class SecurityTest extends CommonClassTest
} }
/**
* testRealCharforNumericEntities()
*
* @return int
*/
public function testRealCharforNumericEntities()
{
global $conf;
// Test that testRealCharforNumericEntities return an ascii char when code is inside Ascii range
$arraytmp = array(0 => '&#97;', 1 => '97;');
$result = realCharForNumericEntities($arraytmp);
$this->assertEquals('a', $result);
// Test that testRealCharforNumericEntities return an emoji utf8 char when code is inside Emoji range
$arraytmp = array(0 => '&#9989;', 1 => '9989;'); // Encoded as decimal
$result = realCharForNumericEntities($arraytmp);
$this->assertEquals('✅', $result);
$arraytmp = array(0 => '&#x2705;', 1 => 'x2705;'); // Encoded as hexadecimal
$result = realCharForNumericEntities($arraytmp);
$this->assertEquals('✅', $result);
return 0;
}
/** /**
* testDolPrintHTMLAndDolPrintHtmlForAttribute. * testDolPrintHTMLAndDolPrintHtmlForAttribute.
* This method include calls to dol_htmlwithnojs() * This method include calls to dol_htmlwithnojs()
@@ -786,6 +814,7 @@ class SecurityTest extends CommonClassTest
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1; $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1;
} else { } else {
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0; $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0;
print "WARNING !!! php-tidy is not available !!!";
} }
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // disabled, does not work on HTML5 and some libxml versions $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // disabled, does not work on HTML5 and some libxml versions
@@ -880,7 +909,6 @@ class SecurityTest extends CommonClassTest
print __METHOD__." result=".$result."\n"; print __METHOD__." result=".$result."\n";
$this->assertEquals($stringfixed, $result, 'Error'); $this->assertEquals($stringfixed, $result, 'Error');
// For a string that is already HTML (contains HTML tags) but badly formatted // For a string that is already HTML (contains HTML tags) but badly formatted
$stringtotest = "testB\n<h1>hhh</h1>\n<td>td alone</td><h1>iii</h1>"; $stringtotest = "testB\n<h1>hhh</h1>\n<td>td alone</td><h1>iii</h1>";
if (getDolGlobalString("MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY")) { if (getDolGlobalString("MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY")) {
@@ -892,7 +920,6 @@ class SecurityTest extends CommonClassTest
print __METHOD__." result=".$result."\n"; print __METHOD__." result=".$result."\n";
$this->assertEquals($stringfixed, $result, 'Error'); $this->assertEquals($stringfixed, $result, 'Error');
// For a string with no HTML tags // For a string with no HTML tags
$stringtotest = "testwithnewline\nsecond line"; $stringtotest = "testwithnewline\nsecond line";
$stringfixed = "testwithnewline<br>\nsecond line"; $stringfixed = "testwithnewline<br>\nsecond line";
@@ -900,6 +927,30 @@ class SecurityTest extends CommonClassTest
print __METHOD__." result=".$result."\n"; print __METHOD__." result=".$result."\n";
$this->assertEquals($stringfixed, $result, 'Error'); $this->assertEquals($stringfixed, $result, 'Error');
// For a string with a simple & inside
// With no clean option
/*
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1;
$stringtotest = "a & b";
$stringfixed = "a &amp; b";
$result = dolPrintHTML($stringtotest);
print __METHOD__." result=".$result."\n";
$this->assertEquals($stringfixed, $result, 'Error');
// For a string with a simple & inside
// With all clean option
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1;
$stringtotest = "a & b";
$stringfixed = "a &amp; b";
$result = dolPrintHTML($stringtotest);
print __METHOD__." result=".$result."\n";
$this->assertEquals($stringfixed, $result, 'Error');
*/
// For a string with ' and &#39; // For a string with ' and &#39;
// With no clean option // With no clean option
@@ -931,7 +982,8 @@ class SecurityTest extends CommonClassTest
// With cleaning options of HTML TIDY // With cleaning options of HTML TIDY
if (extension_loaded('tidy') && class_exists("tidy")) { if (extension_loaded('tidy') && class_exists("tidy")) {
$stringtotest = "Message<br>with ' and &egrave; and &#39; !"; $stringtotest = "Message<br>with ' and &egrave; and &#39; !";
$stringexpected = "Message<br>\nwith ' and &egrave; and ' !"; // The &#39; is modified into ' because html tidy fix it. //$stringexpected = "Message<br>\nwith ' and &egrave; and ' !"; // The &#39; is modified into ' because html tidy fix it.
$stringexpected = "Message<br>\nwith ' and &egrave; and &#39; !";
/* /*
var_dump($stringtotest); var_dump($stringtotest);
var_dump(dol_htmlentitiesbr($stringtotest)); var_dump(dol_htmlentitiesbr($stringtotest));
@@ -949,27 +1001,198 @@ class SecurityTest extends CommonClassTest
/** /**
* testRealCharforNumericEntities() * testDolPrintHTML
* This method include calls to dol_htmlwithnojs()
* *
* @return int * @return int
*
* @depends testDolPrintHTMLAndDolPrintHtmlForAttribute
*/ */
public function testRealCharforNumericEntities() public function testDolPrintHTML()
{ {
global $conf; global $conf;
// Test that testRealCharforNumericEntities return an ascii char when code is inside Ascii range // Set options for cleaning data
$arraytmp = array(0 => '&#97;', 1 => '97;'); $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0; // disabled, does not work on HTML5 and some libxml versions
$result = realCharForNumericEntities($arraytmp); // Enable option MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY if possible
$this->assertEquals('a', $result); if (extension_loaded('tidy') && class_exists("tidy")) {
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1;
} else {
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0;
print "WARNING !!! php-tidy is not available !!!";
}
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // disabled, does not work on HTML5 and some libxml versions
// Test that testRealCharforNumericEntities return an emoji utf8 char when code is inside Emoji range
$arraytmp = array(0 => '&#9989;', 1 => '9989;'); // Encoded as decimal
$result = realCharForNumericEntities($arraytmp);
$this->assertEquals('✅', $result);
$arraytmp = array(0 => '&#x2705;', 1 => 'x2705;'); // Encoded as hexadecimal // With no clean option
$result = realCharForNumericEntities($arraytmp); $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$this->assertEquals('✅', $result); $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp; &eacute; &eacute; &lt; &lt; &quot; &quot; \' &#39; <a href="aaa?aaa=1&amp;bbb=2&amp;ccc=3">a</a> z';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp; &eacute; &lt; &quot; \'';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
if (extension_loaded('tidy') && class_exists("tidy")) {
// With clean TIDY only
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp; &eacute; &eacute; &lt; &lt; &quot; &quot; \' &#39; <a href="aaa?aaa=1&amp;bbb=2&amp;ccc=3">a</a> z';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp; &eacute; &lt; &quot; \'';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// With clean TIDY and remove Bad attributes option
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp; &eacute; &eacute; &lt; &lt; &quot; &quot; \' \' <a href="aaa?aaa=1&amp;bbb=2&amp;ccc=3">a</a> z';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp; &eacute; &lt; &quot; \'';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
}
// With remove Bad attributes option only
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp; &eacute; &eacute; &lt; &lt; &quot; &quot; \' \' <a href="aaa?aaa=1&amp;bbb=2&amp;ccc=3">a</a> z';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp; &eacute; &lt; &quot; \'';
$result = dolPrintHTML($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
return 0;
}
/**
* testDolPrintHTMLForAttribute
* This method include calls to dol_htmlwithnojs()
*
* @return int
* @depends testDolPrintHTML
*/
public function testDolPrintHTMLForAttribute()
{
global $conf;
// Set options for cleaning data
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0; // disabled, does not work on HTML5 and some libxml versions
// Enable option MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY if possible
if (extension_loaded('tidy') && class_exists("tidy")) {
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1;
} else {
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0;
print "WARNING !!! php-tidy is not available !!!";
}
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // disabled, does not work on HTML5 and some libxml versions
// With no clean option
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp;amp; &eacute; &eacute; &lt; &amp;lt; &quot; &amp;quot; \' &amp;apos; a z';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp;amp; &eacute; &amp;lt; &amp;quot; \'';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// With clean TIDY only
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp;amp; &eacute; &eacute; &lt; &amp;lt; &quot; &amp;quot; \' &amp;apos; a z';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp;amp; &eacute; &amp;lt; &amp;quot; \'';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// With clean TIDY and remove Bad attributes option
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp;amp; &eacute; &eacute; &lt; &amp;lt; &quot; &amp;quot; \' &amp;apos; a z';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp;amp; &eacute; &amp;lt; &amp;quot; \'';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// With remove Bad attributes option only
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0;
$conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0; //
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1; // 1 = Replaces & alone into &amp; and replaces &#39 into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & &amp; é &eacute; < &lt; " &quot; \' &apos; <a href="aaa?aaa=1&bbb=2&amp;ccc=3">a</a> <zzz>z</zzz>'; // Detected as already HTML
$expectedresult = 'List of char+their entities: &amp; &amp;amp; &eacute; &eacute; &lt; &amp;lt; &quot; &amp;quot; \' &amp;apos; a z';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
// For a string that is not an already HTML content
$s = 'List: & é < " \''; // Detected as non already HTML
$expectedresult = 'List: &amp;amp; &eacute; &amp;lt; &amp;quot; \'';
$result = dolPrintHTMLForAttribute($s);
$this->assertEquals($expectedresult, $result, 'Error on test dolPrintHTML');
return 0; return 0;
} }
@@ -979,11 +1202,16 @@ class SecurityTest extends CommonClassTest
* testDolHtmlWithNoJs() * testDolHtmlWithNoJs()
* *
* @return int * @return int
*
* @depends testDolPrintHTMLAndDolPrintHtmlForAttribute
*/ */
public function testDolHtmlWithNoJs() public function testDolHtmlWithNoJs()
{ {
global $conf; global $conf;
$conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0;
// If we set this to 1, it will also convert emoticon in htmlentities, so tests must be modified.
$sav1 = getDolGlobalString('MAIN_RESTRICTHTML_ONLY_VALID_HTML'); $sav1 = getDolGlobalString('MAIN_RESTRICTHTML_ONLY_VALID_HTML');
$sav2 = getDolGlobalString('MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY'); $sav2 = getDolGlobalString('MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY');