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

problème script cgi: Time::Local renvoie un tas d'erreurs

12 réponses
Avatar
gvdmoort
Bonjour =E0 tous,

J'ai un script qui fait appel =E0 Time::Local pour convertir un temps au
format YYYYMMDD en epoch et permettre des comparaisons entre des dates.

sub get_time {
$_[0]=3D~/(....)(..)(..)/;
$year =3D $1;
$month =3D $2;
$day =3D $3;
$date=3Dtimelocal(0,0,12,$day, $month-1, $year-1900);
# pour d=E9bugguer (voir le r=E9sultat plus loin) :
print STDERR "$year $month $day\n$date\n";
return $date;
}

Malheureusement, chaque appel =E0 cette fonction entra=EEne l'envoi de
ces messages vers STDERR:

Use of uninitialized value in integer addition (+) at
C:/perl/lib/Time/Local.pm line 76, <INDEX> line 393.
Use of uninitialized value in integer multiplication (*) at
C:/perl/lib/Time/Local.pm line 76, <INDEX> line 393.
Use of uninitialized value in integer multiplication (*) at
C:/perl/lib/Time/Local.pm line 76, <INDEX> line 393.
Use of uninitialized value in pack at C:/perl/lib/Time/Local.pm line
67, <INDEX> line 393.
Use of uninitialized value in pack at C:/perl/lib/Time/Local.pm line
67, <INDEX> line 393.
Use of uninitialized value in integer addition (+) at
C:/perl/lib/Time/Local.pm line 67, <INDEX> line 393.
2006 04 26
1146046210


Comme la comparaison s'effectue sur quelques centaines de dates, =E7a
fait quelques milliers de lignes d'erreur =E0 chaque fois.

Il semble que la sortie d'erreur standard soit redirig=E9e vers la
sortie standard pour les scripts CGI, en tout cas, la page s'affiche en
entrem=EAlant le code html normal et ces lignes d'erreur, et apr=E8s un
temps d=E9sesp=E9r=E9ment long. J'ai tent=E9 de rediriger les erreurs vers
un fichier :

open (STDERR,">errors.txt");

ce qui rend au script son temps d'ex=E9cution normal, mais il tourne
sur un serveur Windows, environnement auquel je ne connais rien, je le
confesse, et les visiteurs qui n'ont pas acc=E8s en =E9criture sur ce
r=E9pertoire ne peuvent cr=E9er ce fichier (on est dans l'intranet d'une
entreprise), et =E7a coince tout autant.

Quelqu'un a-t-il une id=E9e de l'origine de ces erreurs, et si elles ne
peuvent =EAtre r=E9solues, faute de mieux,
y aurait-il une grosse ficelle correspondant par exemple =E0 une
redirection vers /dev/null pour en =EAtre quitte ?

Merci d'avance,

G=2E

10 réponses

1 2
Avatar
Paul Gaborit
À (at) 27 Apr 2006 08:31:02 -0700,
écrivait (wrote):
J'ai un script qui fait appel à Time::Local pour convertir un temps au
format YYYYMMDD en epoch et permettre des comparaisons entre des dates.

sub get_time {
$_[0]=~/(....)(..)(..)/;
$year = $1;
$month = $2;
$day = $3;
$date=timelocal(0,0,12,$day, $month-1, $year-1900);
# pour débugguer (voir le résultat plus loin) :
print STDERR "$year $month $dayn$daten";
return $date;
}

Malheureusement, chaque appel à cette fonction entraîne l'envoi de
ces messages vers STDERR:

Use of uninitialized value in integer addition (+) at
C:/perl/lib/Time/Local.pm line 76, <INDEX> line 393.


Rien ne vous garantit que l'expression régulière/rationnelle a été
reconnue ! Et si ce n'est pas le cas, $1, $2 et $3 peuvent contenir la
valuer 'undef'. Donc :

if ($_[0] =~ m/(d{4})(d{2})(d{2})/) {
$year = $1;
$month = $2;
$day = $3;
# ... et la suite ...
} else {
# ?? Il n'y avait pas de date dans $_[0]
}

