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