Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Bug des expressions régulières ?

4 réponses
Avatar
Jogo
Salut,

Il m'est arrivé un truc étrange. Je me suis retrouvé avec un bug où
tout ce que je voyais était une mort du processus avec $? à 11.
Première question : Est-ce qu'un $SIG{__DIE__} aurait pu afficher
quelquechose ? Sinon comment tracer ce genre de problème ?

Bon alors j'ai tenté d'ajouter un $SIG{__DIE__} et autres logs de
débugage, et je tombe sur l'expression régulière suivante :
/^((?:[^\015]|\015[^\012])*)\015\012.*/

Comme je ne trouve pas ça très joli, je le remplace par
/^(.*?)\015\012/. Et depuis plus de bug. Donc deuxième question :
Est-il possible que le moteur d'expression régulière ait bugué avec
l'expression régulière précédente appliquée à une chaine de caractère
relativement longue (plus de 30000 caractères) et peut-être un peu
perverse ?

Bon, et puisqu'il est question d'expression régulière, une dernière
question : Est-ce une bonne pratique d'ajouter systématiquement le
modificateur o à toutes les expressions régulières constantes ?

Merci beaucoup,

--
La douleur me prive de ma chair, comme le plaisir me la donne.
- Jean-Luc Marion - Le phénomène érotique -

4 réponses

Avatar
Paul Gaborit
À (at) Mon, 2 Feb 2009 22:33:43 +0100,
Jogo écrivait (wrote):
Il m'est arrivé un truc étrange. Je me suis retrouvé avec un bug où
tout ce que je voyais était une mort du processus avec $? à 11.



Manque de mémoire... ?

Première question : Est-ce qu'un $SIG{__DIE__} aurait pu afficher
quelquechose ? Sinon comment tracer ce genre de problème ?



Peut-être... mais pas sûr. Je n'ai jamais testé.

Bon alors j'ai tenté d'ajouter un $SIG{__DIE__} et autres logs de
débugage, et je tombe sur l'expression régulière suivante :
/^((?:[^15]|15[^12])*)1512.*/



Heu... Avec des [...], c'est bizarre !

Comme je ne trouve pas ça très joli, je le remplace par
/^(.*?)1512/. Et depuis plus de bug. Donc deuxième question :
Est-il possible que le moteur d'expression régulière ait bugué avec
l'expression régulière précédente appliquée à une chaine de caractère
relativement longue (plus de 30000 caractères) et peut-être un peu
perverse ?



Le moteur de regexp peut faire exploser la mémoire... Mais avec les
regpexp ci-dessus, ça m'étonnerait quand même.

Bon, et puisqu'il est question d'expression régulière, une dernière
question : Est-ce une bonne pratique d'ajouter systématiquement le
modificateur o à toutes les expressions régulières constantes ?



Ça ne sert strictement à rien si l'expression rationnelle ne contient
aucune variable...


--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Avatar
Jogo
Sur fr.comp.lang.perl, Paul Gaborit disait :

> Il m'est arrivé un truc étrange. Je me suis retrouvé avec un bug où
> tout ce que je voyais était une mort du processus avec $? à 11.

Manque de mémoire... ?



J'avais d'abord pensé à un buffer overflow. C'est pour ça que je peux
affirmer que le scalaire sur lequel est appliquée la regex faisait
entre 25 et 60 Ko. Mais Perl peut gérer de bien plus gros scalaire,
non ?


> Première question : Est-ce qu'un $SIG{__DIE__} aurait pu afficher
> quelquechose ? Sinon comment tracer ce genre de problème ?

Peut-être... mais pas sûr. Je n'ai jamais testé.



La réponse est non. À la limite un $SIG{SEGV} ;)


> Bon alors j'ai tenté d'ajouter un $SIG{__DIE__} et autres logs de
> débugage, et je tombe sur l'expression régulière suivante :
> /^((?:[^15]|15[^12])*)1512.*/