Pour le problème de 'STDERR', il faut voir le configuration de serveur
Web et savoir comment il interagit avec un script CGI...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
gvdmoort
Vous avez sans doute raison de m'indiquer une façon plus stricte de
gérer l'expression régulière/rationnelle, mais dans ce cas
précis, c'est bien pour vérifier ça que j'ai intercalé la ligne de
débuggage

print STDERR "$year $month $dayn$daten";

et il s'avère que l'expression a été reconnue dans TOUS les cas mais
que les erreurs apparaissent cependant.

Merci quand même

G.
Avatar
gvdmoort
Suite des investigations...

Les messages d'erreur précédemment cités disparaissent totalement
lorsque j'utilise l'heure gmt au lieu de l'heure locale:

$date=timegm(0,0,12,$day, $month-1, $year-1900);

Faudrait-il spécifier le fuseau horaire pour pouvoir utiliser l'heure
locale ?

G.
Avatar
gvdmoort
Encore moi...

Pour résoudre les problèmes liés aux messages d'erreur, comment
faire pour rediriger STDERR vers STDOUT ?

Serait-il possible, avant de faire cette redirection, d'exécuter un
traitement sur ces chaînes (reformattage via regexp par ex.)

Merci d'avance,

G.
Avatar
Paul Gaborit
À (at) 27 Apr 2006 12:51:07 -0700,
écrivait (wrote):
Vous avez sans doute raison de m'indiquer une façon plus stricte de
gérer l'expression régulière/rationnelle, mais dans ce cas
précis, c'est bien pour vérifier ça que j'ai intercalé la ligne de
débuggage

print STDERR "$year $month $dayn$daten";

et il s'avère que l'expression a été reconnue dans TOUS les cas mais
que les erreurs apparaissent cependant.


Ok. Je n'avais pas lu tout jusqu'au bout...


--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) 28 Apr 2006 00:44:02 -0700,
écrivait (wrote):
Suite des investigations...

Les messages d'erreur précédemment cités disparaissent totalement
lorsque j'utilise l'heure gmt au lieu de l'heure locale:

$date=timegm(0,0,12,$day, $month-1, $year-1900);

Faudrait-il spécifier le fuseau horaire pour pouvoir utiliser l'heure
locale ?


La piste du fuseau horaire est sûrement une bonne piste. Je ne sais
pas comment se comporte Windows de ce point de vue. Y a-t-il une
valeur par défaut ? Cette machine a-t-elle un fuseau horaire défini
quelque part ? Le serveur Web définit-il cette variable ? Je n'ai pas
de Windows sous la main pour tester...

Sinon il y a beaucoup de choses à vérifier. La première chose est
d'aller voir le code de votre version de Time::Local aux lignes 67 et
76 pour voir ce qui peut clocher (ma version de Time::Local contient
une simple accolade à la ligne 67.). Vous pouvez alors y ajouter du
code de debug pour savoir exactement quelles sont les variables non
définies et voir d'où elles proviennent.

Vous pouvez aussi utiliser le module POSIX et sa fonction 'mktime'
(pour tester une autre fonction de conversion) ainsi que 'tzname' et
'tzset' pour vérifier ou positionner la timezone.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) 28 Apr 2006 01:20:24 -0700,
écrivait (wrote):
Pour résoudre les problèmes liés aux messages d'erreur, comment
faire pour rediriger STDERR vers STDOUT ?


Ce n'est pas l'idéal pour un script CGI. STDOUT est le document
produit (précédé de l'en-tête HTTP). Aucune raison que les messages
d'erreurs se retrouvent dans le document lui-même (surtout s'ils
apparaissent avant l'envoi de l'en-tête HTTP). Mais on peut faire des
choses sympas grâce au module CGI::Carp.

Serait-il possible, avant de faire cette redirection, d'exécuter un
traitement sur ces chaînes (reformattage via regexp par ex.)


On peut installer un "handler" via %SIG (décrit dans perlvar). Par
exemple, pour transformer tous les warnings en erreurs :

$SIG{__WARN__} = sub { die $_[0] };

Ou pour afficher tous les warnings sur STDOUT précédés du mot
"WARNING" et placés dans une balise <PRE>:

