#21389 [NEW]: preg_match crash after some calls
| From: | gregoire dot roland at edfgdf dot fr | Date: | Fri, 03 Jan 2003 12:46:13 +0000 |
| Subject: | #21389 [NEW]: preg_match crash after some calls | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-28970@lists.php.net to get a copy of this message | ||
From: gregoire.roland@edfgdf.fr
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