From:             [EMAIL PROTECTED]
Operating system: Windows NT 4 sp6a french
PHP version:      4.3.0
PHP Bug Type:     Reproducible crash
Bug description:  preg_match crash after some calls

PHP WIN32 4.3.0 + APACHE 2.2.43 + WINNT 4 SP6A FR

Does a DrWatson (Stack OverFlow)


The Script :

<?php


class pcode_analyzer {

        var $fichier_export;            /* Fichier d'entrée d'export du pcode */

        var $fichier_sql;                       /* Fichier généré des appel sql */
        var $fichier_appel;                     /* Fichier généré des appel de 
fonction */
        var $fichier_definition;        /* Fichier généré des définitions de fonction
*/
        var $debug;                                     /* Variable de debugage */

        /* 
         * Constructeur
         * Parametres :
         *              $_f_export : Fichier d'entrée d'export du pcode
         *              $_f_sql    : Fichier généré des appel sql
         *      $_f_appel  : Fichier généré des appel de fonction
         *      $_f_def    : Fichier généré des définitions de fonction
         */
        function pcode_analyzer ($_f_export, $_f_sql, $_f_appel, $_f_def,
$_debug) {       

                $this->fichier_export     = $_f_export;
                $this->fichier_sql        = $_f_sql;
                $this->fichier_appel      = $_f_appel;
                $this->fichier_definition = $_f_def;
                
                $this->debug = $_debug;
                
        }

        function trace($s) {
                if ($this->debug) {
                        echo "==> Trace : $s <==<br>";
                        flush;  
                }
        }
        
        /*
         * Fonction extrait_sql : Extrait le code SQL d'une instruction PCode
SQLExec
         * Parametre :
         *              $code : une instruction Pcode
         */  
        function extrait_sql(&$code) {

                $this->trace("Avant extrait_sql");
                $regs = array();
                /*
                 * Matche la chaine sqlexec(" et récupère la chaine jusqu'a "
                 */
                $this->trace("$code");
/* =============== Crash Here ===================*/             
if (preg_match('/sqlexec\(\"(.*?)\"/i',$code,$regs)) {
                                echo "sql : $regs[1]<br>";
                }
                
                $this->trace("Après extrait_sql");
        }       