$SIG{__WARN__} = sub {
print "<PRE>WARNING: $_[0]</PRE>";
};

Mais ce n'est pas propre...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
jl_morel
Dans l'article ,
a dit...


À (at) 28 Apr 2006 00:44:02 -0700,
écrivait (wrote):
Suite des investigations...

Les messages d'erreur précédemment cités disparaissent totalement
lorsque j'utilise l'heure gmt au lieu de l'heure locale:

$date=timegm(0,0,12,$day, $month-1, $year-1900);

Faudrait-il spécifier le fuseau horaire pour pouvoir utiliser l'heure
locale ?


La piste du fuseau horaire est sûrement une bonne piste. Je ne sais
pas comment se comporte Windows de ce point de vue. Y a-t-il une
valeur par défaut ? Cette machine a-t-elle un fuseau horaire défini
quelque part ? Le serveur Web définit-il cette variable ? Je n'ai pas
de Windows sous la main pour tester...

Sinon il y a beaucoup de choses à vérifier. La première chose est
d'aller voir le code de votre version de Time::Local aux lignes 67 et
76 pour voir ce qui peut clocher (ma version de Time::Local contient
une simple accolade à la ligne 67.). Vous pouvez alors y ajouter du
code de debug pour savoir exactement quelles sont les variables non
définies et voir d'où elles proviennent.



Semble être un bug sous Windows avec Perl 5.8 (Time::Local 1.10)
mais pas sous Perl 5.6 (pas de numéro de version pour Time::Local)
À noter que la dernière version 1.12 ne passe pas tous les tests sous Windows.
(Il faut que j'investigue davantage, je n'arrive pas à localiser les
variables non définies avec des print. Il faut que je regarde sous debug)

F:temp>perl58 -w -MTime::Local -e "print timelocal(0,0,12,1,4,106)"
Use of uninitialized value in integer addition (+) at C:/aperl58/lib/Time/Local.
pm line 76.
Use of uninitialized value in integer multiplication (*) at C:/aperl58/lib/Time/
Local.pm line 76.
Use of uninitialized value in integer multiplication (*) at C:/aperl58/lib/Time/
Local.pm line 76.
Use of uninitialized value in pack at C:/aperl58/lib/Time/Local.pm line 67.
Use of uninitialized value in pack at C:/aperl58/lib/Time/Local.pm line 67.
Use of uninitialized value in integer addition (+) at C:/aperl58/lib/Time/Local.
pm line 68.
Use of uninitialized value in integer addition (+) at C:/aperl58/lib/Time/Local.
pm line 69.
Use of uninitialized value in integer addition (+) at C:/aperl58/lib/Time/Local.
pm line 67.
1146477600
F:temp>
F:temp>perl56 -w -MTime::Local -e "print timelocal(0,0,12,1,4,106)"
1146477600


--
J-L.M.
http://www.bribes.org/perl


Avatar
gvdmoort
Merci pour vos recherches. La version win de Perl en question est la
5.008006 (valeur renvoyée par $] ), et il y a dû y avoir un upgrade
parce que ce script n'est pas récent et ne posait pas de problèmes
auparavant. Le problème est que les gens qui gèrent (hmm...) ce
serveur ne connaissent rien à Perl qui y a un peu le statut d'un
sans-papier.

Chez moi, sur une vieille Linux/Slackware9.1 avec perl-5.8.0, je n'ai
pas ce problème.
Avatar
Paul Gaborit
À (at) 28 Apr 2006 09:41:06 GMT,
(Jean-Louis MOREL) écrivait (wrote):
Semble être un bug sous Windows avec Perl 5.8 (Time::Local 1.10)
mais pas sous Perl 5.6 (pas de numéro de version pour Time::Local)

À noter que la dernière version 1.12 ne passe pas tous les tests
sous Windows. (Il faut que j'investigue davantage, je n'arrive pas
à localiser les variables non définies avec des print. Il faut que
je regarde sous debug)


En tous cas, le bug a déjà été rencontré... et corrigé dans la version
1.11 :

<http://rt.cpan.org/Public/Bug/Display.html?id016>

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

1 2