2017-05-12 15:45:00 +02:00
< ? php
/* Copyright ( C ) 2013 Laurent Destailleur < eldy @ users . sourceforge . net >
2023-05-07 14:31:35 +02:00
* Copyright ( C ) 2023 Alexandre Janniaux < alexandre . janniaux @ gmail . com >
2017-05-12 15:45:00 +02: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
* the Free Software Foundation ; either version 3 of the License , or
* ( 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 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2017-05-12 15:45:00 +02:00
*/
/**
2021-11-11 17:08:35 +01:00
* \file test / phpunit / CodingPhpTest . php
2017-05-12 15:45:00 +02:00
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI : phpunit filename . php
*/
global $conf , $user , $langs , $db ;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
require_once dirname ( __FILE__ ) . '/../../htdocs/master.inc.php' ;
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security.lib.php' ;
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security2.lib.php' ;
2021-01-14 15:09:08 +01:00
if ( ! defined ( 'NOREQUIREUSER' )) {
define ( 'NOREQUIREUSER' , '1' );
}
if ( ! defined ( 'NOREQUIREDB' )) {
define ( 'NOREQUIREDB' , '1' );
}
if ( ! defined ( 'NOREQUIRESOC' )) {
define ( 'NOREQUIRESOC' , '1' );
}
if ( ! defined ( 'NOREQUIRETRAN' )) {
define ( 'NOREQUIRETRAN' , '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 ( empty ( $user -> id )) {
print " Load permissions for admin user nb 1 \n " ;
$user -> fetch ( 1 );
$user -> getrights ();
2017-05-12 15:45:00 +02:00
}
$conf -> global -> MAIN_DISABLE_ALL_MAILS = 1 ;
/**
* Class for PHPUnit tests
*
* @ backupGlobals disabled
* @ backupStaticAttributes enabled
* @ remarks backupGlobals must be disabled to have db , conf , user and lang not erased .
*/
2019-07-05 21:28:27 +02:00
class CodingPhpTest extends PHPUnit\Framework\TestCase
2017-05-12 15:45:00 +02:00
{
2021-01-14 15:09:08 +01:00
protected $savconf ;
protected $savuser ;
protected $savlangs ;
protected $savdb ;
/**
* Constructor
* We save global variables into local variables
*
2023-05-17 12:27:46 +02:00
* @ param string $name Name
2021-01-14 15:09:08 +01:00
* @ return SecurityTest
*/
2023-05-07 14:31:35 +02:00
public function __construct ( $name = '' )
2021-01-14 15:09:08 +01:00
{
2023-05-07 14:31:35 +02:00
parent :: __construct ( $name );
2021-01-14 15:09:08 +01:00
//$this->sharedFixture
global $conf , $user , $langs , $db ;
$this -> savconf = $conf ;
$this -> savuser = $user ;
$this -> savlangs = $langs ;
$this -> savdb = $db ;
print __METHOD__ . " db->type= " . $db -> type . " user->id= " . $user -> id ;
//print " - db ".$db->db;
print " \n " ;
}
/**
* setUpBeforeClass
*
* @ return void
*/
2022-09-21 17:55:04 +02:00
public static function setUpBeforeClass () : void
2021-01-14 15:09:08 +01:00
{
global $conf , $user , $langs , $db ;
$db -> begin (); // This is to have all actions inside a transaction even if test launched without suite.
print __METHOD__ . " \n " ;
}
/**
* tearDownAfterClass
*
* @ return void
*/
2022-09-21 17:55:04 +02:00
public static function tearDownAfterClass () : void
2021-01-14 15:09:08 +01:00
{
global $conf , $user , $langs , $db ;
$db -> rollback ();
print __METHOD__ . " \n " ;
}
/**
* Init phpunit tests
*
* @ return void
*/
2022-09-21 17:55:04 +02:00
protected function setUp () : void
2021-01-14 15:09:08 +01:00
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2021-08-27 22:42:04 +02:00
2021-01-14 15:09:08 +01:00
print __METHOD__ . " \n " ;
}
/**
* End phpunit tests
*
* @ return void
*/
2022-09-21 17:55:04 +02:00
protected function tearDown () : void
2021-01-14 15:09:08 +01:00
{
print __METHOD__ . " \n " ;
}
/**
2022-12-24 15:06:32 +01:00
* testPHP
2021-01-14 15:09:08 +01:00
*
* @ return string
*/
public function testPHP ()
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2022-12-24 15:06:32 +01:00
$filesarray = dol_dir_list ( DOL_DOCUMENT_ROOT , 'files' , 1 , '\.php' , null , 'fullname' , SORT_ASC , 0 , 1 , '' , 1 );
2021-01-14 15:09:08 +01:00
foreach ( $filesarray as $key => $file ) {
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/includes\//' , $file [ 'fullname' ])) {
2021-01-14 15:09:08 +01:00
continue ;
}
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/install\/doctemplates\/websites\//' , $file [ 'fullname' ])) {
2022-10-10 12:05:03 +02:00
continue ;
}
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/custom\//' , $file [ 'fullname' ])) {
2021-01-14 15:09:08 +01:00
continue ;
}
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/dolimed/' , $file [ 'fullname' ])) {
2021-01-14 15:09:08 +01:00
continue ;
}
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/nltechno/' , $file [ 'fullname' ])) {
2021-01-14 15:09:08 +01:00
continue ;
}
2023-06-19 20:07:46 +02:00
if ( preg_match ( '/\/(htdocs|html)\/teclib/' , $file [ 'fullname' ])) {
2021-01-14 15:09:08 +01:00
continue ;
}
2023-05-26 14:51:51 +02:00
//print 'Check php file '.$file['relativename']."\n";
2021-01-14 15:09:08 +01:00
$filecontent = file_get_contents ( $file [ 'fullname' ]);
if ( preg_match ( '/\.class\.php/' , $file [ 'relativename' ])
|| preg_match ( '/boxes\/box_/' , $file [ 'relativename' ])
|| preg_match ( '/modules\/.*\/doc\/(doc|pdf)_/' , $file [ 'relativename' ])
|| preg_match ( '/modules\/(import|mailings|printing)\//' , $file [ 'relativename' ])
2022-09-03 20:08:13 +02:00
|| in_array ( $file [ 'name' ], array ( 'modules_boxes.php' , 'TraceableDB.php' ))) {
2022-05-17 15:10:20 +02:00
// Check into Class files
2021-01-14 15:09:08 +01:00
if ( ! in_array ( $file [ 'name' ], array (
'api.class.php' ,
'commonobject.class.php' ,
'conf.class.php' ,
'html.form.class.php' ,
'translate.class.php' ,
'utils.class.php' ,
'TraceableDB.php' ,
'multicurrency.class.php' ,
2022-03-01 00:01:13 +01:00
'infobox.class.php'
2021-01-14 15:09:08 +01:00
))) {
2021-11-24 23:07:06 +01:00
// Must not find $db->
2021-01-14 15:09:08 +01:00
$ok = true ;
$matches = array ();
2021-11-24 23:07:06 +01:00
// Check string $db-> inside a class.php file (it should be $this->db-> into such classes)
2021-01-14 15:09:08 +01:00
preg_match_all ( '/' . preg_quote ( '$db->' , '/' ) . '/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2021-10-04 19:03:14 +02:00
$this -> assertTrue ( $ok , 'Found string $db-> into a .class.php file in ' . $file [ 'relativename' ] . '. Inside a .class file, you should use $this->db-> instead.' );
2021-01-14 15:09:08 +01:00
//exit;
}
} else {
2022-05-17 15:10:20 +02:00
// Check into Include files
2021-01-14 15:09:08 +01:00
if ( ! in_array ( $file [ 'name' ], array (
2022-03-01 00:01:13 +01:00
'objectline_view.tpl.php' ,
2021-01-14 15:09:08 +01:00
'extrafieldsinexport.inc.php' ,
2022-04-04 13:59:50 +02:00
'extrafieldsinimport.inc.php' ,
2023-06-19 18:55:49 +02:00
'DolQueryCollector.php' ,
'DoliStorage.php'
2021-01-14 15:09:08 +01:00
))) {
2022-03-01 00:01:13 +01:00
// Must not found $this->db->
2021-01-14 15:09:08 +01:00
$ok = true ;
$matches = array ();
2021-08-23 17:41:11 +02:00
// Check string $this->db-> into a non class.php file (it shoud be $db-> into such classes)
2021-01-14 15:09:08 +01:00
preg_match_all ( '/' . preg_quote ( '$this->db->' , '/' ) . '/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2022-03-01 00:01:13 +01:00
$this -> assertTrue ( $ok , 'Found string "$this->db->" in ' . $file [ 'relativename' ]);
2021-01-14 15:09:08 +01:00
//exit;
}
}
2022-09-03 20:08:13 +02:00
// Check we don't miss top_httphead() into any ajax pages
if ( preg_match ( '/ajax\//' , $file [ 'relativename' ])) {
print " Analyze ajax page " . $file [ 'relativename' ] . " \n " ;
$ok = true ;
$matches = array ();
preg_match_all ( '/top_httphead/' , $filecontent , $matches , PREG_SET_ORDER );
if ( count ( $matches ) == 0 ) {
$ok = false ;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Did not find top_httphead into the ajax page ' . $file [ 'relativename' ]);
//exit;
}
2022-05-17 15:10:20 +02:00
// Check if a var_dump has been forgotten
if ( ! preg_match ( '/test\/phpunit/' , $file [ 'fullname' ])) {
2023-06-19 20:05:54 +02:00
if ( ! in_array ( $file [ 'name' ], array ( 'class.nusoap_base.php' ))) {
$ok = true ;
$matches = array ();
preg_match_all ( '/(.)\s*var_dump\(/' , $filecontent , $matches , PREG_SET_ORDER );
//var_dump($matches);
foreach ( $matches as $key => $val ) {
if ( $val [ 1 ] != '/' && $val [ 1 ] != '*' ) {
$ok = false ;
break ;
}
2022-05-17 15:10:20 +02:00
break ;
}
2023-06-19 20:05:54 +02:00
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found string var_dump that is not just after /* or // in ' . $file [ 'relativename' ]);
//exit;
2022-05-17 15:10:20 +02:00
}
}
// Check get_class followed by __METHOD__
2021-01-14 15:09:08 +01:00
$ok = true ;
$matches = array ();
preg_match_all ( '/' . preg_quote ( 'get_class($this)."::".__METHOD__' , '/' ) . '/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found string get_class($this)."::".__METHOD__ that must be replaced with __METHOD__ only in ' . $file [ 'relativename' ]);
//exit;
2021-09-30 15:24:57 +02:00
// Check string $this->db->idate without quotes
2021-01-14 15:09:08 +01:00
$ok = true ;
$matches = array ();
preg_match_all ( '/(..)\s*\.\s*\$this->db->idate\(/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
if ( $val [ 1 ] != '\'"' && $val [ 1 ] != '\'\'' ) {
$ok = false ;
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found a $this->db->idate to forge a sql request without quotes around this date field ' . $file [ 'relativename' ]);
//exit;
2021-08-27 16:33:03 +02:00
// Check sql string DELETE|OR|AND|WHERE|INSERT ... yyy = ".$xxx
2021-08-27 22:42:04 +02:00
// with xxx that is not 'thi' (for $this->db->sanitize) and 'db-' (for $db->sanitize). It means we forget a ' if string, or an (int) if int, when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2022-01-03 18:15:19 +01:00
preg_match_all ( '/(DELETE|OR|AND|WHERE|INSERT)\s.*([^\s][^\s][^\s])\s*=\s*(\'|")\s*\.\s*\$(...)/' , $filecontent , $matches , PREG_SET_ORDER );
2021-08-23 17:41:11 +02:00
foreach ( $matches as $key => $val ) {
2022-01-03 18:15:19 +01:00
if ( $val [ 2 ] == 'ity' && $val [ 4 ] == 'con' ) { // exclude entity = ".$conf->entity
2021-09-02 13:25:00 +02:00
continue ;
}
2022-01-03 18:15:19 +01:00
if ( $val [ 2 ] == 'ame' && $val [ 4 ] == 'db-' && preg_match ( '/WHERE name/' , $val [ 0 ])) { // exclude name = ".$db->encrypt(
2021-09-02 13:25:00 +02:00
continue ;
}
2022-01-03 18:15:19 +01:00
if ( $val [ 2 ] == 'ame' && $val [ 4 ] == 'thi' && preg_match ( '/WHERE name/' , $val [ 0 ])) { // exclude name = ".$this->db->encrypt(
2021-08-23 17:41:11 +02:00
continue ;
}
2021-08-23 18:56:46 +02:00
var_dump ( $matches );
$ok = false ;
2021-08-23 17:45:16 +02:00
break ;
2021-08-23 17:41:11 +02:00
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2021-08-23 18:56:46 +02:00
$this -> assertTrue ( $ok , 'Found non quoted or not casted var into sql request ' . $file [ 'relativename' ] . ' - Bad.' );
2021-08-23 17:41:11 +02:00
//exit;
2021-09-30 15:59:47 +02:00
// Check that forged sql string is using ' instead of " as string PHP quotes
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
preg_match_all ( '/\$sql \.= \'\s*VALUES.*\$/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
//if ($val[1] != '\'"' && $val[1] != '\'\'') {
2023-12-04 11:22:28 +01:00
var_dump ( $matches );
$ok = false ;
break ;
2021-09-30 15:24:57 +02:00
//}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2022-09-10 00:54:16 +02:00
$this -> assertTrue ( $ok , 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables into file ' . $file [ 'relativename' ] . ' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...' );
2021-09-30 15:24:57 +02:00
//exit;
2021-09-30 15:59:47 +02:00
// Check that forged sql string is using ' instead of " as string PHP quotes
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2021-09-30 15:59:47 +02:00
preg_match_all ( '/\$sql \.?= \'SELECT.*\$/' , $filecontent , $matches , PREG_SET_ORDER );
2021-09-30 15:24:57 +02:00
foreach ( $matches as $key => $val ) {
var_dump ( $matches );
$ok = false ;
break ;
}
2022-02-14 11:51:05 +01:00
$this -> assertTrue ( $ok , 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables into file ' . $file [ 'relativename' ] . ' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...' );
2021-09-30 15:24:57 +02:00
2021-08-27 22:42:04 +02:00
// Check sql string VALUES ... , ".$xxx
// with xxx that is not 'db-' (for $db->escape). It means we forget a ' if string, or an (int) if int, when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2021-08-27 22:42:04 +02:00
preg_match_all ( '/(VALUES).*,\s*"\s*\.\s*\$(...)/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
2021-09-02 13:25:00 +02:00
if ( $val [ 1 ] == 'VALUES' && $val [ 2 ] == 'db-' ) { // exclude $db->escape(
continue ;
}
if ( $val [ 1 ] == 'VALUES' && $val [ 2 ] == 'thi' && preg_match ( '/this->db->encrypt/' , $val [ 0 ])) { // exclude ".$this->db->encrypt(
2021-08-27 22:42:04 +02:00
continue ;
}
var_dump ( $matches );
$ok = false ;
break ;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found non quoted or not casted var into sql request ' . $file [ 'relativename' ] . ' - Bad.' );
//exit;
// Check '".$xxx non escaped
2021-08-23 17:41:11 +02:00
2021-01-14 15:09:08 +01:00
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2021-01-14 15:09:08 +01:00
preg_match_all ( '/=\s*\'"\s*\.\s*\$this->(....)/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
if ( $val [ 1 ] != 'db->' && $val [ 1 ] != 'esca' ) {
$ok = false ;
break ;
}
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2021-08-27 22:42:04 +02:00
$this -> assertTrue ( $ok , 'Found non escaped string in building of a sql request (case 1) in ' . $file [ 'relativename' ] . ' - Bad.' );
2021-01-14 15:09:08 +01:00
2021-10-25 18:40:19 +02:00
// Check string sql|set|WHERE|...'".$yyy->xxx with xxx that is not 'escape', 'idate', .... It means we forget a db->escape when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2021-11-11 17:08:35 +01:00
preg_match_all ( '/(sql|SET|WHERE|INSERT|VALUES|LIKE).+\s*\'"\s*\.\s*\$(.......)/' , $filecontent , $matches , PREG_SET_ORDER );
2021-01-14 15:09:08 +01:00
foreach ( $matches as $key => $val ) {
2022-03-07 19:37:53 +01:00
if ( ! in_array ( $val [ 2 ], array ( 'this->d' , 'this->e' , 'db->esc' , 'dbs->es' , 'dbs->id' , 'mydb->e' , 'dbsessi' , 'db->ida' , 'escaped' , 'exclude' , 'include' ))) {
2021-10-25 18:40:19 +02:00
$ok = false ; // This will generate error
2021-01-14 15:09:08 +01:00
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
2021-08-27 22:42:04 +02:00
$this -> assertTrue ( $ok , 'Found non escaped string in building of a sql request (case 2) in ' . $file [ 'relativename' ] . ': ' . $val [ 0 ] . ' - Bad.' );
2021-01-14 15:09:08 +01:00
//exit;
2021-08-27 22:42:04 +02:00
// Check string sql|set...'.$yyy->xxx with xxx that is not 'escape', 'idate', .... It means we forget a db->escape when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2021-08-27 22:42:04 +02:00
preg_match_all ( '/(\$sql|SET\s|WHERE\s|INSERT\s|VALUES\s|VALUES\().+\s*\'\s*\.\s*\$(.........)/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
2022-12-28 17:50:44 +01:00
if ( ! in_array ( $val [ 2 ], array ( 'this->db-' , 'db->prefi' , 'db->sanit' , 'dbs->pref' , 'dbs->sani' , 'conf->ent' , 'key : \'\')' , 'key])."\')' , 'excludefi' , 'regexstri' , '' ))) {
2021-08-27 22:42:04 +02:00
$ok = false ;
var_dump ( $matches );
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found non escaped string in building of a sql request (case 3) in ' . $file [ 'relativename' ] . ': ' . $val [ 0 ] . ' - Bad.' );
//exit;
// Checks with IN
2022-01-13 18:34:15 +01:00
// Check string ' IN (".xxx' or ' IN (\'.xxx' with xxx that is not '$this->db->sanitize' and not '$db->sanitize'. It means we forget a db->sanitize when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2022-01-13 18:34:15 +01:00
preg_match_all ( '/\s+IN\s*\([\'"]\s*\.\s*(.........)/i' , $filecontent , $matches , PREG_SET_ORDER );
2021-03-22 12:00:41 +01:00
foreach ( $matches as $key => $val ) {
2022-01-13 18:34:15 +01:00
//var_dump($val);
2021-03-22 12:47:23 +01:00
if ( ! in_array ( $val [ 1 ], array ( '$db->sani' , '$this->db' , 'getEntity' , 'WON\',\'L' , 'self::STA' , 'Commande:' , 'CommandeF' , 'Entrepot:' , 'Facture::' , 'FactureFo' , 'ExpenseRe' , 'Societe::' , 'Ticket::S' ))) {
2021-03-22 12:00:41 +01:00
$ok = false ;
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found non sanitized string in building of a IN or NOT IN sql request ' . $file [ 'relativename' ] . ' - Bad.' );
//exit;
2021-01-14 15:09:08 +01:00
2022-01-13 18:34:15 +01:00
// Check string ' IN (\'".xxx' with xxx that is not '$this->db->sanitize' and not '$db->sanitize'. It means we forget a db->sanitize when forging sql request.
2021-09-30 15:24:57 +02:00
$ok = true ;
$matches = array ();
2022-01-13 18:34:15 +01:00
preg_match_all ( '/\s+IN\s*\(\'"\s*\.\s*(.........)/i' , $filecontent , $matches , PREG_SET_ORDER );
2021-03-23 03:44:50 +01:00
foreach ( $matches as $key => $val ) {
2022-01-13 18:34:15 +01:00
//var_dump($val);
2021-03-23 03:44:50 +01:00
if ( ! in_array ( $val [ 1 ], array ( '$db->sani' , '$this->db' , 'getEntity' , 'WON\',\'L' , 'self::STA' , 'Commande:' , 'CommandeF' , 'Entrepot:' , 'Facture::' , 'FactureFo' , 'ExpenseRe' , 'Societe::' , 'Ticket::S' ))) {
$ok = false ;
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found non sanitized string in building of a IN or NOT IN sql request ' . $file [ 'relativename' ] . ' - Bad.' );
//exit;
2021-01-14 15:09:08 +01:00
// Test that output of $_SERVER\[\'QUERY_STRING\'\] is escaped.
$ok = true ;
$matches = array ();
preg_match_all ( '/(..............)\$_SERVER\[\'QUERY_STRING\'\]/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
if ( $val [ 1 ] != 'scape_htmltag(' && $val [ 1 ] != 'ing_nohtmltag(' && $val [ 1 ] != 'dol_escape_js(' ) {
$ok = false ;
break ;
}
}
2022-01-10 15:52:45 +01:00
$this -> assertTrue ( $ok , 'Found a $_SERVER[\'QUERY_STRING\'] without dol_escape_htmltag neither dol_string_nohtmltag around it, in file ' . $file [ 'relativename' ] . '. Bad.' );
2021-01-14 15:09:08 +01:00
2022-01-19 15:20:10 +01:00
// Check GETPOST(... 'none');
$ok = true ;
$matches = array ();
preg_match_all ( '/GETPOST\s*\(([^\)]+),\s*["\']none["\']/i' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
2022-02-23 19:24:17 +01:00
//var_dump($val);
2022-01-19 15:20:10 +01:00
if ( ! in_array ( $val [ 1 ], array (
2022-09-03 20:08:13 +02:00
" 'replacestring' " , " 'htmlheader' " , " 'WEBSITE_HTML_HEADER' " , " 'WEBSITE_CSS_INLINE' " , " 'WEBSITE_JS_INLINE' " , " 'WEBSITE_MANIFEST_JSON' " , " 'PAGE_CONTENT' " , " 'WEBSITE_README' " , " 'WEBSITE_LICENSE' " ,
2022-08-26 19:27:38 +02:00
'"mysqldump"' , '"postgresqldump"' ,
" 'db_pass_root' " , " 'db_pass' " , '"pass"' , '"pass1"' , '"pass2"' , '"password"' , " 'password' " ,
'"MAIN_MAIL_SMTPS_PW"' , '"MAIN_MAIL_SMTPS_PW_EMAILING"' , '"MAIN_MAIL_SMTPS_PW_TICKET"' ))) {
2022-01-19 15:20:10 +01:00
$ok = false ;
break ;
}
//if ($reg[0] != 'db') $ok=false;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this -> assertTrue ( $ok , 'Found a GETPOST that use \'none\' as a parameter in file ' . $file [ 'relativename' ] . ' and param is not an allowed parameter for using none - Bad.' );
//exit;
2021-01-14 15:09:08 +01:00
// Test that first param of print_liste_field_titre is a translation key and not the translated value
$ok = true ;
$matches = array ();
2021-08-23 17:41:11 +02:00
// Check string ='print_liste_field_titre\(\$langs'.
2021-01-14 15:09:08 +01:00
preg_match_all ( '/print_liste_field_titre\(\$langs/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
2023-12-04 11:22:28 +01:00
$ok = false ;
break ;
2021-01-14 15:09:08 +01:00
}
$this -> assertTrue ( $ok , 'Found a use of print_liste_field_titre with first parameter that is a translated value instead of just the translation key in file ' . $file [ 'relativename' ] . '. Bad.' );
// Test we don't have <br />
$ok = true ;
$matches = array ();
2021-08-23 17:41:11 +02:00
preg_match_all ( '/<br\s+\/>/' , $filecontent , $matches , PREG_SET_ORDER );
2021-01-14 15:09:08 +01:00
foreach ( $matches as $key => $val ) {
if ( $file [ 'name' ] != 'functions.lib.php' ) {
$ok = false ;
break ;
}
}
$this -> assertTrue ( $ok , 'Found a tag <br /> that is for xml in file ' . $file [ 'relativename' ] . '. You must use html syntax <br> instead.' );
// Test we don't have name="token" value="'.$_SESSION['newtoken'], we must use name="token" value="'.newToken() instead.
$ok = true ;
$matches = array ();
preg_match_all ( '/name="token" value="\'\s*\.\s*\$_SESSION/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
if ( $file [ 'name' ] != 'excludefile.php' ) {
$ok = false ;
break ;
}
}
$this -> assertTrue ( $ok , 'Found a forbidden string sequence into ' . $file [ 'relativename' ] . ' : name="token" value="\'.$_SESSION[..., you must use a newToken() instead of $_SESSION[\'newtoken\'].' );
2022-08-14 16:38:20 +02:00
// Test we don't have preg_grep with a param without preg_quote
2022-01-08 19:50:55 +01:00
$ok = true ;
$matches = array ();
preg_match_all ( '/preg_grep\(.*\$/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
if ( strpos ( $val [ 0 ], 'preg_quote' ) === false ) {
$ok = false ;
break ;
}
}
$this -> assertTrue ( $ok , 'Found a preg_grep with a param that is a $var but without preg_quote in file ' . $file [ 'relativename' ] . '.' );
2023-03-17 18:05:45 +01:00
// Test we don't have "if ($resql >"
$ok = true ;
$matches = array ();
preg_match_all ( '/if \(\$resql >/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
$this -> assertTrue ( $ok , 'Found a if $resql with a > operator (when $resql is a boolean or resource) in file ' . $file [ 'relativename' ] . '. Please remove the > ... part.' );
2022-08-14 16:38:20 +02:00
// Test we don't have empty($user->hasRight
$ok = true ;
$matches = array ();
preg_match_all ( '/empty\(\$user->hasRight/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
2023-08-27 15:55:44 +02:00
$this -> assertTrue ( $ok , 'Found code empty($user->hasRight in file ' . $file [ 'relativename' ] . '. empty() must not be used on a var not on a function.' );
2022-08-14 16:38:20 +02:00
2022-09-25 14:56:13 +02:00
// Test we don't have empty(DolibarrApiAccess::$user->hasRight
$ok = true ;
$matches = array ();
preg_match_all ( '/empty\(DolibarrApiAccess::\$user->hasRight/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
2023-08-27 15:55:44 +02:00
$this -> assertTrue ( $ok , 'Found code empty(DolibarrApiAccess::$user->hasRight in file ' . $file [ 'relativename' ] . '. empty() must not be used on a var not on a function.' );
// Test we don't have empty($user->hasRight
$ok = true ;
$matches = array ();
preg_match_all ( '/empty\(getDolGlobal/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
$this -> assertTrue ( $ok , 'Found code empty(getDolGlobal... in file ' . $file [ 'relativename' ] . '. empty() must be used on a var not on a function.' );
2022-08-14 16:38:20 +02:00
2021-01-14 15:09:08 +01:00
// Test we don't have @var array(
$ok = true ;
$matches = array ();
preg_match_all ( '/@var\s+array\(/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
$this -> assertTrue ( $ok , 'Found a declaration @var array() instead of @var array in file ' . $file [ 'relativename' ] . '.' );
2021-02-03 23:18:44 +01:00
2021-03-01 00:19:52 +01:00
// Test we don't have CURDATE()
$ok = true ;
$matches = array ();
preg_match_all ( '/CURDATE\(\)/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val ) {
$ok = false ;
break ;
}
$this -> assertTrue ( $ok , 'Found a CURDATE\(\) into code. Do not use this SQL method in file ' . $file [ 'relativename' ] . '. You must use the PHP function dol_now() instead.' );
}
2021-01-14 15:09:08 +01:00
return ;
}
2017-05-12 15:45:00 +02:00
}