        /*
         * Fonction extrait_fonction : Extrait le nom des fonction déclaré 
         *                                                         et utilisé dans une 
liste d'instruction Pcode
         * Parametres :
         *              $instruction : Liste des instructions Pcode
         *              $code        : Instruction Pcode à analyser
         */ 
        function extrait_fonction(&$instruction,&$code) {
                
                $this->trace("Avant extrait_fonction");
                
                /*
                 * Matche le declare et le peoplecode dans l'instruction à analyser
                 * et récupére le prototype de la fonction
                 */ 
                if (preg_match("/declare (.*) peoplecode (.*)/i",$code,$regs)) {
                        /*
                         * Match le mot clef function et recupere
                         * le nom de la fonction
                         */
                        preg_match("/function (.*)\(/i",$regs[1],$nom);
                        /*
                         * Verifie pour chaque instruction si le nom précedement 
trouvé
                         * est utilisé dans les instructions Pcode, en ignorant la 
ligne de
déclaration
                         */  
                        foreach ($instruction as $key => $value) {
                                if (!preg_match("/declare (.*) peoplecode 
(.*)/i",$value) &&
preg_match("/" . $nom[1] . "/i",$value)) {
                                    $use = true;
                                        break;
                                }
                        }
                        if ($use) {
                            echo "fct : $regs[2] => $regs[1] => $nom[1]<br>";
                        }
                }
                
                $this->trace("Après extrait_fonction");
        }

        /* 
         * Fonction analyse_definition : analyse la définition d'une fonction
         * Parametre : 
         *              $definition : Liste d'instruction Pcode contenant la 
definition de
fonction
         */ 
        function analyse_definition (&$definition) {

                $this->trace("Avant analyse_definition");
                
                /*
                 * Macthe les mots clefs "declare fonction " et recupère le nom de 
                 *  la fonction analysée
                 */ 
                preg_match("/declare function (.*?) /i",$definition[0],$regs);
                echo "fct : $regs[1]<br>";
                
                /*
                 *  Extrait le SQL sur chaque instruction de la définition
                 */ 
                foreach($definition as $key => $val) {
                        $this->extrait_sql($val);
                }
        
                $this->trace("Après analyse_definition");
        }       
        
        
        /*
         * Fonction efface_commenataire : efface les commentaire du Pcode
         * Parametre : 
         *              $code : chaine de Pcode
         */ 
        function efface_commentaire(&$code) {

                $this->trace("Avant efface_commentaire");
                
                /*
                 *  Tant que les commentaire sont matché :
                 */ 
                while (preg_match("/(\/\*((.|\n)+?)\*\/)/i",$code,$reg)) {
                        /*
                         *  Remplace les commentaire par chaine vide
                         */ 
                        $code = preg_replace('/(\/\*((.|\n)+?)\*\/)/','',$code);
                }

                $this->trace("Apres efface_commentaire");
        }       
        
        
        /* 
         * Fonction analyse_evenement : analyse le code d'un evenement Pcode
         * Parametres :
         *              $record : Record de l'evenement
         *              $field  : Champ de l'evenement
         *              $event  : nom de l'evenement
         *              $code   : Code de l'evenement
         */
        function analyse_evenement (&$record, &$field, &$event, &$code) {

                $this->trace("Debut Analyse Evenement [$record.$field.$event]");
                
                /*
                 * Efface les commentaires du code
                 */ 
                $this->efface_commentaire($code);           
                
                /*
                 * Sépare le code en instruction suivant les points virgules
                 * On cree le tableau instruction sans def
                 */ 
                $this->trace("Avant split");
                $instruction = split(";",$code);                
                $instruction_sans_def = $instruction;
                $this->trace("Après efface_commentaire");
                /*
                 * Pour chaque instructions :
                 */ 
                foreach ($instruction as $key => $val) {
                        /*
                         * Si on matche le mot clef "declare"
                         * c'est peut être un début de définition de fonction
                         */ 
                        if (preg_match("/declare/i",$val,$regs)) {
                                $def = array();
                                /*
                                 * On stocke les instructions dans un tableau 
contenant les
instructions
                                 * de définition
                                 */ 
                                array_push($def,$val);
                                /*
                                 * Pour chaque instruction suivante
                                 */ 
                                for($i = $key + 1; $i < sizeof($instruction); ++$i) {
                                        /*
                                         * On stocke l'instruction dans le tableau de 
definition
                                         */ 
                                        array_push($def,$instruction[$i]);
                                        
                                        /*
                                         *  Si on matche un declare, ce n'etait pas 
une definition
                                         */
                                        if (preg_match("/declare/i",$instruction[$i])) 
{
                                                break;
                                        }       
                                        
                                        /*
                                         * Si on matche un end-fun c'est une 
definition, on l'analyse
                                         * et on la supprime du tableau 
instruction_sans_def
                                         */ 
                                        if (preg_match("/end-fun/i",$instruction[$i])) 
{
                                                $this->analyse_definition($def);
                                                $instruction_sans_def = 
array_diff($instruction_sans_def,$def);
                                                break;
                                        }
                                }
                        }
                }
                
                /*
                 * On extrait le SQL et les declaration de fonction du reste des
instructions
                 */ 
                foreach ($instruction_sans_def as $key => $val) {
                        $this->extrait_sql($val);
                        $this->extrait_fonction($instruction,$val);
                }       
                        
                $this->trace("Fin Analyse Evenement");
        }
        
        /*
         * Fonction analyse : analyse le fichier d'export du pcode 
         * 
         */
        function analyze () {   
                
                $this->trace("<b>Debut Analyse</b>");
                
                /*
                 * Ouvre le fichier d'export du pcode
                 */
                $fin  = fopen($this->fichier_export, "r");
                
                /*
                 *  Lit la premiere ligne du fichier
                 */ 
                $buffer = fgets($fin);
                do {
                        $evt = "";      
                        /* 
                         * Début de evt : recupérer les lignes du fichier jusqu'au 
record
prochain
                         * Matche la chaine record.field.event => début d'evenement
                         */ 
                        if (preg_match("/\[(\S+)\.(\S+)\.(\S+)\]/i",$buffer,$regs)) {
                                $buffer = "";
                                /*
                                 *  Lit l'evenement jusqu'au suivant
                                 */ 
                                do {
                                        $evt .= $buffer; 
                                        $buffer = fgets($fin);
                                } while(!feof($fin) &&
!preg_match("/\[(\S+)\.(\S+)\.(\S+)\]/i",$buffer));     
                                /*
                                 * Effectue l'analyse de l'evenement ssi perimetre IEG 
(record
commençant par "EG_"
                                 */ 
                                if ( strtoupper(substr($regs[1],0,3)) == "EG_") {
                                        $this->analyse_evenement($regs[1], $regs[2], 
$regs[3], $evt);
                                }
                        }
                } while(!feof($fin));
                fclose($fin);
                
                $this->trace("<b>Fin Analyse</b>");
                
        }
                
}


$pa = new pcode_analyzer("export_pcode.txt","","","",true);
$pa->analyze();



-- 
Edit bug report at http://bugs.php.net/?id=21389&edit=1
-- 
Try a CVS snapshot:         http://bugs.php.net/fix.php?id=21389&r=trysnapshot
Fixed in CVS:               http://bugs.php.net/fix.php?id=21389&r=fixedcvs
Fixed in release:           http://bugs.php.net/fix.php?id=21389&r=alreadyfixed
Need backtrace:             http://bugs.php.net/fix.php?id=21389&r=needtrace
Try newer version:          http://bugs.php.net/fix.php?id=21389&r=oldversion
Not developer issue:        http://bugs.php.net/fix.php?id=21389&r=support
Expected behavior:          http://bugs.php.net/fix.php?id=21389&r=notwrong
Not enough info:            http://bugs.php.net/fix.php?id=21389&r=notenoughinfo
Submitted twice:            http://bugs.php.net/fix.php?id=21389&r=submittedtwice
register_globals:           http://bugs.php.net/fix.php?id=21389&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=21389&r=php3
Daylight Savings:           http://bugs.php.net/fix.php?id=21389&r=dst
IIS Stability:              http://bugs.php.net/fix.php?id=21389&r=isapi
Install GNU Sed:            http://bugs.php.net/fix.php?id=21389&r=gnused

Reply via email to