source: trunk/workflow/inc/report/includes/classes/SqlParser.class.php @ 5307

Revision 5307, 6.8 KB checked in by pereira.jair, 12 years ago (diff)

Ticket #2416 - Inclusao da nova ferramenta de relatorios do workflow.

Line 
1<?php
2
3class SqlParser {
4   
5    var $_sql;
6    var $_bloqueios = array(
7        "insert",
8        "update",
9        "delete",
10        //" into [temp]", //DESSA FORMA A EXPRESSÃO INTO É BLOQUEADA MAS SE FOR ACOMPANHADA DA PALAVRA TEMP ENTÃO SERÁ LIBERADA.
11        "drop ",
12        "alter ",
13        "database",
14        "create ",
15        "disable ",
16        "begin",
17        "rollback",
18        "commit",
19        "declare",
20        " abort",
21        "copy",
22        "close",
23        "execute",
24        "grant",
25        "revoke",
26        "reset",
27        "vacuum",
28        "truncate",
29        "cascade",
30                " overlay",
31                "prepare",
32                "dblink",
33                "dblink_exec");
34   
35    var $_erro = "";
36       
37    function SqlParser($sql) {
38        $this->setSql($sql);
39    }
40   
41    protected function procuraPalavra($texto,$palavra,$msgerro) {
42        $achou = "";
43        $palavratemchaves = stristr(strtolower($palavra),"[");
44        if ($palavratemchaves) {
45                $liberado = str_replace(" ","",str_replace("]","",str_replace("[","",$palavra)));
46                $arr = explode("[",$palavra);
47                $bloqueado = $arr[0];
48                $txtsemespacos = strtolower(str_replace(" ","",$texto));
49
50                $achouliberado = stristr($txtsemespacos,$liberado);
51                $achoubloqueio = stristr($texto,$bloqueado);
52               
53                if ($achoubloqueio != "" && $achouliberado != "") {
54                        $achou = "";
55                } else {
56                        if ($achoubloqueio) {
57                                $achou = $achoubloqueio;
58                        }
59                }
60        } else {
61                $achou = stristr(strtolower($texto),$palavra); 
62        }
63        $palavratemparenteses = stristr(strtolower($palavra),"(");
64       
65        if ($palavratemparenteses) {
66                $achou = stristr(strtolower(str_replace(" ","",$texto)),$palavra);
67        }
68        if ($achou!="") {
69            throw new Exception($msgerro);
70        }
71    }
72   
73    public function bloquearPalavra($palavra,$bloquear = true) {
74        if ($bloquear) {
75           array_push($this->_bloqueios,$palavra);
76        } else {
77            $arr = array();
78                foreach($this->_bloqueios as $a) {
79                        if ($a != $palavra) {
80                    array_push($arr,$palavra);
81                }
82                }
83            $this->_bloqueios = $arr;
84        }
85    }
86   
87    function verificaSql() {
88        $ret = false;
89        try {
90            $select = $this->_sql;
91            foreach ($this->_bloqueios as $palavra) {
92                $arr = explode("[",$palavra);
93                $palavrabloqueada = $arr[0];
94                $this->procuraPalavra($select,$palavra,"Por questões de segurança, a palavra: '" . trim(strtoupper($palavrabloqueada)) . "' não é permitida.");
95            }
96           
97            $ret = true;
98           
99        } catch (Exception $e) {
100            $this->_erro = $e->getMessage();
101            $ret = false;
102        }
103        return $ret;
104    }
105   
106    function getErro() {
107        return $this->_erro;
108    }
109   
110    public function setSql($value) {
111        $this->_sql = $value;
112    }
113   
114    public function getSql() {
115        return $this->_sql;
116    }
117   
118    protected function getQuantidadeIfs($texto) {
119        $qtd = 0;
120        for ($i = 0;  $i <= strlen($texto); $i++) {
121            if (strtolower(substr($texto,$i,3)) == "#if") {
122                $qtd = $qtd + 1;
123            }
124        }
125        return $qtd;
126    }
127   
128    protected function numerarCondicao($texto,$num) {
129        $qtd = 0;
130        for ($i = 0;  $i <= strlen($texto); $i++) {
131            if (strtolower(substr($texto,$i,3)) == "#if") {
132                $qtd = $qtd + 1;
133                $condicoesabertas = 1;
134                $condicoesfechadas = 0;
135                if ($qtd == $num) {
136                    for ($j = $i+1;  $j <= strlen($texto); $j++) {
137                       
138                        if ((strtolower(substr($texto,$j,5)) == "#/if#")) {
139                            $condicoesfechadas = $condicoesfechadas + 1;
140                        }
141                       
142                        if ((strtolower(substr($texto,$j,3)) == "#if")) {
143                            $condicoesabertas = $condicoesabertas + 1;
144                        }
145   
146                        if ($condicoesfechadas == $condicoesabertas) {
147                            $condicao = substr($texto,$i,$j-$i+5);
148                            $condicao = "#co$num " . substr($condicao,4,strlen($condicao)-9) . "#/co$num#";
149                            $prefixo = substr($texto,0,$i);
150                            $sufixo = substr($texto,$j+5,strlen($texto));
151                            return $prefixo . $condicao . $sufixo;
152                        }
153                    }
154                }
155               
156            }
157        }
158    }
159   
160    protected function validarCondicao($texto,$num) {
161       
162        try {
163       
164            $inicond = stripos($texto,"#co$num");
165            $endcond = stripos($texto,"#/co$num#");
166            $condicao = substr($texto,$inicond,$endcond-$inicond+6);
167            $conteudo = "";
168           
169            $fincond = stripos(substr($condicao,1,strlen($condicao)),"#");
170            $condeval = substr($condicao,strlen("#co$num"),$fincond-strlen("#co$num")+1); 
171            $condconcat = substr($condicao,$fincond+2,strlen($condicao)-$fincond-strlen("#/co$num#")-2);
172            if ($condeval != "") {
173                $fcondicao = ' if (' . trim($condeval) . ') { $ret = true; } else { $ret = false; }';
174               
175              //  echo $fcondicao . "<br>";
176           
177                if ($this->verificaSintaxe($fcondicao) === false) {
178                    throw new Exception("Impossível validar condição: ( $condeval )");
179                }
180               
181               
182                eval($fcondicao);
183               
184                $prefixo = substr($texto,0,$inicond);
185                $sufixo = substr($texto,$endcond+strlen("#/co$num#"),strlen($texto));
186               
187                if ($ret) {
188                    $conteudo = $condconcat;
189                }
190               
191                $novotexto = $prefixo . $conteudo . $sufixo;
192                $ret = $novotexto;
193            }
194       
195        } catch (Exception $e) {
196            $this->_erro = $e->getMessage();
197            $ret = false;
198        }
199
200        return $ret;
201    }
202   
203    function verificaCondicoes() {
204        $ret = true;
205        $texto = $this->getSql();
206        $novotexto = $this->getSql();
207        $qtdifs = $this->getQuantidadeIfs($texto);
208        for ($i = $qtdifs;  $i >= 1; $i--) {
209           $ftexto = $this->numerarCondicao($novotexto,$i);
210           $novotexto = $ftexto;
211        }
212        for ($i = $qtdifs;  $i >= 1; $i--) {
213           $novotexto = $this->validarCondicao($novotexto,$i);
214           if ($novotexto == false) {
215                  $ret = false;
216           }
217        }
218        $this->setSql($novotexto);
219
220        return $ret;
221    }
222   
223    protected function verificaSintaxe($code) {
224        return @eval('return true;' . $code);
225    }
226   
227}
228
229?>
Note: See TracBrowser for help on using the repository browser.