Heu... Avec des [...], c'est bizarre !



Qu'est-ce qui est bizarre ? Ma regex ou qu'elle fasse buguer ?


Le moteur de regexp peut faire exploser la mémoire... Mais avec les
regpexp ci-dessus, ça m'étonnerait quand même.



Dans quels cas cela explose ?


> Est-ce une bonne pratique d'ajouter systématiquement le
> modificateur o à toutes les expressions régulières constantes ?

Ça ne sert strictement à rien si l'expression rationnelle ne contient
aucune variable...



Voilà, merci beaucoup.


--
Il ne faut pas croire, mais Michel a parfois tendance à manier le
second degré (et même plus) l'air de rien. Où à forcer le trait pour
faire passer une idée.
-- F. Senault dans fufe - Où ça ? --
Avatar
Paul Gaborit
À (at) Mon, 2 Feb 2009 23:35:43 +0100,
Jogo écrivait (wrote):
Sur fr.comp.lang.perl, Paul Gaborit disait :

> Il m'est arrivé un truc étrange. Je me suis retrouvé avec un bug où
> tout ce que je voyais était une mort du processus avec $? à 11.

Manque de mémoire... ?



J'avais d'abord pensé à un buffer overflow. C'est pour ça que je peux
affirmer que le scalaire sur lequel est appliquée la regex faisait
entre 25 et 60 Ko. Mais Perl peut gérer de bien plus gros scalaire,
non ?



Oui. Sans aucun problème.

> Première question : Est-ce qu'un $SIG{__DIE__} aurait pu afficher
> quelquechose ? Sinon comment tracer ce genre de problème ?

Peut-être... mais pas sûr. Je n'ai jamais testé.



La réponse est non. À la limite un $SIG{SEGV} ;)

> Bon alors j'ai tenté d'ajouter un $SIG{__DIE__} et autres logs de
> débugage, et je tombe sur l'expression régulière suivante :
> /^((?:[^15]|15[^12])*)1512.*/

Heu... Avec des [...], c'est bizarre !



Qu'est-ce qui est bizarre ? Ma regex ou qu'elle fasse buguer ?



C'est censé servir à quoi ?

(ça m'étonerait que ce soit la regexp qui fasse planter perl..)

Le moteur de regexp peut faire exploser la mémoire... Mais avec les
regpexp ci-dessus, ça m'étonnerait quand même.



Dans quels cas cela explose ?



Si le nombre de truc à mémoriser est trop gros et trop long...

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Avatar
Jogo
Sur fr.comp.lang.perl, Paul Gaborit disait :

/^((?:[^15]|15[^12])*)1512.*/



Heu... Avec des [...], c'est bizarre !



Qu'est-ce qui est bizarre ? Ma regex ou qu'elle fasse buguer ?



C'est censé servir à quoi ?



Ben c'est un bête getline. Corrigé (et résumé) ça donne :

sub getline {
my $tmp ;
my $sz ;

while (1) {
if ($buff =~ /^(.*?)1512/) {
$tmp = $1 ;
$buff = substr($buff,length($tmp)+2) ;
return $tmp ;
} ;

select($tmp = $rin, undef, undef, $timeout))
or return undef;
$sz = pack("L",0) ;
$tmp = ioctl($fh,FIONREAD,$sz) ;
$sz = unpack("L",$sz) ;
sysread($state->{'fhin'},$tmp,$sz))
or return undef;
$buff .= $tmp ;
}
}

J'ai réinventé la roue pour avoir exactement cette gestion là du
timeout, et parce que ça ne me semblait plus rapide à implémenter que
de trouver la bonne roue.

(ça m'étonerait que ce soit la regexp qui fasse planter perl..)



Pourtant je n'ai corrigé que ça et ça marche depuis plus de 24 heures
alors que ça plantait toutes les 30 secondes...

Il s'agit de perl 5.8.8.

--
Don't smoke the next cigarette. Repeat.