diff --git a/dev/test_parse_formula.php b/dev/test_parse_formula.php index ac62e01d1..023f15af6 100644 --- a/dev/test_parse_formula.php +++ b/dev/test_parse_formula.php @@ -1,10 +1,10 @@ '; foreach ( array('1', @@ -30,21 +30,21 @@ foreach ( array('1', 'ls -1') as $a ) { echo "Testing :".$a; - echo (CheckFormula($a)==false)?'Non valide ':'ok'; + echo (Impress::check_formula($a)==false)?'Non valide ':'ok'; echo '
'; foreach (array('+','-','/') as $b ) { $ee=str_replace('*',$b,$a); echo "Testing :".$ee; - echo (CheckFormula($ee)==false)?'Non valide ':'ok'; + echo (Impress::check_formula($ee)==false)?'Non valide ':'ok'; echo '
'; } for($e=0;$e<3;$e++) { $a.="*".$a; echo "Testing :".$a; - echo (CheckFormula($a)==false)?'Non valide ':'ok'; + echo (Impress::check_formula($a)==false)?'Non valide ':'ok'; echo '
'; } diff --git a/include/ac_common.php b/include/ac_common.php index c78f6c73c..d737a186d 100644 --- a/include/ac_common.php +++ b/include/ac_common.php @@ -619,6 +619,8 @@ function alert($p_msg, $buffer=false) */ function set_language() { + // desactivate local check + if ( defined(LOCALE) && LOCALE==0 ) return; $dir = ""; // set differently the language depending of the operating system if (what_os() == 1) @@ -859,10 +861,6 @@ function show_menu($module, $idx) if (empty($amenu) || count($amenu) == 1) { - /** - * @todo add security - * check if user can access this module - */ $file = $cn->get_array("select me_file,me_parameter,me_javascript,me_type from menu_ref join profile_menu using (me_code) diff --git a/include/class_acc_bilan.php b/include/class_acc_bilan.php index 77a9fd1da..dad824b1e 100644 --- a/include/class_acc_bilan.php +++ b/include/class_acc_bilan.php @@ -27,7 +27,7 @@ require_once("class_iselect.php"); require_once ('class_database.php'); require_once ('class_dossier.php'); -require_once ('impress_inc.php'); +require_once ('class_impress.php'); require_once ('header_print.php'); require_once ('class_acc_account_ledger.php'); @@ -305,7 +305,7 @@ class Acc_Bilan while (! feof ($p_handle)) { $buffer=trim(fgets($p_handle)); - // $a=(CheckFormula($buffer) == true)?"$buffer ok
":''.'Pas ok '.$buffer."
"; + // $a=(Impress::check_formula($buffer) == true)?"$buffer ok
":''.'Pas ok '.$buffer."
"; // echo $a; // blank line are skipped if (strlen(trim($buffer))==0) @@ -315,7 +315,7 @@ class Acc_Bilan continue; // buffer contains a formula A$=.... // We need to eval it - $a=ParseFormula($this->db,"$buffer",$buffer,$this->from,$this->to,false); + $a=Impress::parse_formula($this->db,"$buffer",$buffer,$this->from,$this->to,false); $b=str_replace("$","\$this->",$a); if ( eval("$b;") === false ) echo_debug(__FILE__,__LINE__,"Code failed with $b"); diff --git a/include/class_acc_report.php b/include/class_acc_report.php index 33698d507..a055ef77c 100644 --- a/include/class_acc_report.php +++ b/include/class_acc_report.php @@ -25,7 +25,7 @@ require_once("class_itext.php"); require_once("class_ibutton.php"); require_once('class_acc_report_row.php'); -require_once('impress_inc.php'); +require_once('class_impress.php'); /*! * \brief Class rapport Create, view, modify and parse report @@ -85,7 +85,7 @@ class Acc_Report for ($i=0;$i<$Max;$i++) { $l_line=Database::fetch_array($Res,$i); - $col[]=ParseFormula($this->db, + $col[]=Impress::parse_formula($this->db, $l_line['fo_label'], $l_line['fo_formula'], $p_start, diff --git a/include/class_impress.php b/include/class_impress.php new file mode 100644 index 000000000..438e0b851 --- /dev/null +++ b/include/class_impress.php @@ -0,0 +1,233 @@ +$p_label.' Erreur Formule!', + 'montant'=>0); + else + return $p_formula; + + } + if ( $p_type_date == 0 ) + $cond=sql_filter_per($p_cn,$p_start,$p_end,'p_id','j_tech_per'); + else + $cond="( j_date >= to_date('$p_start','DD.MM.YYYY') and j_date <= to_date('$p_end','DD.MM.YYYY'))"; + include_once("class_acc_account_ledger.php"); + + // while (@ereg("(\[[0-9]*%*D*C*S*\])",$p_formula,$e) == true) + while (preg_match_all("(\[[0-9]*%*D*C*S*\])",$p_formula,$e) == true) + { + + // remove the [ ] + $x=$e[0]; + foreach ($x as $line) + { + $compute='all'; + if ( strpos($line,'D') != 0 ) + $compute='deb'; + if ( strpos($line,'C') != 0 ) + $compute='cred'; + if ( strpos($line,'S') != 0 ) + $compute='signed'; + $line=str_replace ("[","",$line); + $line=str_replace ("]","",$line); + $line=str_replace ("D","",$line); + $line=str_replace ("C","",$line); + $line=str_replace ("S","",$line); + // If there is a FROM clause we must recompute + // the time cond + + if ($p_type_date == 0 && preg_match ("/FROM=[0-9]+\.[0-9]+/", $p_formula,$afrom) == 1 ) + { + // There is a FROM clause + // then we must modify the cond for the periode + $from=str_replace("FROM=","",$afrom[0]); + + // Get the periode + /*! \note special value for the clause FROM=00.0000 + */ + if ( $from == '00.0000' ) + { + + // retrieve the first month of this periode + $User=new User($p_cn); + $user_periode=$User->get_periode(); + $oPeriode=new Periode($p_cn); + $periode=$oPeriode->get_exercice($user_periode); + list($first,$last)=$oPeriode->get_limit($periode); + $ret=$first->get_date_limit(); + $end_date=$oPeriode->get_date_limit($p_end); + if ($ret == null ) throw new Exception ('Pas de limite à cette période',1); + $cond=sql_filter_per($p_cn,$ret['p_start'],$end_date['p_end'],'date','j_tech_per'); + + + } + else + { + $oPeriode=new Periode($p_cn); + try + { + $from=$oPeriode->find_periode('01'.$from); + } + catch (Exception $exp) + { + /* if none periode is found + then we take the first periode of the year + */ + $User=new User($p_cn); + $user_periode=$User->get_periode(); + + $year=$oPeriode->get_exercice($user_periode); + list($first,$last)=$oPeriode->get_limit($year); + $ret=$first->get_date_limit(); + $end_date=$oPeriode->get_date_limit($p_end); + if ($ret == null ) throw new Exception ('Pas de limite à cette période',1); + $cond=sql_filter_per($p_cn,$ret['p_start'],$end_date['p_end'],'date','j_tech_per'); + } + } + } + + if ( strpos($p_formula,"FROM") != 0) + { + // We remove FROM out of the p_formula + $p_formula=substr_replace($p_formula,"",strpos($p_formula,"FROM")); + } + + // Get sum of account + $P=new Acc_Account_Ledger($p_cn,$line); + $detail=$P->get_solde_detail($cond); + + + if ( $compute=='all') + $i=$detail['solde']; + if ( $compute=='deb') + $i=$detail['debit']; + if ( $compute=='cred') + $i=$detail['credit']; + if ( $compute=='signed') + $i=$detail['debit']-$detail['credit']; + $p_formula=str_replace($x[0],$i,$p_formula); + } + } + + // $p_eval is true then we eval and returns result + if ( $p_eval == true) + { + $p_formula="\$result=".$p_formula.";"; + + eval("$p_formula"); + + while (preg_match("/\[([0-9]+)([Tt]*)\]/",trim($p_label),$e) == 1) + { + $nom = "!!".$e[1]."!!"; + if (Impress::check_formula($e[0])) + { + $nom = $p_cn->get_value ( "SELECT pcm_lib AS acct_name FROM tmp_pcmn WHERE pcm_val::text LIKE $1||'%' ORDER BY pcm_val ASC LIMIT 1",array($e[1])); + if($nom) + { + if($e[2] == 'T') $nom = strtoupper($nom); + if($e[2] == 't') $nom = strtolower($nom); + } + } + $p_label = str_replace($e[0], $nom, $p_label); + } + + $aret=array('desc'=>$p_label, + 'montant'=>$result); + return $aret; + } + else + { + // $p_eval is false we returns only the string + return $p_formula; + } + } + /*! + * \brief Check if formula doesn't contain + * php injection + * \param string + * + * \return true if the formula is good otherwise false + */ + static function Impress::check_formula($p_string) + { + // the preg_match gets too complex if we want to add a test + // for parenthesis, math function... + // So I prefer remove them before testing + $p_string=str_replace("round","",$p_string); + $p_string=str_replace("abs","",$p_string); + $p_string=str_replace("(","",$p_string); + $p_string=str_replace(")","",$p_string); + // for the inline test like $a=(cond)?value:other; + $p_string=str_replace("?","+",$p_string); + $p_string=str_replace(":","+",$p_string); + $p_string=str_replace(">=","+",$p_string); + $p_string=str_replace("<=","+",$p_string); + $p_string=str_replace(">","+",$p_string); + $p_string=str_replace("<","+",$p_string); + // eat Space + $p_string=str_replace(" ","",$p_string); + // Remove D/C/S + $p_string=str_replace("C","",$p_string); + $p_string=str_replace("D","",$p_string); + $p_string=str_replace("S","",$p_string); + // Remove T,t + $p_string=str_replace("T","",$p_string); + $p_string=str_replace("t","",$p_string); + + if ( @ereg ("^(\\$[a-zA-Z]*[0-9]*=){0,1}((\[{0,1}[0-9]+\.*[0-9]*%{0,1}\]{0,1})+ *([+-\*/])* *(\[{0,1}[0-9]+\.*[0-9]*%{0,1}\]{0,1})*)*(([+-\*/])*\\$([a-zA-Z])+[0-9]*([+-\*/])*)* *( *FROM=[0-9][0-0].20[0-9][0-9]){0,1}$",$p_string) == false) + { + return false; + } + else + { + return true; + } + } +} +?> diff --git a/include/config.inc b/include/config.inc index 3063a61f5..0400899f7 100644 --- a/include/config.inc +++ b/include/config.inc @@ -36,3 +36,4 @@ define ("phpcompta_psql_port","5432"); // // the domain can't start by a number !!! define ("domaine",""); +define ("LOCALE",1); \ No newline at end of file diff --git a/include/config_file.php b/include/config_file.php index 20428edf8..c230ad762 100644 --- a/include/config_file.php +++ b/include/config_file.php @@ -62,6 +62,7 @@ function config_file_form($p_array=null) $cpasswd='dany'; $cport=5432; $cdomain=''; + $clocal=1; } else extract ($p_array); @@ -76,6 +77,12 @@ function config_file_form($p_array=null) $r.='(?)'; $r.='
'; + $r.='Désactivation changement de langue: '; + $text->title='Désactiver le changement de langue (requis pour MacOSX'; + $r.=$text->input('clocale',$clocale); + $r.='(?)'; + $r.='
'; + $r.='Chemin complet vers les executable de Postgresql : '; $text->title='Le chemin vers le repertoire contenant psql, pg_dump...'; $r.=$text->input('cpath',$cpath); @@ -140,6 +147,9 @@ function config_file_create($p_array,$from_setup=1,$os=1) fputs($hFile, 'define ("phpcompta_psql_host","127.0.0.1");'); fputs($hFile,"\r\n"); + fputs($hFile, 'define ("locale",'.$clocal.');'); + fputs($hFile,"\r\n"); + fputs($hFile, 'define ("domaine","");'); fputs($hFile,"\r\n"); fputs($hFile,'?>'); diff --git a/include/export_bilan_oth.php b/include/export_bilan_oth.php index 3e041c6d9..d0954d564 100644 --- a/include/export_bilan_oth.php +++ b/include/export_bilan_oth.php @@ -22,7 +22,7 @@ * \brief send a Bilan in RTF format */ include_once("ac_common.php"); -include_once("impress_inc.php"); +include_once("class_impress.php"); require_once('class_database.php'); require_once ('header_print.php'); require_once ('class_acc_bilan.php'); diff --git a/include/export_fiche_detail_pdf.php b/include/export_fiche_detail_pdf.php index 806d61829..98e409933 100644 --- a/include/export_fiche_detail_pdf.php +++ b/include/export_fiche_detail_pdf.php @@ -26,7 +26,7 @@ include_once("class_acc_account_ledger.php"); include_once("ac_common.php"); require_once('class_database.php'); -include_once("impress_inc.php"); +include_once("class_impress.php"); require_once("class_fiche.php"); require_once ('header_print.php'); require_once('class_dossier.php'); diff --git a/include/export_form_csv.php b/include/export_form_csv.php index f33267acf..ded1f6697 100644 --- a/include/export_form_csv.php +++ b/include/export_form_csv.php @@ -25,7 +25,7 @@ require_once ("ac_common.php"); require_once('class_database.php'); require_once ('class_user.php'); require_once("class_acc_report.php"); -require_once("impress_inc.php"); +require_once("class_impress.php"); header('Pragma: public'); header('Content-type: application/csv'); header('Content-Disposition: attachment;filename="rapport.csv"',FALSE); diff --git a/include/export_form_pdf.php b/include/export_form_pdf.php index a9e0666dd..b80cf080e 100644 --- a/include/export_form_pdf.php +++ b/include/export_form_pdf.php @@ -27,7 +27,7 @@ include_once("class_acc_report.php"); include_once("ac_common.php"); require_once('class_database.php'); -include_once("impress_inc.php"); +include_once("class_impress.php"); require_once('class_user.php'); require_once ('header_print.php'); require_once('class_dossier.php'); diff --git a/include/export_gl_csv.php b/include/export_gl_csv.php index 2847da25b..8f6635132 100644 --- a/include/export_gl_csv.php +++ b/include/export_gl_csv.php @@ -27,7 +27,7 @@ include_once('class_acc_account_ledger.php'); include_once('ac_common.php'); require_once('class_database.php'); -include_once('impress_inc.php'); +include_once('class_impress.php'); require_once('class_own.php'); require_once('class_dossier.php'); require_once('class_user.php'); diff --git a/include/export_gl_pdf.php b/include/export_gl_pdf.php index 93f8dbb0c..4d820643c 100644 --- a/include/export_gl_pdf.php +++ b/include/export_gl_pdf.php @@ -27,7 +27,7 @@ include_once('class_acc_account_ledger.php'); include_once('ac_common.php'); require_once('class_database.php'); -include_once('impress_inc.php'); +include_once('class_impress.php'); require_once('class_own.php'); require_once('class_dossier.php'); require_once('class_user.php'); diff --git a/include/export_ledger_pdf.php b/include/export_ledger_pdf.php index 9d44d848c..6f1388536 100644 --- a/include/export_ledger_pdf.php +++ b/include/export_ledger_pdf.php @@ -32,7 +32,7 @@ require_once('class_pdf.php'); include_once('class_user.php'); include_once("ac_common.php"); require_once('class_database.php'); -include_once("impress_inc.php"); +include_once("class_impress.php"); include_once("class_acc_ledger.php"); require_once('class_own.php'); require_once('class_periode.php'); diff --git a/include/export_poste_detail_pdf.php b/include/export_poste_detail_pdf.php index a90d3d2e6..88df8c207 100644 --- a/include/export_poste_detail_pdf.php +++ b/include/export_poste_detail_pdf.php @@ -26,7 +26,7 @@ include_once("class_acc_account_ledger.php"); include_once("ac_common.php"); require_once('class_database.php'); -include_once("impress_inc.php"); +include_once("class_impress.php"); require_once ('header_print.php'); require_once('class_dossier.php'); require_once('class_user.php'); diff --git a/include/impress_inc.php b/include/impress_inc.php deleted file mode 100644 index a223a7ce1..000000000 --- a/include/impress_inc.php +++ /dev/null @@ -1,230 +0,0 @@ -$p_label.' Erreur Formule!', - 'montant'=>0); - else - return $p_formula; - - } - if ( $p_type_date == 0 ) - $cond=sql_filter_per($p_cn,$p_start,$p_end,'p_id','j_tech_per'); - else - $cond="( j_date >= to_date('$p_start','DD.MM.YYYY') and j_date <= to_date('$p_end','DD.MM.YYYY'))"; - include_once("class_acc_account_ledger.php"); - - // while (@ereg("(\[[0-9]*%*D*C*S*\])",$p_formula,$e) == true) - while (preg_match_all("(\[[0-9]*%*D*C*S*\])",$p_formula,$e) == true) - { - - // remove the [ ] - $x=$e[0]; - foreach ($x as $line) - { - $compute='all'; - if ( strpos($line,'D') != 0 ) - $compute='deb'; - if ( strpos($line,'C') != 0 ) - $compute='cred'; - if ( strpos($line,'S') != 0 ) - $compute='signed'; - $line=str_replace ("[","",$line); - $line=str_replace ("]","",$line); - $line=str_replace ("D","",$line); - $line=str_replace ("C","",$line); - $line=str_replace ("S","",$line); - // If there is a FROM clause we must recompute - // the time cond - - if ($p_type_date == 0 && preg_match ("/FROM=[0-9]+\.[0-9]+/", $p_formula,$afrom) == 1 ) - { - // There is a FROM clause - // then we must modify the cond for the periode - $from=str_replace("FROM=","",$afrom[0]); - - // Get the periode - /*! \note special value for the clause FROM=00.0000 - */ - if ( $from == '00.0000' ) - { - - // retrieve the first month of this periode - $User=new User($p_cn); - $user_periode=$User->get_periode(); - $oPeriode=new Periode($p_cn); - $periode=$oPeriode->get_exercice($user_periode); - list($first,$last)=$oPeriode->get_limit($periode); - $ret=$first->get_date_limit(); - $end_date=$oPeriode->get_date_limit($p_end); - if ($ret == null ) throw new Exception ('Pas de limite à cette période',1); - $cond=sql_filter_per($p_cn,$ret['p_start'],$end_date['p_end'],'date','j_tech_per'); - - - } - else - { - $oPeriode=new Periode($p_cn); - try - { - $from=$oPeriode->find_periode('01'.$from); - } - catch (Exception $exp) - { - /* if none periode is found - then we take the first periode of the year - */ - $User=new User($p_cn); - $user_periode=$User->get_periode(); - - $year=$oPeriode->get_exercice($user_periode); - list($first,$last)=$oPeriode->get_limit($year); - $ret=$first->get_date_limit(); - $end_date=$oPeriode->get_date_limit($p_end); - if ($ret == null ) throw new Exception ('Pas de limite à cette période',1); - $cond=sql_filter_per($p_cn,$ret['p_start'],$end_date['p_end'],'date','j_tech_per'); - } - } - } - - if ( strpos($p_formula,"FROM") != 0) - { - // We remove FROM out of the p_formula - $p_formula=substr_replace($p_formula,"",strpos($p_formula,"FROM")); - } - - // Get sum of account - $P=new Acc_Account_Ledger($p_cn,$line); - $detail=$P->get_solde_detail($cond); - - - if ( $compute=='all') - $i=$detail['solde']; - if ( $compute=='deb') - $i=$detail['debit']; - if ( $compute=='cred') - $i=$detail['credit']; - if ( $compute=='signed') - $i=$detail['debit']-$detail['credit']; - $p_formula=str_replace($x[0],$i,$p_formula); - } - } - - // $p_eval is true then we eval and returns result - if ( $p_eval == true) - { - $p_formula="\$result=".$p_formula.";"; - - eval("$p_formula"); - - while (preg_match("/\[([0-9]+)([Tt]*)\]/",trim($p_label),$e) == 1) - { - $nom = "!!".$e[1]."!!"; - if (CheckFormula($e[0])) - { - $nom = $p_cn->get_value ( "SELECT pcm_lib AS acct_name FROM tmp_pcmn WHERE pcm_val::text LIKE $1||'%' ORDER BY pcm_val ASC LIMIT 1",array($e[1])); - if($nom) - { - if($e[2] == 'T') $nom = strtoupper($nom); - if($e[2] == 't') $nom = strtolower($nom); - } - } - $p_label = str_replace($e[0], $nom, $p_label); - } - - $aret=array('desc'=>$p_label, - 'montant'=>$result); - return $aret; - } - else - { - // $p_eval is false we returns only the string - return $p_formula; - } -} -/*! - * \brief Check if formula doesn't contain - * php injection - * \param string - * - * \return true if the formula is good otherwise false - */ -function CheckFormula($p_string) -{ - // the preg_match gets too complex if we want to add a test - // for parenthesis, math function... - // So I prefer remove them before testing - $p_string=str_replace("round","",$p_string); - $p_string=str_replace("abs","",$p_string); - $p_string=str_replace("(","",$p_string); - $p_string=str_replace(")","",$p_string); - // for the inline test like $a=(cond)?value:other; - $p_string=str_replace("?","+",$p_string); - $p_string=str_replace(":","+",$p_string); - $p_string=str_replace(">=","+",$p_string); - $p_string=str_replace("<=","+",$p_string); - $p_string=str_replace(">","+",$p_string); - $p_string=str_replace("<","+",$p_string); - // eat Space - $p_string=str_replace(" ","",$p_string); - // Remove D/C/S - $p_string=str_replace("C","",$p_string); - $p_string=str_replace("D","",$p_string); - $p_string=str_replace("S","",$p_string); - // Remove T,t - $p_string=str_replace("T","",$p_string); - $p_string=str_replace("t","",$p_string); - - if ( @ereg ("^(\\$[a-zA-Z]*[0-9]*=){0,1}((\[{0,1}[0-9]+\.*[0-9]*%{0,1}\]{0,1})+ *([+-\*/])* *(\[{0,1}[0-9]+\.*[0-9]*%{0,1}\]{0,1})*)*(([+-\*/])*\\$([a-zA-Z])+[0-9]*([+-\*/])*)* *( *FROM=[0-9][0-0].20[0-9][0-9]){0,1}$",$p_string) == false) - { - return false; - } - else - { - return true; - } -} - -?> diff --git a/sql/upgrade.sql b/sql/upgrade.sql index 2a937f9eb..618374fe7 100644 --- a/sql/upgrade.sql +++ b/sql/upgrade.sql @@ -5,6 +5,7 @@ begin; drop table public.import_tmp; drop table public.format_csv_banque; insert into parameter values ('MY_ALPHANUM','N'); +update PARAMETER set pr_value='N' where pr_id='MY_CHECK_PERIODE'; delete from action where ac_id not in (800,805,910); insert into action (ac_id,ac_description, ac_module, ac_code) values(1020,'Effacer les documents du suivi','followup','RMDOC'); insert into action (ac_id,ac_description, ac_module, ac_code) values(1010,'Voir les documents du suivi','followup','VIEWDOC');