2017-05-12 15:45:00 +02:00
< ? php
/* Copyright ( C ) 2013 Laurent Destailleur < eldy @ users . sourceforge . net >
*
* 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
*/
/**
* \file test / phpunit / SqlTest . php
* \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' ;
2019-01-27 13:07:22 +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)
2017-05-12 15:45:00 +02:00
if ( empty ( $user -> id ))
{
print " Load permissions for admin user nb 1 \n " ;
$user -> fetch ( 1 );
$user -> getrights ();
}
$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
{
protected $savconf ;
protected $savuser ;
protected $savlangs ;
protected $savdb ;
/**
* Constructor
* We save global variables into local variables
*
* @ return SecurityTest
*/
2019-02-25 00:56:48 +01:00
public function __construct ()
2017-05-12 15:45:00 +02:00
{
2019-02-25 00:56:48 +01:00
parent :: __construct ();
2018-09-02 14:23:52 +02:00
2019-02-25 00:56:48 +01:00
//$this->sharedFixture
2017-05-12 15:45:00 +02:00
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 " ;
}
2020-05-03 22:47:43 +02:00
/**
* setUpBeforeClass
*
* @ return void
*/
2017-05-12 15:45:00 +02:00
public static function setUpBeforeClass ()
{
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 " ;
}
2020-05-03 22:47:43 +02:00
/**
* tearDownAfterClass
*
* @ return void
*/
2017-05-12 15:45:00 +02:00
public static function tearDownAfterClass ()
{
global $conf , $user , $langs , $db ;
$db -> rollback ();
print __METHOD__ . " \n " ;
}
/**
* Init phpunit tests
*
* @ return void
*/
protected function setUp ()
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
print __METHOD__ . " \n " ;
}
/**
* End phpunit tests
*
* @ return void
*/
protected function tearDown ()
{
print __METHOD__ . " \n " ;
}
/**
* testSql
*
* @ return string
*/
public function testPHP ()
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2017-05-18 19:19:55 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2017-05-12 15:45:00 +02:00
$filesarray = dol_dir_list ( DOL_DOCUMENT_ROOT , 'files' , 1 , '\.php' , null , 'fullname' );
2017-06-18 21:13:48 +02:00
foreach ( $filesarray as $key => $file )
2017-05-12 15:45:00 +02:00
{
if ( preg_match ( '/\/htdocs\/includes\//' , $file [ 'fullname' ])) continue ;
if ( preg_match ( '/\/htdocs\/custom\//' , $file [ 'fullname' ])) continue ;
if ( preg_match ( '/\/htdocs\/dolimed/' , $file [ 'fullname' ])) continue ;
2017-05-12 16:55:11 +02:00
if ( preg_match ( '/\/htdocs\/nltechno/' , $file [ 'fullname' ])) continue ;
if ( preg_match ( '/\/htdocs\/teclib/' , $file [ 'fullname' ])) continue ;
2017-06-18 21:13:48 +02:00
2017-05-12 15:45:00 +02:00
print 'Check php file ' . $file [ 'fullname' ] . " \n " ;
$filecontent = file_get_contents ( $file [ 'fullname' ]);
2017-06-18 21:13:48 +02:00
2017-07-26 21:22:53 +02:00
2020-02-17 12:34:00 +01:00
$ok = true ;
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
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 [ 'fullname' ]);
//exit;
2017-07-26 21:22:53 +02:00
$ok = true ;
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
preg_match_all ( '/(..)\s*\.\s*\$this->db->idate\(/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val )
{
2019-02-25 00:56:48 +01:00
if ( $val [ 1 ] != '\'"' && $val [ 1 ] != '\'\'' )
{
$ok = false ;
break ;
}
//if ($reg[0] != 'db') $ok=false;
2017-07-26 21:22:53 +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 a $this->db->idate to forge a sql request without quotes around this date field ' . $file [ 'fullname' ] . ' :: ' . $val [ 0 ]);
//exit;
2017-05-12 15:45:00 +02:00
$ok = true ;
$matches = array ();
2017-05-29 13:29:27 +02:00
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
2017-09-15 15:41:07 +02:00
preg_match_all ( '/(=|sql.+)\s*\'"\s*\.\s*\$this->(....)/' , $filecontent , $matches , PREG_SET_ORDER );
2017-05-12 15:45:00 +02:00
foreach ( $matches as $key => $val )
{
2017-09-15 15:41:07 +02:00
if ( $val [ 2 ] != 'db->' && $val [ 2 ] != 'esca' )
2017-05-12 15:45:00 +02: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";
2017-05-12 16:55:11 +02:00
$this -> assertTrue ( $ok , 'Found non escaped string in building of a sql request ' . $file [ 'fullname' ] . ' (' . $val [ 0 ] . '). Bad.' );
2017-05-12 15:45:00 +02:00
//exit;
2017-06-18 21:13:48 +02:00
2017-07-26 21:22:53 +02:00
2017-06-18 21:27:49 +02:00
// Test that output of $_SERVER\[\'QUERY_STRING\'\] is escaped.
2017-06-18 21:13:48 +02:00
$ok = true ;
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
2018-02-14 22:17:53 +01:00
preg_match_all ( '/(..............)\$_SERVER\[\'QUERY_STRING\'\]/' , $filecontent , $matches , PREG_SET_ORDER );
2017-06-18 21:13:48 +02:00
foreach ( $matches as $key => $val )
{
2019-02-25 00:56:48 +01:00
if ( $val [ 1 ] != 'scape_htmltag(' && $val [ 1 ] != 'ing_nohtmltag(' && $val [ 1 ] != 'dol_escape_js(' )
2016-02-15 00:31:33 +01:00
{
2017-06-18 21:13:48 +02:00
$ok = false ;
break ;
2016-02-15 00:31:33 +01:00
}
2015-01-06 17:54:36 +01:00
}
2017-09-14 09:16:57 +02:00
$this -> assertTrue ( $ok , 'Found a $_SERVER[\'QUERY_STRING\'] without dol_escape_htmltag neither dol_string_nohtmltag around it, in file ' . $file [ 'fullname' ] . ' (' . $val [ 1 ] . '$_SERVER[\'QUERY_STRING\']). Bad.' );
2017-06-18 21:27:49 +02:00
2017-08-02 13:31:53 +02:00
// Test that first param of print_liste_field_titre is a translation key and not the translated value
$ok = true ;
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
preg_match_all ( '/print_liste_field_titre\(\$langs/' , $filecontent , $matches , PREG_SET_ORDER );
foreach ( $matches as $key => $val )
{
2019-02-25 00:56:48 +01:00
$ok = false ;
break ;
2017-08-02 13:31:53 +02:00
}
2019-03-09 01:13:15 +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 [ 'fullname' ] . '. Bad.' );
2017-08-02 13:31:53 +02:00
2018-01-17 13:26:57 +01:00
// Test we don't have <br />
$ok = true ;
2017-06-18 21:27:49 +02:00
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
2018-01-17 13:26:57 +01:00
preg_match_all ( '/<br \/>/' , $filecontent , $matches , PREG_SET_ORDER );
2017-06-18 21:27:49 +02:00
foreach ( $matches as $key => $val )
{
2019-02-25 00:56:48 +01:00
if ( $file [ 'name' ] != 'functions.lib.php' )
2017-06-18 21:27:49 +02:00
{
$ok = false ;
break ;
}
}
2019-04-01 18:16:50 +02:00
$this -> assertTrue ( $ok , 'Found a tag <br /> that is for xml in file ' . $file [ 'fullname' ] . '. You may use html syntax <br> instead.' );
// Test we don't have @var array(
$ok = true ;
$matches = array ();
// Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request.
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 [ 'fullname' ] . '.' );
2017-05-12 15:45:00 +02:00
}
return ;
}
}