[RESOLU] Bug preg_match ?

Petit nouveau ! | 2 Messages

07 juil. 2015, 12:24

Bonjour,

Les codes php et perl qui suivent ne donnent pas le même résultat, le 1er test php est erroné !

./bug.php
#.+?End#us : KO
#End#us : Ok

./bug.pl
.+?End : Ok
End : Ok

Est-ce que j'ai loupé qqc ou est-ce un bug php ?

PS : c'est mon 1er message sur ce forum et je n'ai pas trouvé comment attaché le fihier de taille 1Mo ... que je n'arrive pas à réduire plus, 'toutes' autres modifications entrainant la disparition du problème. Cependant j'ai posté le même message avec le fichier sur le forum debian.

Pour info mon système : Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
#!/usr/bin/php
<?php 

$contenu=file_get_contents('bug.txt');


function test($filtre) {
	global $contenu;
	echo $filtre," : ";
	if ( preg_match($filtre,$contenu) ) echo "Ok\n"; else echo "KO\n";
} 

test("#.+?End#us");
test("#End#us");
?>

Code : Tout sélectionner

#!/usr/bin/perl use strict; our $contenu=''; sub test { my $filtre=shift; print $filtre." : "; if ( $contenu =~ /$filtre/us ) { print "Ok\n"; } else { print "KO\n"; } } open(FIC, 'bug.txt'); while (<FIC>) { $contenu.=$_; } test(".+?End"); test("End");

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

07 juil. 2015, 13:59

Alors ça c'est un bug intéressant et pas commun... :)

Le fichier bug.txt est dispo ici : https://www.debian-fr.org/ressources/file/3612

En supprimant 5 caractères de ton fichier, ça fonctionne, en en supprimant 4 ça bloque :
- Pas de problème : 1 001 686 octets
- Problème : 1 001 687 octets
Quand tout le reste a échoué, lisez le mode d'emploi...

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

07 juil. 2015, 14:12

J'ai modifié ton code pour avoir les messages d'erreur de preg :
<?php 

$contenu=file_get_contents('bug.txt');

function test($filtre) {
  global $contenu;
  echo $filtre," : ";
  if ( preg_match($filtre,$contenu) ) echo "Ok\n"; else echo "KO : ".array_flip(get_defined_constants(true)['pcre'])[preg_last_error()]."\n";
} 

test("#.*?End#us");
test("#End#us");
Le message d'erreur obtenu est "PREG_BACKTRACK_LIMIT_ERROR" et après pas mal de recherche, j'ai trouvé une solution grâce à Moodle et Mediawiki qui ont été confrontés au même problème :)


La solution est donc d'augmenter le paramètre pcre.backtrack_limit avec la commande suivante à mettre en haut de ton fichier PHP :
ini_set( 'pcre.backtrack_limit', '2M' );
Et là... magie, ça marche ! :)
Quand tout le reste a échoué, lisez le mode d'emploi...

Petit nouveau ! | 2 Messages

07 juil. 2015, 20:35

@rthur merci pour ta réponse, j'imaginais un truc du genre mais n'avais pas eu le temps de fouiller plus ...

La cause est donc bien expliquée et pour moi, la 1ère solution est surtout de tester :
if ( False===preg_match .... ) ce que je n'ai pas fait ! ( erreur de débutant )