2010-11-20 15:25:08 +00:00
< ? php
/* Copyright ( C ) 2010 Laurent Destailleur < eldy @ users . sourceforge . net >
2023-05-07 12:31:35 +00:00
* Copyright ( C ) 2023 Alexandre Janniaux < alexandre . janniaux @ gmail . com >
2024-11-13 23:16:43 +00:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2010-11-20 15:25:08 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 14:36:08 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2010-11-20 15:25:08 +00:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2010-11-20 15:25:08 +00:00
*/
/**
* \file test / phpunit / SecurityTest . php
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI : phpunit filename . php
*/
2025-03-09 20:26:51 +00:00
global $conf , $user , $langs , $db ;
2010-11-20 15:25:08 +00:00
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
2014-05-01 17:57:53 +00:00
//require_once 'PHPUnit/Autoload.php';
2010-11-20 15:25:08 +00:00
2021-01-14 14:09:08 +00:00
if ( ! defined ( 'NOREQUIRESOC' )) {
define ( 'NOREQUIRESOC' , '1' );
}
if ( ! defined ( 'NOCSRFCHECK' )) {
define ( 'NOCSRFCHECK' , '1' );
}
if ( ! defined ( 'NOTOKENRENEWAL' )) {
define ( 'NOTOKENRENEWAL' , '1' );
}
if ( ! defined ( 'NOREQUIREMENU' )) {
define ( 'NOREQUIREMENU' , '1' ); // If there is no menu to show
}
if ( ! defined ( 'NOREQUIREHTML' )) {
define ( 'NOREQUIREHTML' , '1' ); // If we don't need to load the html.form.class.php
}
if ( ! defined ( 'NOREQUIREAJAX' )) {
define ( 'NOREQUIREAJAX' , '1' );
}
if ( ! defined ( " NOLOGIN " )) {
define ( " NOLOGIN " , '1' ); // If this page is public (can be called outside logged session)
}
if ( ! defined ( " NOSESSION " )) {
define ( " NOSESSION " , '1' );
}
2010-11-20 15:25:08 +00:00
2024-03-11 11:51:27 +00:00
require_once dirname ( __FILE__ ) . '/../../htdocs/main.inc.php' ; // We force include of main.inc.php instead of master.inc.php even if we are in CLI mode because it contains a lot of security components we want to test.
2020-11-27 15:52:52 +00:00
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security.lib.php' ;
2026-07-24 14:21:18 +00:00
require_once dirname ( __FILE__ ) . '/../../htdocs/blockedlog/lib/securitycore.lib.php' ;
2020-11-27 15:52:52 +00:00
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security2.lib.php' ;
2024-03-11 11:53:03 +00:00
require_once dirname ( __FILE__ ) . '/CommonClassTest.class.php' ;
2020-11-27 15:52:52 +00:00
2021-01-14 14:09:08 +00:00
if ( empty ( $user -> id )) {
print " Load permissions for admin user nb 1 \n " ;
$user -> fetch ( 1 );
2024-11-13 23:16:43 +00:00
$user -> loadRights ();
2012-02-12 17:30:50 +00:00
}
2024-02-19 14:28:21 +00:00
$conf -> global -> MAIN_DISABLE_ALL_MAILS = 1 ;
2012-02-12 17:30:50 +00:00
2010-11-20 15:25:08 +00:00
2025-03-09 22:37:36 +00:00
print " PHP Version: " . phpversion () . " \n " ;
print " Memory limit: " . ini_get ( 'memory_limit' ) . " \n " ;
2025-03-09 20:26:51 +00:00
2010-11-20 15:25:08 +00:00
/**
2011-09-23 12:21:00 +00:00
* Class for PHPUnit tests
2010-11-20 15:25:08 +00:00
*
2025-12-18 14:07:54 +00:00
* #LNE1-QU2507-0005
*
2010-11-20 15:25:08 +00:00
* @ backupGlobals disabled
* @ backupStaticAttributes enabled
* @ remarks backupGlobals must be disabled to have db , conf , user and lang not erased .
*/
2024-02-16 22:26:32 +00:00
class SecurityTest extends CommonClassTest
2010-11-20 15:25:08 +00:00
{
2021-01-14 14:09:08 +00:00
/**
* testSetLang
*
* @ return string
*/
public function testSetLang ()
{
global $conf ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
2021-01-14 14:09:08 +00:00
$tmplangs = new Translate ( '' , $conf );
$_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ] = " ' malicious text with quote " ;
$tmplangs -> setDefaultLang ( 'auto' );
print __METHOD__ . ' $tmplangs->defaultlang=' . $tmplangs -> defaultlang . " \n " ;
$this -> assertEquals ( $tmplangs -> defaultlang , 'malicioustextwithquote_MALICIOUSTEXTWITHQUOTE' );
}
2023-11-29 19:19:21 +00:00
2026-07-24 14:21:18 +00:00
/**
* testDolEncryptDolDecrypt
*
* @ return void
*/
public function testDolEncryptDolDecrypt ()
{
$s = 'simple string with no special char a..z 1..0' ;
$es = dolEncrypt ( $s );
$news = dolDecrypt ( $es );
print __METHOD__ . ' testDolEncryptDolDecrypt ' . $s . ' ==> ' . $es . ' ==> ' . $news . " \n " ;
$this -> assertEquals ( $news , $s );
$s = 'string with à é ç' ;
$es = dolEncrypt ( $s );
$news = dolDecrypt ( $es );
print __METHOD__ . ' testDolEncryptDolDecrypt ' . $s . ' ==> ' . $es . ' ==> ' . $news . " \n " ;
$this -> assertEquals ( $news , $s );
}
2021-01-14 14:09:08 +00:00
/**
* testSqlAndScriptInjectWithPHPUnit
*
* @ return void
*/
public function testSqlAndScriptInjectWithPHPUnit ()
{
// Run tests
// More on https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
// Should be OK
2024-02-19 14:28:21 +00:00
$expectedresult = 0 ;
2021-01-14 14:09:08 +00:00
2021-03-13 11:33:26 +00:00
/*
$test = '' ;
$result = testSqlAndScriptInject ( $test , 0 );
$this -> assertGreaterThanOrEqual ( 0 , $result , 'Error on testSqlAndScriptInject kkk' );
*/
2024-02-19 14:28:21 +00:00
$_SERVER [ " PHP_SELF " ] = '/DIR WITH SPACE/htdocs/admin/index.php' ;
$result = testSqlAndScriptInject ( $_SERVER [ " PHP_SELF " ], 2 );
2021-03-14 14:06:40 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for PHP_SELF that should be ok' );
2021-01-25 21:46:09 +00:00
$test = 'This is a < inside string with < and > also and tag like <a> before the >' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-25 21:46:09 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject expected 0b' );
2021-01-14 14:09:08 +00:00
2021-06-25 08:47:31 +00:00
$test = 'This is the union of all for the selection of the best' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-06-25 08:47:31 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject expected 0c' );
2021-05-17 21:47:16 +00:00
2024-02-19 14:28:21 +00:00
$test = '/user/perms.php?id=1&action=addrights&entity=1&rights=123&confirm=yes&token=123456789&updatedmodulename=lmscoursetracking' ;
$result = testSqlAndScriptInject ( $test , 1 );
2023-06-19 01:17:24 +00:00
print " test= " . $test . " result= " . $result . " \n " ;
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject with a valid url' );
2021-05-17 21:47:16 +00:00
// Should detect attack
2024-02-19 14:28:21 +00:00
$expectedresult = 1 ;
2021-01-14 14:09:08 +00:00
2024-02-19 14:28:21 +00:00
$_SERVER [ " PHP_SELF " ] = '/DIR WITH SPACE/htdocs/admin/index.php/<svg>' ;
$result = testSqlAndScriptInject ( $_SERVER [ " PHP_SELF " ], 2 );
2021-03-14 14:06:40 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject for PHP_SELF that should detect XSS' );
2026-05-17 13:25:53 +00:00
$_SERVER [ " PHP_SELF " ] = '/dolibarr/htdocs/admin/index.php/aaa%bbb' ;
$result = testSqlAndScriptInject ( $_SERVER [ " PHP_SELF " ], 2 );
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject for PHP_SELF that should detect % inside URL' );
2021-06-25 08:47:31 +00:00
$test = 'select @@version' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-06-25 08:47:31 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for SQL1a. Should find an attack on POST param and did not.' );
$test = 'select @@version' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 1 );
2021-06-25 08:47:31 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for SQL1b. Should find an attack on GET param and did not.' );
2022-06-29 14:40:19 +00:00
$test = '... update ... set ... =' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 1 );
2022-06-29 14:40:19 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for SQL2a. Should find an attack on GET param and did not.' );
2022-12-05 14:05:40 +00:00
$test = " delete \n from " ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 1 );
2022-12-05 14:05:40 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for SQL2b. Should find an attack on GET param and did not.' );
2022-06-29 14:40:19 +00:00
$test = 'action=update& ... set ... =' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 1 );
2022-06-29 14:40:19 +00:00
$this -> assertEquals ( 0 , $result , 'Error on testSqlAndScriptInject for SQL2b. Should not find an attack on GET param and did.' );
2021-06-25 08:47:31 +00:00
$test = '... union ... selection ' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 1 );
2022-06-29 14:40:19 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for SQL2c. Should find an attack on GET param and did not.' );
2021-06-25 08:47:31 +00:00
2021-05-17 21:47:16 +00:00
$test = 'javascript:' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-05-17 21:47:16 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for javascript1. Should find an attack and did not.' );
$test = 'javascript:' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-05-17 21:47:16 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for javascript2. Should find an attack and did not.' );
2021-03-14 14:06:40 +00:00
$test = 'javascript&colon;alert(1)' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-05-17 21:47:16 +00:00
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject for javascript2' );
2021-01-14 14:09:08 +00:00
2024-02-19 14:28:21 +00:00
$test = " <img src='1.jpg' onerror =javascript:alert('XSS')> " ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-05-17 21:47:16 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa1' );
2021-01-14 14:09:08 +00:00
2024-02-19 14:28:21 +00:00
$test = " <img src='1.jpg' onerror =javascript:alert('XSS')> " ;
$result = testSqlAndScriptInject ( $test , 2 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa2' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC=# onmouseover="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa3' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC onmouseover="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa4' );
2024-02-19 14:28:21 +00:00
$test = '<IMG onmouseover="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa5' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC=/ onerror="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa6' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC="  javascript:alert(1);">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject aaa7' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC=javascript:alert('XSS')>' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject bbb' );
2025-02-13 19:29:25 +00:00
$test = '<marquee onbeforeintput="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject onbeforeintput' );
$test = '<marquee onbounce="alert(1)">' ;
$result = testSqlAndScriptInject ( $test , 0 );
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject onbounce' );
2024-02-19 14:28:21 +00:00
$test = '<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject ccc' );
2024-02-19 14:28:21 +00:00
$test = '<IMG SRC="javascript:alert(\'XSS\');">' ;
$result = testSqlAndScriptInject ( $test , 1 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject ddd' );
2024-02-19 14:28:21 +00:00
$test = '<IMG """><SCRIPT>alert("XSS")</SCRIPT>">' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject eee' );
2024-02-19 14:28:21 +00:00
$test = ' <!-- Google analytics -->
2020-11-27 15:52:52 +00:00
< script >
( function ( i , s , o , g , r , a , m ){ i [ \ ' GoogleAnalyticsObject\ ' ] = r ; i [ r ] = i [ r ] || function (){
( i [ r ] . q = i [ r ] . q || []) . push ( arguments )}, i [ r ] . l = 1 * new Date (); a = s . createElement ( o ),
m = s . getElementsByTagName ( o )[ 0 ]; a . async = 1 ; a . src = g ; m . parentNode . insertBefore ( a , m )
})( window , document , \ ' script\ ' , \ ' https :// www . google - analytics . com / analytics . js\ ' , \ ' ga\ ' );
ga ( \ ' create\ ' , \ ' UA - 99999999 - 9 \ ' , \ ' auto\ ' );
ga ( \ ' send\ ' , \ ' pageview\ ' );
</ script > ' ;
2024-02-19 14:28:21 +00:00
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject eee' );
2024-02-19 14:28:21 +00:00
$test = " <IMG SRC= \" jav \t ascript:alert('XSS'); \" > " ; // Is locked by some browser like chrome because the default directive no-referrer-when-downgrade is sent when requesting the SRC and then refused because of browser protection on img src load without referrer.
$test = " <IMG SRC= \" jav
ascript:alert('XSS'); \" > " ; // Same
2021-01-14 14:09:08 +00:00
2024-02-19 14:28:21 +00:00
$test = '<SCRIPT/XSS SRC="http://xss.rocks/xss.js"></SCRIPT>' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject fff1' );
2024-02-19 14:28:21 +00:00
$test = '<SCRIPT/SRC="http://xss.rocks/xss.js"></SCRIPT>' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject fff2' );
// This case seems to be filtered by browsers now.
2024-02-19 14:28:21 +00:00
$test = '<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert(1)>' ;
2021-01-14 14:09:08 +00:00
//$result=testSqlAndScriptInject($test, 0);
//$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ggg');
2024-02-19 14:28:21 +00:00
$test = '<iframe src=http://xss.rocks/scriptlet.html <' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject hhh' );
2024-02-19 14:28:21 +00:00
$test = 'Set.constructor`alert\x281\x29```' ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject iii' );
2024-02-19 14:28:21 +00:00
$test = " on<!-- ab \n c -->error=alert(1) " ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-14 14:09:08 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject jjj' );
2021-01-25 21:46:09 +00:00
2024-02-19 14:28:21 +00:00
$test = " <img src=x one<a>rror=alert(document.location) " ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-01-25 21:46:09 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject kkk' );
2021-05-21 10:17:56 +00:00
2024-02-19 14:28:21 +00:00
$test = " <a onpointerdown=alert(document.domain)>XSS</a> " ;
$result = testSqlAndScriptInject ( $test , 0 );
2021-05-21 10:17:56 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject lll' );
2021-07-05 14:08:47 +00:00
2024-02-19 14:28:21 +00:00
$test = '<a onscrollend=alert(1) style="display:block;overflow:auto;border:1px+dashed;width:500px;height:100px;"><br><br><br><br><br><span+id=x>test</span></a>' ; // Add the char %F6 into the variable
$result = testSqlAndScriptInject ( $test , 0 );
2023-08-13 13:45:45 +00:00
//print "test=".$test." result=".$result."\n";
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject mmm' );
2024-02-19 14:28:21 +00:00
$test = " Text with ' encoded with the numeric html entity converted into text entity ' (like when submitted by CKEditor) " ;
$result = testSqlAndScriptInject ( $test , 0 ); // result must be 0
2022-12-05 14:05:40 +00:00
$this -> assertEquals ( 0 , $result , 'Error on testSqlAndScriptInject mmm, result should be 0 and is not' );
2024-02-19 14:28:21 +00:00
$test = '<a href="j	a	v	asc
ri	pt:(a	l	e	r	t	(document.cookie))">XSS</a>' ;
$result = testSqlAndScriptInject ( $test , 0 );
2022-12-05 14:05:40 +00:00
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject nnn, result should be >= 1 and is not' );
2022-04-02 12:32:53 +00:00
2024-02-19 14:28:21 +00:00
$test = " /dolibarr/htdocs/index.php/ " . chr ( '246' ) . " abc " ; // Add the char %F6 into the variable
$result = testSqlAndScriptInject ( $test , 2 );
2022-04-02 12:32:53 +00:00
//print "test=".$test." result=".$result."\n";
$this -> assertGreaterThanOrEqual ( $expectedresult , $result , 'Error on testSqlAndScriptInject with a non valid UTF8 char' );
2024-07-27 16:07:37 +00:00
$test = '<img onerror<>=alert(document.domain)' ;
$result = testSqlAndScriptInject ( $test , 0 );
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject with an obfuscated string that bypass the WAF' );
$test = '<img onerror<abc>=alert(document.domain)' ;
$result = testSqlAndScriptInject ( $test , 0 );
$this -> assertEquals ( $expectedresult , $result , 'Error on testSqlAndScriptInject with an obfuscated string that bypass the WAF' );
2025-04-06 16:56:59 +00:00
// Can allow the " in GET parameter value
define ( " SECURITY_WAF_ALLOW_QUOTES_IN_GET " , 1 );
$test = 'aa"bb' ;
$result = testSqlAndScriptInject ( $test , 1 ); // Should return 0 = allowed
$this -> assertEquals ( 0 , $result , 'Error on testSqlAndScriptInject with SECURITY_WAF_ALLOW_QUOTES_IN_GET, should return 0, result=' . $result );
2021-01-14 14:09:08 +00:00
}
/**
* testEncodeDecode
*
2023-11-29 19:19:21 +00:00
* @ return int
2021-01-14 14:09:08 +00:00
*/
public function testEncodeDecode ()
{
2024-02-19 14:28:21 +00:00
$stringtotest = " This is a string to test encode/decode. This is a string to test encode/decode. This is a string to test encode/decode. " ;
2021-01-14 14:09:08 +00:00
2024-02-19 14:28:21 +00:00
$encodedstring = dol_encode ( $stringtotest );
$decodedstring = dol_decode ( $encodedstring );
2021-01-14 14:09:08 +00:00
print __METHOD__ . " encodedstring= " . $encodedstring . " " . base64_encode ( $stringtotest ) . " \n " ;
$this -> assertEquals ( $stringtotest , $decodedstring , 'Use dol_encode/decode with no parameter' );
2024-02-19 14:28:21 +00:00
$encodedstring = dol_encode ( $stringtotest , 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' );
$decodedstring = dol_decode ( $encodedstring , 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' );
2021-01-14 14:09:08 +00:00
print __METHOD__ . " encodedstring= " . $encodedstring . " " . base64_encode ( $stringtotest ) . " \n " ;
$this -> assertEquals ( $stringtotest , $decodedstring , 'Use dol_encode/decode with a key parameter' );
return 0 ;
}
/**
* testDolStringOnlyTheseHtmlTags
*
2023-11-29 19:19:21 +00:00
* @ return int
2021-01-14 14:09:08 +00:00
*/
public function testDolHTMLEntityDecode ()
{
$stringtotest = 'a : b " c ' d ' e é' ;
$decodedstring = dol_html_entity_decode ( $stringtotest , ENT_QUOTES );
$this -> assertEquals ( 'a : b " c \' d ' e é' , $decodedstring , 'Function did not sanitize correclty' );
$stringtotest = 'a : b " c ' d ' e é' ;
2024-02-19 14:28:21 +00:00
$decodedstring = dol_html_entity_decode ( $stringtotest , ENT_QUOTES | ENT_HTML5 );
2021-01-14 14:09:08 +00:00
$this -> assertEquals ( 'a : b " c \' d \' e é' , $decodedstring , 'Function did not sanitize correclty' );
return 0 ;
}
/**
* testDolStringOnlyTheseHtmlTags
*
2023-11-29 19:19:21 +00:00
* @ return int
2021-01-14 14:09:08 +00:00
*/
public function testDolStringOnlyTheseHtmlTags ()
{
$stringtotest = '<a href="javascript:aaa">bbbڴ' ;
$decodedstring = dol_string_onlythesehtmltags ( $stringtotest , 1 , 1 , 1 );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( '<a href="aaa">bbbڴ' , $decodedstring , 'Function did not sanitize correctly with test 1' );
2021-01-14 14:09:08 +00:00
$stringtotest = '<a href="java' . chr ( 0 ) . 'script:aaa">bbbڴ' ;
$decodedstring = dol_string_onlythesehtmltags ( $stringtotest , 1 , 1 , 1 );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( '<a href="aaa">bbbڴ' , $decodedstring , 'Function did not sanitize correctly with test 2' );
2021-01-14 14:09:08 +00:00
$stringtotest = '<a href="javascript:aaa">bbbڴ' ;
$decodedstring = dol_string_onlythesehtmltags ( $stringtotest , 1 , 1 , 1 );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( '<a href="aaa">bbbڴ' , $decodedstring , 'Function did not sanitize correctly with test 3' );
2021-01-14 14:09:08 +00:00
2023-06-03 11:56:06 +00:00
$stringtotest = 'text <link href="aaa"> text' ;
$decodedstring = dol_string_onlythesehtmltags ( $stringtotest , 1 , 1 , 1 , 0 , array (), 0 );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( 'text text' , $decodedstring , 'Function did not sanitize correctly with test 4a' );
2023-06-03 11:56:06 +00:00
$stringtotest = 'text <link href="aaa"> text' ;
$decodedstring = dol_string_onlythesehtmltags ( $stringtotest , 1 , 1 , 1 , 0 , array (), 1 );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( 'text <link href="aaa"> text' , $decodedstring , 'Function did not sanitize correctly with test 4b' );
2023-06-03 11:56:06 +00:00
2021-01-14 14:09:08 +00:00
return 0 ;
}
2021-03-17 20:36:20 +00:00
/**
* testDolStringOnlyTheseHtmlAttributes
*
2023-11-29 19:19:21 +00:00
* @ return int
2021-03-17 20:36:20 +00:00
*/
public function testDolStringOnlyTheseHtmlAttributes ()
{
2021-12-17 11:01:25 +00:00
$stringtotest = 'eée' ;
$decodedstring = dol_string_onlythesehtmlattributes ( $stringtotest );
2025-09-05 09:38:30 +00:00
2025-07-15 19:51:50 +00:00
//$this->assertEquals('eée', $decodedstring, 'Function did not sanitize correctly with test 1');
$this -> assertEquals ( 'eée' , $decodedstring , 'Function did not sanitize correctly with test 1' );
2021-12-17 11:01:25 +00:00
2021-03-17 20:36:20 +00:00
$stringtotest = '<div onload="ee"><a href="123"><span class="abc">abc</span></a></div>' ;
$decodedstring = dol_string_onlythesehtmlattributes ( $stringtotest );
$decodedstring = preg_replace ( " / \n $ / " , " " , $decodedstring );
2024-01-12 16:14:13 +00:00
$this -> assertEquals ( '<div><a href="123"><span class="abc">abc</span></a></div>' , $decodedstring , 'Function did not sanitize correctly with test 2' );
2021-03-17 20:36:20 +00:00
return 0 ;
}
2021-01-14 14:09:08 +00:00
/**
* testGetRandomPassword
*
2023-11-29 19:19:21 +00:00
* @ return int
2021-01-14 14:09:08 +00:00
*/
public function testGetRandomPassword ()
{
global $conf ;
2024-02-19 14:28:21 +00:00
$genpass1 = getRandomPassword ( true ); // Should be a string return by dol_hash (if no option set, will be md5)
2021-01-14 14:09:08 +00:00
print __METHOD__ . " genpass1= " . $genpass1 . " \n " ;
$this -> assertEquals ( strlen ( $genpass1 ), 32 );
2024-02-19 14:28:21 +00:00
$genpass1 = getRandomPassword ( true , array ( 'I' )); // Should be a string return by dol_hash (if no option set, will be md5)
2021-01-14 14:09:08 +00:00
print __METHOD__ . " genpass1= " . $genpass1 . " \n " ;
$this -> assertEquals ( strlen ( $genpass1 ), 32 );
2024-02-19 14:28:21 +00:00
$conf -> global -> USER_PASSWORD_GENERATED = 'None' ;
$genpass2 = getRandomPassword ( false ); // Should return an empty string
2021-01-14 14:09:08 +00:00
print __METHOD__ . " genpass2= " . $genpass2 . " \n " ;
$this -> assertEquals ( $genpass2 , '' );
2024-02-19 14:28:21 +00:00
$conf -> global -> USER_PASSWORD_GENERATED = 'Standard' ;
$genpass3 = getRandomPassword ( false ); // Should return a password of 12 chars
2021-01-14 14:09:08 +00:00
print __METHOD__ . " genpass3= " . $genpass3 . " \n " ;
2021-04-19 18:25:22 +00:00
$this -> assertEquals ( strlen ( $genpass3 ), 12 );
2021-01-14 14:09:08 +00:00
return 0 ;
}
/**
* testRestrictedArea
*
* @ return void
*/
public function testRestrictedArea ()
{
global $conf , $user , $langs , $db ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2012-02-12 16:41:28 +00:00
2012-02-12 17:30:50 +00:00
//$dummyuser=new User($db);
//$result=restrictedArea($dummyuser,'societe');
2012-02-12 16:41:28 +00:00
2026-07-24 14:21:18 +00:00
$result = restrictedArea ( $user , 'societe' , 0 , '' , '' , 'fk_soc' , 'rowid' , 0 , 1 );
2019-01-27 12:07:22 +00:00
$this -> assertEquals ( 1 , $result );
2021-01-14 14:09:08 +00:00
}
2021-03-14 15:13:03 +00:00
/**
* testDolSanitizeUrl
*
* @ return void
*/
public function testDolSanitizeUrl ()
{
global $conf , $user , $langs , $db ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2021-03-14 15:13:03 +00:00
2021-03-14 17:57:18 +00:00
$test = 'javascripT&javascript#x3a alert(1)' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeUrl ( $test );
2021-03-14 19:37:59 +00:00
$this -> assertEquals ( 'x3a alert(1)' , $result , 'Test on dol_sanitizeUrl A' );
2021-03-14 17:57:18 +00:00
2021-03-14 15:13:03 +00:00
$test = 'javajavascriptscript&cjavascriptolon;alert(1)' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeUrl ( $test );
2021-03-14 17:57:18 +00:00
$this -> assertEquals ( 'alert(1)' , $result , 'Test on dol_sanitizeUrl B' );
2021-03-14 15:13:03 +00:00
$test = '/javas:cript/google.com' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeUrl ( $test );
2021-03-14 17:57:18 +00:00
$this -> assertEquals ( 'google.com' , $result , 'Test on dol_sanitizeUrl C' );
2021-03-14 15:13:03 +00:00
}
2022-11-28 15:54:34 +00:00
/**
* testDolSanitizeEmail
*
* @ return void
*/
public function testDolSanitizeEmail ()
{
global $conf , $user , $langs , $db ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2022-11-28 15:54:34 +00:00
$test = 'aaa@mycompany.com <My name>, bbb@mycompany.com <Another name>' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeEmail ( $test );
2022-11-28 15:54:34 +00:00
$this -> assertEquals ( $test , $result , 'Test on dol_sanitizeEmail A' );
$test = " aaa@mycompany.com <My name>, \n bbb@mycompany.com <Another name> " ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeEmail ( $test );
2022-11-28 15:54:34 +00:00
$this -> assertEquals ( 'aaa@mycompany.com <My name>,bbb@mycompany.com <Another name>' , $result , 'Test on dol_sanitizeEmail B' );
$test = 'aaa@mycompany.com <My name>,\nbbb@mycompany.com <Another name>' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeEmail ( $test );
2022-11-28 15:54:34 +00:00
$this -> assertEquals ( 'aaa@mycompany.com <My name>,nbbb@mycompany.com <Another name>' , $result , 'Test on dol_sanitizeEmail C' );
$test = 'aaa@mycompany.com <My name>, "bcc:bbb"@mycompany.com <Another name>' ;
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeEmail ( $test );
2022-11-28 15:54:34 +00:00
$this -> assertEquals ( 'aaa@mycompany.com <My name>, bccbbb@mycompany.com <Another name>' , $result , 'Test on dol_sanitizeEmail D' );
}
2021-01-14 14:09:08 +00:00
/**
* testDolSanitizeFileName
*
* @ return void
*/
public function testDolSanitizeFileName ()
{
global $conf , $user , $langs , $db ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2021-01-14 14:09:08 +00:00
//$dummyuser=new User($db);
//$result=restrictedArea($dummyuser,'societe');
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeFileName ( 'bad file | evilaction' );
2021-01-14 14:09:08 +00:00
$this -> assertEquals ( 'bad file _ evilaction' , $result );
2024-02-19 14:28:21 +00:00
$result = dol_sanitizeFileName ( 'bad file -evilparam --evilparam ---evilparam ----evilparam' );
2021-07-05 20:57:27 +00:00
$this -> assertEquals ( 'bad file _evilparam _evilparam _evilparam _evilparam' , $result );
2021-01-14 14:09:08 +00:00
}
2021-06-09 15:44:42 +00:00
/**
* testDolEval
*
* @ return void
*/
public function testDolEval ()
{
global $conf , $user , $langs , $db ;
2024-02-19 14:28:21 +00:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2021-06-09 15:44:42 +00:00
2024-03-03 12:11:54 +00:00
// Declare classes found into string to evaluate
include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php' ;
include_once DOL_DOCUMENT_ROOT . '/projet/class/task.class.php' ;
2025-04-01 10:23:58 +00:00
$conf -> global -> MAIN_USE_DOL_EVAL_NEW = 0 ;
//$conf->global->MAIN_USE_DOL_EVAL_NEW = 1;
2025-05-06 09:10:57 +00:00
$conf -> global -> MAIN_ALLOW_DOUBLE_COLON_IN_DOL_EVAL = 0 ;
2025-11-18 22:34:23 +00:00
$conf -> global -> MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 1 ;
2024-03-24 06:08:40 +00:00
2026-03-25 15:33:02 +00:00
// We force $dolibarr_main_restrict_eval_methods to 2 values, so the code will use the old black-list patterns.
2025-11-19 02:44:24 +00:00
global $dolibarr_main_restrict_eval_methods ;
2026-03-25 15:33:02 +00:00
foreach ( array ( '' , 'getDolGlobalString, getDolGlobalInt, getDolCurrency, getDolEntity, getDolDBType, fetchNoCompute, hasRight, isAdmin, isModEnabled, isStringVarMatching, abs, min, max, round, dol_now, preg_match' ) as $valparam ) {
$dolibarr_main_restrict_eval_methods = $valparam ;
print " \n dolibarr_main_restrict_eval_methods = " . $dolibarr_main_restrict_eval_methods . " \n " ;
//$dolibarr_main_restrict_eval_methods = array();
//$resulttest = dol_eval('((getDolGlobalString("MAIN_USE_ADVANCED_PERMS") ? $user->hasRight("user","group_advance","read") : $user->hasRight("user","user","lire")) || $user->admin) && !(isModEnabled("multicompany") && $conf->entity > 1 && getDolGlobalString("MULTICOMPANY_TRANSVERSE_MODE"))', 1, 0);
//print "resulttest = ".$resulttest."\n";
//$this->assertTrue($resulttest);
$result = dol_eval ( " ('exec') /* */ ('id') " );
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
$result = dol_eval ( " ('exec') ('id') " );
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
$result = dol_eval ( '1==1' , 1 , 0 );
print " result1 = " . $result . " \n " ;
$this -> assertTrue ( $result );
$result = dol_eval ( '1==2' , 1 , 0 );
print " result2 = " . $result . " \n " ;
$this -> assertFalse ( $result );
2026-03-29 18:31:54 +00:00
if ( empty ( $dolibarr_main_restrict_eval_methods )) { // Old mode
$s = '(($var1 = ne SyntaxErrorOnNew($db)))' ;
$result3a = dol_eval ( $s , 1 , 1 , '2' );
print " result3a = " . $result3a . " \n " ;
$this -> assertStringContainsString ( 'Exception during evaluation' , $result3a , 'The string was not detected as evil : ' . $s );
$s = '((($var1 = new ClassThatDoesNotExists($db)) && ($var1->fetchNoCompute($objectoffield->fk_product) > 0)) ? \'1\' : \'0\')' ;
$result3c = dol_eval ( $s , 1 , 1 , '2' );
print " result3c = " . $result3c . " \n " ;
$this -> assertStringContainsString ( 'Exception during evaluation' , $result3c , 'The string was not detected as evil : ' . $s );
$s = '((($var1 = new SimpleXMLElement()) ? \'1\' : \'0\')' ;
$result3d = dol_eval ( $s , 1 , 1 , '2' );
print " result3d = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Exception during evaluation' , $result3d , 'The string was not detected as evil : ' . $s );
} else { // New mode for v23+
$s = '(($var1 = ne SyntaxErrorOnNew($db)))' ;
$result3a = dol_eval ( $s , 1 , 1 , '2' );
print " result3a = " . $result3a . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate.' , $result3a , 'The string was not detected as evil' );
$s = '((($var1 = new ClassThatDoesNotExists($db)) && ($var1->fetchNoCompute($objectoffield->fk_product) > 0)) ? \'1\' : \'0\')' ;
$result3c = dol_eval ( $s , 1 , 1 , '2' );
print " result3c = " . $result3c . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result3c , 'The string was not detected as evil' );
$s = '((($var1 = new SimpleXMLElement()) ? \'1\' : \'0\')' ;
$result3d = dol_eval ( $s , 1 , 1 , '2' );
print " result3d = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result3d , 'The string was not detected as evil' );
}
// This next one are okfor syntax and allowance
2026-03-25 15:33:02 +00:00
$s = '((($var1 = new Project($db)) && ($var1->fetchNoCompute($objectoffield->fk_product) > 0)) ? \'1\' : \'0\')' ;
$result3b = dol_eval ( $s , 1 , 1 , '2' );
print " result3b = " . $result . " \n " ;
$this -> assertEquals ( '0' , $result3b );
2025-11-19 02:44:24 +00:00
2026-03-25 15:33:02 +00:00
$s = '(($var1 = new Task($db)) && ($var1->fetchNoCompute($objectoffield->id) > 0) && ($var2 = new Project($db)) && ($var2->fetchNoCompute($var1->fk_project) > 0)) ? $var2->ref : "Parent project not found"' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result3c = " . $result . " \n " ;
$this -> assertEquals ( 'Parent project not found' , $result );
2025-10-22 00:21:52 +00:00
2026-03-25 15:33:02 +00:00
$s = '(($var1 = new Task($db)) && ($var1->fetchNoCompute($objectoffield->id) > 0) && ($var2 = new Project($db)) && ($var2->fetchNoCompute($var1->fk_project) > 0)) ? $var2->ref : \'Parent project not found\'' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result4 = " . $result . " \n " ;
$this -> assertEquals ( 'Parent project not found' , $result , 'Test 4' );
$s = '4 < 5' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result6 = " . $result . " \n " ;
$this -> assertEquals ( '1' , $result , 'Test 5' );
/*
$s = 'MyClass::MyMethod()' ;
$result = dol_eval ( $s , 1 , 1 , '2' );
print " result7 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (double : char is forbidden without setting MAIN_ALLOW_DOUBLE_COLON_IN_DOL_EVAL)' , $result , 'The string was not detected as evil' );
*/
2025-10-22 00:21:52 +00:00
2026-03-25 15:33:02 +00:00
/* not allowed . Not a one line eval string
$result = ( string ) dol_eval ( 'if ($a == 1) { }' , 1 , 1 );
print " result4b = " . $result . " \n " ;
$this -> assertEquals ( 'aaa' , $result );
*/
2021-06-09 15:44:42 +00:00
2026-03-25 15:33:02 +00:00
// Now string not allowed
2021-06-09 15:44:42 +00:00
2026-03-25 15:33:02 +00:00
$s = '4 <5' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' ); // in mode 2, char < is allowed only if followed by a space
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'Test 4 <5 - The string was not detected as evil' );
2024-03-03 12:11:54 +00:00
2026-03-25 15:33:02 +00:00
$s = '4 < 5' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '1' ); // in mode 1, char < is always forbidden
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'Test 4 < 5 - The string was not detected as evil' );
2022-03-01 15:38:06 +00:00
2026-03-29 18:31:54 +00:00
$s = '1==\x01' ;
$result = dol_eval ( $s , 1 , 1 , '1' ); // Check that we can't make dol_eval on string containing \ char.
print " result5 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string)' , $result );
2026-03-25 15:33:02 +00:00
$s = 'new abc->invoke(\'whoami\')' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2022-03-01 15:38:06 +00:00
2026-03-29 18:31:54 +00:00
/* $s = 'new ReflectionFunction(\'abc\')' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
*/
2026-03-25 15:33:02 +00:00
$s = 'new ReflectionFunction(\'abc\')' ;
$result = ( string ) dol_eval ( $s , 1 , 1 , '2' );
print " result = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
$result = dol_eval ( 'json_encode(array_map(implode("",["ex","ec"]), ["id"]))' , 1 , 1 , '1' ); // result of dol_eval may be an object Closure
print " result4a = " . json_encode ( $result ) . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'The string was not detected as evil, it should due to the [ char and method "2"' );
$result = dol_eval ( 'json_encode(array_map(implode("",["ex","ec"]), ["id"]))' , 1 , 1 , '2' ); // result of dol_eval may be an object Closure
print " result4b = " . json_encode ( $result ) . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'The string was not detected as evil, it should due to the use of array_map' );
$result = dol_eval ( 'json_encode(array_map(implode("",array("ex","ec"), array("id")))' , 1 , 1 , '1' ); // result of dol_eval may be an object Closure
print " result4c = " . json_encode ( $result ) . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'The string was not detected as evil, it should due to the use of array_map' );
2024-12-23 13:07:08 +00:00
2026-03-25 15:33:02 +00:00
$result = dol_eval ( '$a=function() { }; $a' , 1 , 1 , '0' ); // result of dol_eval may be an object Closure
print " result5 = " . json_encode ( $result ) . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'The string was not detected as evil' );
$result = dol_eval ( '$a=function() { }; $a();' , 1 , 1 , '1' );
print " result6 = " . json_encode ( $result ) . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'The string was not detected as evil' );
$result = ( string ) dol_eval ( 'instruction;' , 1 , 1 ); // ; is not allowed.
print " result7 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string)' , $result , 'The string was not detected as evil' );
$result = ( string ) dol_eval ( '$var1=exec("ls")' , 1 , 1 );
print " result7 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
$result = ( string ) dol_eval ( '$var1=exec(\'ls\')' , 1 , 1 );
print " result7 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
$result = ( string ) dol_eval ( '$var1=exec ("ls")' , 1 , 1 );
print " result8 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2025-04-01 10:23:58 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( " strrev('metsys') ('whoami') " , 1 , 1 );
print " result8b = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2024-12-23 13:07:08 +00:00
2026-03-25 15:33:02 +00:00
$conf -> global -> MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 0 ;
2025-07-15 03:42:06 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '$a="test"; $$a;' , 1 , 0 );
print " result9 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string)' , $result , 'The string was not detected as evil' );
2025-07-15 03:42:06 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '`ls`' , 1 , 0 );
print " result10 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2023-09-08 12:12:12 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( " ('ex'.'ec')('ls') " , 1 , 0 ); // This will execute exec of ls
print " result11 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2021-06-09 15:44:42 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( " ('ex'.'ec') /* */ (/* */'ls') " , 1 , 0 ); // This will execute exec of ls
print " result11 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( " sprintf( \" %s%s \" , \" ex \" , \" ec \" )('echo abc') " , 1 , 0 );
print " result12 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'The string was not detected as evil' );
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
$result = dol_eval ( " 90402.38+267678+0 " , 1 , 1 , 1 );
print " result13 = " . $result . " \n " ;
$this -> assertEquals ( '358080.38' , $result , 'The string was not detected as evil' );
2021-06-09 15:44:42 +00:00
2024-12-23 10:57:19 +00:00
2026-03-25 15:33:02 +00:00
// Must be allowed
2021-10-31 14:59:03 +00:00
2026-03-25 15:33:02 +00:00
global $mainmenu , $leftmenu ; // Used into following strings to eval
2025-05-10 10:53:37 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'AAA' ;
$result = dol_eval ( 'getDolCurrency() && preg_match(\'/^(AAA|BBB)/\',$leftmenu)' , 1 , 1 , '1' );
print " result = " . $result . " \n " ;
$this -> assertTrue ( $result );
2021-06-09 15:44:42 +00:00
2026-03-25 15:33:02 +00:00
// Same with a value that does not match
$leftmenu = 'XXX' ;
$result = dol_eval ( 'getDolCurrency() && preg_match(\'/^(AAA|BBB)/\',$leftmenu)' , 1 , 1 , '1' );
print " result14 = " . $result . " \n " ;
$this -> assertFalse ( $result );
2022-03-01 15:38:06 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'AAA' ;
$result = dol_eval ( 'getDolCurrency() && isStringVarMatching(\'leftmenu\', \'(AAA|BBB)\')' , 1 , 1 , '1' );
print " result15 = " . $result . " \n " ;
$this -> assertTrue ( $result );
2025-04-01 13:21:43 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'XXX' ;
$result = dol_eval ( 'getDolCurrency() && isStringVarMatching(\'leftmenu\', \'(AAA|BBB)\')' , 1 , 1 , '1' );
print " result16 = " . $result . " \n " ;
$this -> assertFalse ( $result );
2022-03-01 15:38:06 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'XXX' ;
$conf -> global -> MAIN_FEATURES_LEVEL = 1 ; // Force for the case option is -1
$string = '(isModEnabled("user") || isModEnabled("resource")) && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 0 && preg_match(\'/^(admintools|all|XXX)/\', $leftmenu)' ;
$result = dol_eval ( $string , 1 , 1 , '1' );
print " result17 = " . $result . " \n " ;
$this -> assertTrue ( $result );
2022-03-01 17:14:24 +00:00
2026-03-25 15:33:02 +00:00
$result = dol_eval ( '1 && getDolGlobalInt("doesnotexist1") && getDolGlobalInt("MAIN_FEATURES_LEVEL")' , 1 , 0 ); // Should return false and not a 'Bad string syntax to evaluate ...'
print " result18 = " . $result . " \n " ;
$this -> assertFalse ( $result );
2024-12-23 10:57:19 +00:00
2026-03-25 15:33:02 +00:00
$mainmenu = 'TTT' ;
$leftmenu = 'LLL' ;
$result = ( string ) dol_eval ( '$mainmenu=\'T2\' && ($mainmenu == \'TTT\')' , 1 , 0 );
print " result11 = " . $result . " \n " ;
$this -> assertEquals ( '1' , $result , 'The string was not detected as evil' );
2022-05-09 19:56:21 +00:00
2022-03-03 00:59:31 +00:00
2026-03-25 15:33:02 +00:00
// Test option MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL
2022-03-03 00:17:44 +00:00
2026-03-25 15:33:02 +00:00
$conf -> global -> MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 1 ;
2022-03-03 00:59:31 +00:00
2026-03-25 15:33:02 +00:00
$mainmenu = 'ex' ;
$result = ( string ) dol_eval ( '$mainmenu.\'ec\'' , 1 , 0 );
print " resultconcat1 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'exec' , $result , 'With MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL on. we should accept concat' );
2023-09-08 03:51:06 +00:00
2026-03-25 15:33:02 +00:00
$mainmenu = 'ex' ;
$leftmenu = 'ec' ;
$result = ( string ) dol_eval ( " \$ mainmenu. \$ leftmenu " , 1 , 0 );
print " resultconcat2 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'exec' , $result , 'With MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL on. we should accept concat' );
2023-09-08 03:51:06 +00:00
2026-03-25 15:33:02 +00:00
// Test option MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 0
2022-03-03 00:17:44 +00:00
2026-03-25 15:33:02 +00:00
$conf -> global -> MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 0 ;
2022-03-01 15:38:06 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'ab' ;
$result = ( string ) dol_eval ( " ( \$ leftmenu.'s') " , 1 , 0 );
print " resultconcat3 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (dot char is forbidden if not strictly between 2 numbers)' , $result , 'Test concat - The string was not reported as a bad syntax when it should' );
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
// Not allowed
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
$conf -> global -> MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL = 1 ;
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
$leftmenu = 'abs' ;
$result = ( string ) dol_eval ( '$leftmenu(-5)' , 1 , 0 );
print " result20 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (mode 1, found a call using "$abc(" or "$abc (" instead of using the direct name of the function)' , $result , 'Test 20 - The string was not detected as evil' );
2025-04-01 11:25:10 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( 'str_replace("z","e","zxzc")("whoami");' , 1 , 0 );
print " result21 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'Test 21 - The string was not detected as evil' );
2024-12-23 10:57:19 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '($a = "ex") && ($b = "ec") && ($cmd = "$a$b") && $cmd ("curl localhost:5555")' , 1 , 0 );
print " result22 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , $result , 'Test 22 - The string was not detected as evil' );
2025-04-01 14:23:50 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '\'exec\'("aaa")' , 1 , 0 );
print " result23 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'Test 23 - The string was not detected as evil - Can\'t find the string Bad string syntax when it should' );
2025-04-01 14:23:50 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '1 + 2 <? echo "aaa" ?>' , 1 , 0 , '2' );
print " result24 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate (The char ? can be used only with a space before and after)' , json_encode ( $result ), 'Test 24 - The string was not detected as evil - Can\'t find the string Bad string syntax when i should' );
2024-06-04 12:06:35 +00:00
2026-03-25 15:33:02 +00:00
$result = ( string ) dol_eval ( '$$a' , 1 , 0 );
print " result25 = " . $result . " \n " ;
$this -> assertStringContainsString ( 'Bad string syntax to evaluate' , json_encode ( $result ), 'Test 25 - The string was not detected as evil - Can\'t find the string Bad string syntax when i should' );
}
2021-06-09 15:44:42 +00:00
}
2022-05-09 19:56:21 +00:00
2025-01-08 16:41:45 +00:00
2025-03-09 20:26:51 +00:00
/**
* testRealCharforNumericEntities ()
*
* @ return int
*/
public function testRealCharforNumericEntities ()
{
global $conf ;
// Test that testRealCharforNumericEntities return an ascii char when code is inside Ascii range
$arraytmp = array ( 0 => 'a' , 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 => '✅' , 1 => '9989;' ); // Encoded as decimal
$result = realCharForNumericEntities ( $arraytmp );
$this -> assertEquals ( '✅' , $result );
$arraytmp = array ( 0 => '✅' , 1 => 'x2705;' ); // Encoded as hexadecimal
$result = realCharForNumericEntities ( $arraytmp );
$this -> assertEquals ( '✅' , $result );
return 0 ;
}
2023-11-29 19:19:21 +00:00
/**
2025-01-08 16:41:45 +00:00
* testDolPrintHTMLAndDolPrintHtmlForAttribute .
2023-11-29 19:19:21 +00:00
* This method include calls to dol_htmlwithnojs ()
*
* @ return int
*/
2025-01-08 16:41:45 +00:00
public function testDolPrintHTMLAndDolPrintHtmlForAttribute ()
2023-11-29 19:19:21 +00:00
{
global $conf ;
// Set options for cleaning data
2023-11-29 23:06:05 +00:00
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ; // disabled, does not work on HTML5 and some libxml versions
2025-01-06 11:56:24 +00:00
// Enable option MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY if possible
2023-11-29 19:19:21 +00:00
if ( extension_loaded ( 'tidy' ) && class_exists ( " tidy " )) {
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1 ;
2025-01-06 11:56:24 +00:00
} else {
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
2025-03-09 20:26:51 +00:00
print " WARNING !!! php-tidy is not available !!! " ;
2023-11-29 19:19:21 +00:00
}
2023-11-29 23:06:05 +00:00
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ; // disabled, does not work on HTML5 and some libxml versions
2023-11-29 19:19:21 +00:00
2025-01-08 16:41:45 +00:00
// dolPrintHTML - With dolPrintHTML(), only content not already in HTML is encoded with HTML.
$stringtotest = " < > <b>bold</b> " ;
$stringfixed = " < > <b>bold</b> " ;
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTML test 1' ); // Expected '' because should failed because login 'auto' does not exists
2026-01-20 11:30:08 +00:00
$stringtotest = " <b>bold</b> <code>aaa</code> " ;
$stringfixed = " <b>bold</b> aaa " ;
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTML test 1' ); // Expected '' because should failed because login 'auto' does not exists
$stringtotest = " <b>bold</b> <code>aaa</code> " ;
$stringfixed = " <b>bold</b> aaa " ;
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
$result = dolPrintHTML ( $stringtotest , 0 , array ( 'code' ));
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTML test 1' ); // Expected '' because should failed because login 'auto' does not exists
2025-01-08 16:41:45 +00:00
2024-01-12 16:14:13 +00:00
// For a string that is already HTML (contains HTML tags) with special tags but badly formatted
2025-01-08 16:41:45 +00:00
$stringtotest = " " > < <b>bold</b> " ;
$stringfixed = " " > < <b>bold</b> " ;
2023-11-29 19:19:21 +00:00
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
2025-01-08 16:41:45 +00:00
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
2023-11-29 19:19:21 +00:00
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
2025-01-08 16:41:45 +00:00
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTML test 2' ); // Expected '' because should failed because login 'auto' does not exists
// dolPrintHTMLForAttribute - With dolPrintHTMLForAttribute(), the content is HTML encode, even if it is already HTML content.
2023-11-29 19:19:21 +00:00
2025-01-08 16:41:45 +00:00
$stringtotest = " < > <b>bold</b> " ;
$stringfixed = " < > <b>bold</b> " ;
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
$result = dolPrintHTMLForAttribute ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTMLForAttribute test 1' ); // Expected '' because should failed because login 'auto' does not exists
// For a string that is already HTML (contains HTML tags) with special tags but badly formatted
$stringtotest = " " > < <b>bold</b> " ;
$stringfixed = " &quot; &gt; &lt; <b>bold</b> " ;
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0, array())), 1, 1, 'common', 0, 1);
$result = dolPrintHTMLForAttribute ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTMLForAttribute test 2' ); // Expected '' because should failed because login 'auto' does not exists
2025-01-09 12:54:25 +00:00
// dolPrintHTMLForAttributeUrl - With dolPrintHTMLForAttributeUrl(), the param should already be and HTML URL encoded
$stringtotest = " <b>aa</b> & & a=%10 " ;
$stringfixed = " aa & & a=%10 " ;
// $result = dol_escape_htmltag(dol_string_onlythesehtmltags($s, 1, 1, 1, 0, array()), 0, 0, '', $escapeonlyhtmltags, 1);
$result = dolPrintHTMLForAttributeUrl ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTMLForAttributeUrl test 1' ); // Expected '' because should failed because login 'auto' does not exists
// For a string that is already HTML (contains HTML tags) with special tags but badly formatted
$stringtotest = " aa & & a=%10 " ;
$stringfixed = " aa & & a=%10 " ;
// $result = dol_escape_htmltag(dol_string_onlythesehtmltags($s, 1, 1, 1, 0, array()), 0, 0, '', $escapeonlyhtmltags, 1);
$result = dolPrintHTMLForAttributeUrl ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTMLForAttributeUrl test 2' ); // Expected '' because should failed because login 'auto' does not exists
2025-01-08 16:41:45 +00:00
// dolPrintHTML
/*
//return dol_escape_htmltag(dol_string_onlythesehtmltags(dol_htmlentitiesbr($s), 1, 0, 0, 0, array('br', 'b', 'font', 'hr', 'span')), 1, -1, '', 0, 1);
$result = dolPrintHTMLForAttribute ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error in dolPrintHTML test 2' ); // Expected '' because should failed because login 'auto' does not exists
*/
2023-11-29 19:19:21 +00:00
2024-01-12 16:14:13 +00:00
// For a string that is already HTML (contains HTML tags) with special tags but badly formatted
2023-11-29 19:19:21 +00:00
$stringtotest = " testA \n <h1>hhhh</h1><z>ddd</z><header>aaa</header><footer>bbb</footer> " ;
if ( getDolGlobalString ( " MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY " )) {
2023-11-29 23:06:05 +00:00
$stringfixed = " testA \n <h1>hhhh</h1> \n ddd \n <header>aaa</header> \n <footer>bbb</footer> \n " ;
2023-11-29 19:19:21 +00:00
} else {
$stringfixed = " testA \n <h1>hhhh</h1>ddd<header>aaa</header><footer>bbb</footer> " ;
}
//$result = dol_htmlentitiesbr($stringtotest);
//$result = dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0);
//$result = dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0));
//$result = dol_escape_htmltag(dol_htmlwithnojs(dol_string_onlythesehtmltags(dol_htmlentitiesbr($stringtotest), 1, 1, 1, 0)), 1, 1, 'common', 0, 1);
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
2023-11-29 23:06:05 +00:00
$this -> assertEquals ( $stringfixed , $result , 'Error' );
2023-11-29 19:19:21 +00:00
2024-01-12 16:14:13 +00:00
// For a string that is already HTML (contains HTML tags) but badly formatted
2023-11-29 19:19:21 +00:00
$stringtotest = " testB \n <h1>hhh</h1> \n <td>td alone</td><h1>iii</h1> " ;
if ( getDolGlobalString ( " MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY " )) {
2023-11-29 23:06:05 +00:00
$stringfixed = " testB \n <h1>hhh</h1> \n <h1>iii</h1> \n <table> \n <tr> \n <td>td alone</td> \n </tr> \n </table> \n " ;
2023-11-29 19:19:21 +00:00
} else {
$stringfixed = " testB \n <h1>hhh</h1> \n <td>td alone</td><h1>iii</h1> " ;
}
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
2023-11-29 23:06:05 +00:00
$this -> assertEquals ( $stringfixed , $result , 'Error' );
2023-11-29 19:19:21 +00:00
// For a string with no HTML tags
2024-07-22 14:36:24 +00:00
$stringtotest = " testwithnewline \n second line " ;
$stringfixed = " testwithnewline<br> \n second line " ;
2023-11-29 19:19:21 +00:00
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
2023-11-29 23:06:05 +00:00
$this -> assertEquals ( $stringfixed , $result , 'Error' );
2023-11-29 19:19:21 +00:00
2025-03-09 20:26:51 +00:00
// 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 & 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 & b " ;
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringfixed , $result , 'Error' );
*/
2024-07-22 14:36:24 +00:00
// For a string with ' and '
// With no clean option
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
$stringtotest = " Message<br>with ' and è and ' ! " ;
/*
var_dump ( $stringtotest );
var_dump ( dol_htmlentitiesbr ( $stringtotest ));
var_dump ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 ));
var_dump ( dol_htmlwithnojs ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 )));
var_dump ( dol_escape_htmltag ( dol_htmlwithnojs ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 )), 1 , 1 , 'common' , 0 , 1 ));
*/
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringtotest , $result , 'Error' );
2024-07-27 16:07:37 +00:00
2024-07-22 14:36:24 +00:00
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
// Enabled 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 ;
}
// For a string with ' and '
// With cleaning options of HTML TIDY
if ( extension_loaded ( 'tidy' ) && class_exists ( " tidy " )) {
$stringtotest = " Message<br>with ' and è and ' ! " ;
2025-03-09 20:26:51 +00:00
//$stringexpected = "Message<br>\nwith ' and è and ' !"; // The ' is modified into ' because html tidy fix it.
$stringexpected = " Message<br> \n with ' and è and ' ! " ;
2024-07-22 14:36:24 +00:00
/*
var_dump ( $stringtotest );
var_dump ( dol_htmlentitiesbr ( $stringtotest ));
var_dump ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 ));
var_dump ( dol_htmlwithnojs ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 )));
var_dump ( dol_escape_htmltag ( dol_htmlwithnojs ( dol_string_onlythesehtmltags ( dol_htmlentitiesbr ( $stringtotest ), 1 , 1 , 1 , 0 )), 1 , 1 , 'common' , 0 , 1 ));
*/
$result = dolPrintHTML ( $stringtotest );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $stringexpected , $result , 'Error' );
}
2023-11-29 19:19:21 +00:00
return 0 ;
}
2024-05-14 16:19:48 +00:00
/**
2025-03-09 20:26:51 +00:00
* testDolPrintHTML
* This method include calls to dol_htmlwithnojs ()
2024-05-14 16:19:48 +00:00
*
* @ return int
2025-03-09 20:26:51 +00:00
*
* @ depends testDolPrintHTMLAndDolPrintHtmlForAttribute
2024-05-14 16:19:48 +00:00
*/
2025-03-09 20:26:51 +00:00
public function testDolPrintHTML ()
2024-05-14 16:19:48 +00:00
{
global $conf ;
2025-03-09 20:26:51 +00:00
// 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 !!! " ;
}
2025-03-09 22:37:36 +00:00
$libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ; // Ok with 2.9.14, not ok on HTML5 and some libxmlversion like the one of travis
2024-05-14 16:19:48 +00:00
2025-03-09 20:26:51 +00:00
// 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 & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&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: & é < " \'' ;
$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 & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&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: & é < " \'' ;
$result = dolPrintHTML ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
2025-03-09 22:37:36 +00:00
if ( $libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES ) {
// 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 & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & & é é < < " " \' \' <a href="aaa?aaa=1&bbb=2&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: & é < " \'' ;
$result = dolPrintHTML ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
}
}
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
if ( $libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES ) {
// With remove Bad attributes option only
2025-03-09 20:26:51 +00:00
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
2025-03-09 22:37:36 +00:00
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ; //
2025-03-09 20:26:51 +00:00
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1 ; // 1 = Replaces & alone into & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & & é é < < " " \' \' <a href="aaa?aaa=1&bbb=2&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: & é < " \'' ;
$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 !!! " ;
}
2025-03-09 22:37:36 +00:00
$libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ; // Ok with 2.9.14, not ok on HTML5 and some libxmlversion like the one of travis
2025-03-09 20:26:51 +00:00
// 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 & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & &amp; é é < &lt; " &quot; \' &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; é &lt; &quot; \'' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
2025-03-09 22:37:36 +00:00
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 & and replaces ' into '
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & &amp; é é < &lt; " &quot; \' &apos; a z' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
// For a string that is not an already HTML content
$s = 'List: & é < " \'' ; // Detected as non already HTML
$expectedresult = 'List: &amp; é &lt; &quot; \'' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
if ( $libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES ) {
// 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 & and replaces ' into '
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & &amp; é é < &lt; " &quot; \' &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; é &lt; &quot; \'' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
}
}
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
if ( $libXmlIsOkForMAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES ) {
// 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 & and replaces ' into '
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
// For a string with a simple & inside and already encoded
$s = 'List of char+their entities: & & é é < < " " \' ' <a href="aaa?aaa=1&bbb=2&ccc=3">a</a> <zzz>z</zzz>' ; // Detected as already HTML
$expectedresult = 'List of char+their entities: & &amp; é é < &lt; " &quot; \' &apos; a z' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
2025-03-09 20:26:51 +00:00
2025-03-09 22:37:36 +00:00
// For a string that is not an already HTML content
$s = 'List: & é < " \'' ; // Detected as non already HTML
$expectedresult = 'List: &amp; é &lt; &quot; \'' ;
$result = dolPrintHTMLForAttribute ( $s );
$this -> assertEquals ( $expectedresult , $result , 'Error on test dolPrintHTML' );
}
2024-05-14 16:19:48 +00:00
return 0 ;
}
/**
* testDolHtmlWithNoJs ()
*
* @ return int
2025-03-09 20:26:51 +00:00
*
* @ depends testDolPrintHTMLAndDolPrintHtmlForAttribute
2024-05-14 16:19:48 +00:00
*/
public function testDolHtmlWithNoJs ()
{
global $conf ;
2026-03-26 14:46:21 +00:00
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 2 ; // 1 = only valid html, 2 = only valid htm and allowed styles
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1 ;
// Test on sanitizing styles
$result = dol_htmlwithnojs ( 'Text <div style="position: 0">Div content</div><span style="z-index: 123">Text</span> and more' , 0 , 'restricthtml' );
print __METHOD__ . " result= " . $result . " \n " ;
2026-03-29 17:15:21 +00:00
// Normalize formatting differences between libxml/php versions (spaces and line breaks around tags/style values)
2026-03-29 17:22:55 +00:00
$normalizedresult = str_replace ( array ( " \r " , " \n " , " \t " ), ' ' , $result );
2026-03-29 17:15:21 +00:00
$normalizedresult = preg_replace ( '/style="\s*([0-9]+)\s*"/' , 'style="$1"' , $normalizedresult );
2026-03-29 17:22:55 +00:00
$normalizedresult = preg_replace ( '/>\s*</' , '><' , $normalizedresult );
$this -> assertEquals ( 'Text <div style="0">Div content</div><span style="123">Text</span> and more' , $normalizedresult , 'Test sanitizing style for CSS UI redressing' );
2026-03-26 14:46:21 +00:00
2025-07-15 19:51:50 +00:00
// Test on a string in hindi with MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES because
// in past this case was losing the UTF8.
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0 ;
$result = dol_htmlwithnojs ( 'String in Hindi लेखाकर्म' , 0 , 'restricthtml' );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( 'String in Hindi लेखाकर्म' , $result , 'Test js sanitizing a Hindi string is ko' );
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1 ;
$result = dol_htmlwithnojs ( 'String in Hindi लेखाकर्म' , 0 , 'restricthtml' );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( 'String in Hindi लेखाकर्म' , $result , 'Test js sanitizing a Hindi string is ko' );
$conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1 ;
$result = dol_htmlwithnojs ( 'String in Hindi लेखाकर्म' , 0 , 'restricthtml' );
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( 'String in Hindi लेखाकर्म' , $result , 'Test js sanitizing a Hindi string is ko' );
2026-03-26 14:46:21 +00:00
// Test emoticons
2025-07-15 19:51:50 +00:00
2026-03-26 14:46:21 +00:00
$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.
2025-03-09 20:26:51 +00:00
2024-05-15 10:19:57 +00:00
$sav1 = getDolGlobalString ( 'MAIN_RESTRICTHTML_ONLY_VALID_HTML' );
$sav2 = getDolGlobalString ( 'MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY' );
2024-05-14 16:19:48 +00:00
// Test with an emoji
$test = 'abc ✅ def' ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1 ;
$result = dol_htmlwithnojs ( $test );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
print __METHOD__ . " result for dol_htmlwithnojs and MAIN_RESTRICTHTML_ONLY_VALID_HTML=0 with emoji = " . $result . " \n " ;
$this -> assertEquals ( $test , $result , 'dol_htmlwithnojs failed with an emoji when MAIN_RESTRICTHTML_ONLY_VALID_HTML=0' );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
$result = dol_htmlwithnojs ( $test );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
print __METHOD__ . " result for dol_htmlwithnojs and MAIN_RESTRICTHTML_ONLY_VALID_HTML=1 with emoji = " . $result . " \n " ;
$this -> assertEquals ( $test , $result , 'dol_htmlwithnojs failed with an emoji when MAIN_RESTRICTHTML_ONLY_VALID_HTML=1' );
2024-07-27 16:07:37 +00:00
// For a string with js on attribute
// Without HTML_TIDY
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
2025-01-09 18:19:28 +00:00
2024-07-27 16:07:37 +00:00
$result = dol_htmlwithnojs ( '<img onerror=alert(document.domain) src=x>' , 1 , 'restricthtml' );
print __METHOD__ . " result= " . $result . " \n " ;
2025-01-09 18:28:08 +00:00
$this -> assertEquals ( '<img alert(document.domain) src=x>' , $result , 'Test js sanitizing without tidy on' );
2024-07-27 16:07:37 +00:00
2025-01-09 18:19:28 +00:00
$result = dol_htmlwithnojs ( '<<r>scr<r>ipt<r>>alert("hello")<<r>/scr<r>ipt<r>>' , 1 , 'restricthtml' );
//$result = dol_string_onlythesehtmltags($aa, 0, 1, 1);
print __METHOD__ . " result= " . $result . " \n " ;
2025-01-09 18:28:08 +00:00
$this -> assertEquals ( 'alert("hello")' , $result , 'Test js sanitizing without tidy' );
2025-01-09 18:19:28 +00:00
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
2024-07-27 16:07:37 +00:00
// With HTML TIDY
if ( extension_loaded ( 'tidy' ) && class_exists ( " tidy " )) {
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1 ;
2025-01-09 18:19:28 +00:00
2024-07-27 16:07:37 +00:00
$result = dol_htmlwithnojs ( '<img onerror=alert(document.domain) src=x>' , 1 , 'restricthtml' );
//$result = dol_string_onlythesehtmltags($aa, 0, 1, 1);
print __METHOD__ . " result= " . $result . " \n " ;
2025-01-09 18:28:08 +00:00
$this -> assertEquals ( '<img src="x">' , $result , 'Test js sanitizing with tidy on' );
2025-01-09 18:19:28 +00:00
$result = dol_htmlwithnojs ( '<<r>scr<r>ipt<r>>alert("hello")<<r>/scr<r>ipt<r>>' , 1 , 'restricthtml' );
//$result = dol_string_onlythesehtmltags($aa, 0, 1, 1);
print __METHOD__ . " result= " . $result . " \n " ;
2025-01-09 18:28:08 +00:00
$this -> assertEquals ( '<script>alert("hello")</script>' , $result , 'Test js sanitizing with tidy on' );
2025-01-09 18:19:28 +00:00
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
2024-07-27 16:07:37 +00:00
}
2024-09-09 13:56:47 +00:00
// For a string with js and link with restricthtmlallowlinkscript
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
$s = ' < link rel = " stylesheet " id = " google-fonts-css " href = " //fonts.googleapis.com/css?family=Open+Sans:300,400,700 " >
< link rel = " stylesheet " id = " font-wasesome-css " href = " //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css " >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js " ></ script >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js " ></ script > ' ;
$result = dol_htmlwithnojs ( $s , 1 , 'restricthtmlallowlinkscript' );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $s , $result , 'Test for restricthtmlallowlinkscript' );
// For a string with js and link with restricthtmlallowlinkscript
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 1 ;
$s = ' < link rel = " stylesheet " id = " google-fonts-css " href = " //fonts.googleapis.com/css?family=Open+Sans:300,400,700 " >
< link rel = " stylesheet " id = " font-wasesome-css " href = " //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css " >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js " ></ script >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js " ></ script > ' ;
$result = dol_htmlwithnojs ( $s , 1 , 'restricthtmlallowlinkscript' );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $s , $result , 'Test for restricthtmlallowlinkscript' );
// For a string with js and link with restricthtmlallowlinkscript
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = 0 ;
$s = ' < link rel = " stylesheet " id = " google-fonts-css " href = " //fonts.googleapis.com/css?family=Open+Sans:300,400,700 " >
< link rel = " stylesheet " id = " font-wasesome-css " href = " //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css " >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js " ></ script >
< script src = " //cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js " ></ script > ' ;
$result = dol_htmlwithnojs ( $s , 1 , 'restricthtmlallowlinkscript' );
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML = $sav1 ;
$conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML_TIDY = $sav2 ;
print __METHOD__ . " result= " . $result . " \n " ;
$this -> assertEquals ( $s , $result , 'Test for restricthtmlallowlinkscript' );
2024-05-14 16:19:48 +00:00
return 0 ;
}
2010-11-20 15:25:08 +00:00
}