Sortie de Perl 5.30.0

Posté par . Édité par ZeroHeure, palm123, thomasv, Davy Defaud, Nils Ratusznik, Ysabeau, Benoît Sibaud et M5oul. Modéré par ZeroHeure. Licence CC by-sa.
Tags :
46
9
juil.
2019
Perl

Perl est un langage généraliste crée en 1987 par Larry Wall. « Perl continue de prospérer dans sa troisième décennie grâce à une communauté d’utilisateurs et de développeurs très dynamique. », dixit perldelta. Perl est distribué sous une double licence : Artistic Licence et GPL v1+. La plupart des modules du CPAN suivent également ce même traitement.
Perl 5 raptor  Perl 5 raptor de kraih, licence CC-BY-SA 4.0

En 2010, on parlait de « Perl moderne » pour mettre en évidence la modernisation du langage et des pratiques autour de celui‐ci (dans le livre Modern Perl, ainsi que Perl Moderne, écrit par trois mongueurs français, ou encore le module Modern::Perl). Nous sommes probablement à présent dans l’ère « post‐moderne de Perl » :-)

Un certain nombre de dépêches ont été postées sur LinuxFr.org à propos des évolutions du langage.

N. D. M. : cette longue dépêche a été scindée en deux : l’abondante bibliographie est dans une dépêche séparée.

Sommaire

Le développement de Perl

Précédentes dépêches sur les sorties des versions de Perl

Autres versions de Perl

  • Perl 6 le 25 décembre 2015. Attention Perl 6 n'est pas Perl 5 et la comparaison entre Python 3/Perl 6 et Python 2/ Perl 5 ne tient pas ;).
  • Perl 5.24 en 2016.
  • Perl 5.26 en 2017.
  • Perl 5.28 en 2018.
  • Perl 5.30 en 2019.

(une version majeure par an, lien Wikipédia sur l'historique des versions de Perl)

Perl 6… Eh bien c'est compliqué… Perl 6 est trop loin de Perl 5 pour être vraiment la version suivante de Perl 5. Et certains ont demandé à changer le nom de Perl 6. Et Larry Wall a accepté en donnant l'alias Raku (du nom de la machine virtuelle). La machine virtuelle n'est plus Parrot ni pugs, mais Rakudo (qui est en fait la continuité/spécialisation de Parrot pour Perl 6).

Releasing flow

Comme on peut le voir sur la page d'historique des versions de Perl (ou mieux dans perlhist), le versioning de Perl a changé au cours des années. De 5.000 a 5.005 puis la version suivante est devenue 5.6.0. À partir de la 5.10.0 les releases sont devenues annuelles et une version avec un mineur impair est une version de dev. Rappel Perl 5.10.0 est donc Perl Majeur.Mineur.Patch selon la règle du versioning semantique. Les version patchs servent à fixer généralement les problèmes de sécurité (CVE-…) et les régressions.

Attention : des versions patch continuent d'apparaître après la sortie de la version stable suivante. Par exemple, seule 5.24.1 (14 janvier 2017) était sortie au moment la la sortie de 5.26.0 (30 mai 2017).
Frise des versions de Perl
(il y a d'autres versions non représentées sur cette frise)

bleadperl est le nom donné à la dernière version de la branche de dev de Perl 5. Par exemple, on peut lire "testé avec bleadperl" ou "dois-je cibler bleadperl pour mon patch ?".

La version de perl fournie avec une distribution se nomme le perl vendor. Le perl vendor est empaqueté par la distribution. On peut décider de ne pas utiliser cette version mais pourquoi ?

  • Parce qu'on souhaite utiliser une version plus récente.
  • Pour figer la version Perl utilisée.
  • Parce qu'on veut une version de Perl avec des flags de compilation différents.
  • Pour éviter d'utiliser un perl vendor qui a été mal packagé.

On peut donc compiler notre propre version de Perl ou même utiliser le gestionnaire de binaires perlbrew (ou plenv).

Stuffed pumpkin et core dev team

Le gardien de la citrouille empaillée ou le possesseur de la citrouille à patch ou encore le pumpking (contraction de pumpkin et king) est en quelque sorte le mainteneur principal (ou mainteneur en chef comme le dit ce commentaire linuxfr) ou release manager ou tout simplement celui qui fusionne le code et coordonne la release. Il s'agit depuis quelques releases de Sawyer X (profil CPAN, Sawyer X est aussi l'auteur de Dancer) sur les releases x.y.0 (depuis 2017) et ensuite sur les numéros patch soit ça varie soit c'est Steve Hay.
Avant Sawyer X, le pumpking était Ricardo Signes (profil CPAN) sur les releases x.y.0 (depuis 2013) et de nombreux autres sur les patchs.

Voici la liste des "pumpking" ainsi que l'explication de la citrouille de patch.

Les développeurs du cœur de perl se nomment les Perl5 porters, ils contribuent leur code dans le repository git de Perl et utilisent le gestionnaire de ticket request tracker.

Sawyer X vient d'annoncer sur la liste de diffusion de Perl 5 Porters la décision commune de migrer le git repo principal ainsi que le gestionnaire de tickets vers github (notez d'ailleurs que Python fait la meme chose PEP581 et PEP588).

A priori, le repository github perl5 du projet Perl5 qui n'est actuellement un miroir devrait donc devenir le repository officiel et le gestionnaire de tickets central de Perl.




CHANGELOGS

Place maintenant aux différents CHANGELOG ou perldelta qui n'ont pas été traités sur LinuxFR. C'est (peut-être) long, très détaillé, mais ça permet de découvrir certaines features ou de se rendre compte un peu comment se passent les fixes. Je conseille donc à ceux qui ne sont pas intéressés par les détails internes du langage de lire en diagonale tout ce qui suit ! Perl 5 est un langage mature et les évolutions et les bugs ne sont pas forcement tous très impressionnants (c'est plutôt rassurant).

Ce qui va suivre est très détaillé et les détails techniques pas forcément appropriés pour un débutant Perl. Mais les items sont accompagnés le plus souvent possible d'explications des fonctions ou du contexte du fix, ce qui peut donner de l'intérêt même si on ne saisit pas bien le côté technique. Les analyses de changelog qui suivent sont exhaustives c'est à dire que mis à part certaines mises à jour de modules embarqués (et donc des diffs pas faciles à remonter) et certaines évolutions propres à des systèmes qui ne nous intéressent pas, tout a été traité.

Avant de commencer encore un petit xkcd pour vous motiver pour la suite (Licence CC-BY-NC) :
Messing with Perl

Sortie de Perl 5.22

La version 5.22.0 a déjà été traitée dans la dépêche sortie de perl 5.22.0 on passe donc directement à la version suivante qui est la version patch 5.22.1.

5.22.1

Un changement incompatible sur des fonctionnalités récentes mais boguées autour des regex boundaries et ici les \b{sb} pour phrase \b{wb} pour un mot et \b{lb} pour un retour à la ligne et leurs amis. Encore aujourd'hui, toutes ces regex ne sont toujours pas parfaites et font simplement du best effort.

MAJ des modules

POSIX::strerror

POSIX::strerror qui accidentellement écrasait $!(code erreur ou message d'erreur) a été fixé. Cela signifie que le oneliner

perl -MPOSIX -e '$! = 123; strerror($!); print "[$!]\n";'

n'affichait plus rien alors qu'il doit afficher :

perl -MPOSIX -e '$! = 123; strerror($!); print "[$!]\n";'
[No medium found]

Il faut voir que strerror est une fonction qui permet d'obtenir le libellé à partir d'un code d'erreur. Or en Perl, un print $! fait déjà ce travail (conversion implicite vers une chaine).

Même chose pour print "[$!]\n". Si on veut avoir le code il faudra faire quelque chose comme

perl -MPOSIX -e '$! = 123; print 0+$!;'

Ou encore avec sprintf

perl -MPOSIX -e '$! = 123; print sprintf "%d", $!;'

(scalar ne marchera pas dans ce cas-là)

Compilation

Grave problème de -Accflags et les quotes

Le flag de compilation -Accflags ne pouvait plus contenir de quotes (TRES GRAVE). C'est fixé en 5.22.1 ! Ouf :) Ce flag (précédé de -A pour Add) est transmis jusqu'au compilateur et peut contenir des trucs comme par exemple si on donne ceci au Configure script : -Accflags='-DAPPLLIB_EXP=\"/usr/libperl\"' Ça permet de faire que Perl ajoute /usr/libperl dans le @INC à l'exécution.

Bugfixes

Possessive quantifier

Un autre problème sur une feature expérimentale de regex, les possessive quantifier. Plutôt que de parler de ce qui ne fonctionnait pas, on va détailler un peu ce qu'est un possessive. Les regular expressions peuvent être greedy (défaut) ou non-greedy (quantifier ? juste après expression à matcher) ou même possessive.

Un exemple pour comparer greedy et non-greedy :

  • GREEDY (gourmand) : perl -e 'print "$1\n" if "aabaab" =~ qr/((aab)+)/;' qui nous donne aabaab (match le plus possible)
  • NON-GREEDY ou LAZY : perl -e 'print "$1\n" if "aabaab" =~ qr/((aab)+?)/;' qui nous donne aab (s'arrête après avoir trouvé)

Le possessive quantifier (++ après expression ou ?> avant expression) va quant à lui faire plus qu'être gourmand car il empêche également le retour en arrière (et empêche donc de matcher le a du ab suivant.

  • perl -e 'print "$1\n" if "aab" =~ qr/(a*ab)/;' trouve bien aab
  • POSSESSIVE (1) : perl -e 'print "$1\n" if "aab" =~ qr/(a++ab)/;' ne trouve RIEN
  • POSSESSIVE (2) : perl -e 'print "$1\n" if "aab" =~ qr/(?>a*ab)/;' ne trouve RIEN

La différence entre possessive et greedy est que greedy va chercher à matcher le plus possible mais en backtracking va ensuite essayer de matcher plus petit pour arranger en vue de ce qui est demandé après. En possessive non, ça matche le plus possible et c'est tout.

Warnings fatality

Un fix sur les warnings fatality qui pouvaient entrainer un crash. Qu'est-ce qu'un warnings fatality ? Une sorte de -Wall -Werror en version Mortal Kombat ? (désolé je n’ai pas pu résister). Et bien c'est à peu près ça. Un exemple :

perl -e 'use utf8; use warnings FATAL => 'all'; print "\x{255}\n"; while(1) {print "Je suis vivant\n"}'

Cette ligne n'affiche QUE le warning Wide character in print at -e line 1. et puis s'arrête. Mais sans rien :

perl -e 'use utf8; print "\x{255}\n"; while(1) {print "Je suis vivant\n"}'

La ligne exécute bien la boucle infinie après avoir affiché le warning.

Regex sets

Plusieurs utilisations marginales d'une feature expérimentale de regex crashait a l'exécution. Il s'agit des regex_sets ou Extended Bracketed Character Classes qui permettent de faires des ranges de possibles avec des opération ensemblistes comme par exemple :

qr/(?[ [\w] - [a-zA-Z] ])/;
# (un mot ne contenant pas les lettres a jusqu'à z, ni A jusqu'à Z). 

Cette feature est expérimentale et semble l'être encore aujourd'hui et requiert donc une déclaration no warnings "experimental::regex_sets"; pour désactiver le warning associé à son usage.

Plusieurs bugs et plusieurs fixes sur ce genre d'expressions :

(?[ () ])
(?[(\c])
(?[!!(\w])
ou encore (?[[0]+()+])
Cas marginal avec %::

Un autre cas marginal qui pouvait faire crasher l'interpréteur :
perl -e '%::=(); J->${\"::"}'

Explications :
%:: est un hash valide (mais déjà on cherche les problèmes avec cette syntaxe tirée par les cheveux) mais :: est aussi un séparateur de classe or il existe une classe implicite qui s'appelle main et qui récupère par exemple les variables qui ne sont pas déclarées par my ou state.

Par exemple perl -e '$var = "toto"; print $main::var;' affiche toto.

Autres
  • Plusieurs petits fixes sur des usages de regex qui doivent terminer en erreur. Comme le cas des nested quantifiers. Un nested quantifier c'est ce genre de choses /ab{2}??c/. Ou encore certaines séquences non terminées /(?i/. C'est tout simplement des regex fausses mais perl doit gérer correctement cette erreur.
  • Un mauvais usage de BEGIN faisait crasher perl, à présent BEGIN <> { } est simplement reporté en erreur.
  • Un bugfix sur le parsing de la ligne de commande (-Cnn pour unicode). Il s'agit de choses comme ceci perl -C3 -e 'print "\x{255}\n"' (qui produira ɕ). Le -Cnn pour Perl signifie qu'il faut activer les fonctionnalités Unicode et je cite The -C command line option can specify that certain inputs to the program are Unicode (perlunicode)
  • Des bugs dans le support des nombres flottants hexadécimaux lors des overflows (perte de bits en haut ou en bas. Également un bug au formatage avec sprintf "%a", $var.

5.22.2

Pas de changement incompatible.

Sécurité

File::Spec

[CVE-2015-8607] Bugfix dans File::Spec qui avait une faille avec le taint mode (protection de l'input) dans la fonction canonpath(). canonpath est une fonction du core module File::Spec (un core module est un module fourni avec la distribution perl standard, à chaque version de Perl, les core modules sont mis à jour et certains sont éventuellement ajoutés ou retirés selon leur qualité et leur utilité). C'est une fonction qui permet de récupérer le path canonique à partir d'une chaine et ce de manière portable. C'est une fonction de cleanup. Exemple :

perl -e 'use File::Spec; print File::Spec->canonpath ("/toto/./././\./tata")'
/toto/tata

C'est une fonction qui travaille sur les chaines mais ne va pas jusqu'à regarder le file système. D'ailleurs dans l'exemple le path /toto/tata n'existe pas sur le système :

ls /toto/tata
ls: cannot access '/toto/tata': No such file or directory

abs_path ou son alias realpath par exemple

perl -e 'use Cwd; print
Cwd::abs_path("/tmp/./././toto/../toto/../../tmp/./toto/tata")'

retournera bien /tmp/toto/tata… Mais seulement si le fichier /tmp/toto/tata existe !
abs_path est d'ailleurs aussi capable de résoudre les liens :

ln -s /tmp/toto/tata /tmp/toto/link && perl -e 'use Cwd; print Cwd::abs_path("/tmp/./././toto/../toto/../../tmp/./toto/link")'

donnera bien /tmp/toto/tata… Mais seulement si le fichier /tmp/toto/tata existe !

Mkstemp et umask

Bugfix sur le umask de mkstemp : au lieu de donner la négation à appliquer à 0666 pour obtenir un umask résultant de 0600, la valeur donnée était la valeur ciblée. Une fois la négation faite avec 0666, la valeur résultant était 0066, donnant beaucoup de droits aux membres du groupe et aux autres et peu au propriétaire. Nouvelle valeur après le fix : 0177.

Autres
  • Fix accès mémoire non initialisé par la fonction crypt().
  • [CVE-2016-2381] Un autre bugfix sur un problème intéressant. La façon de remplir %ENV à partir de environ[] ne donnait pas forcement les même valeurs. La cause ? Perl écrasait l'entrée dans %ENV avec la dernière vue alors que getenv gardait la première. Avec le fix, non seulement l'ordre est le même mais en plus le ménage est fait dans environ[].
  • [CVE-2015-8608] Bugfix sur les fonctions VDir::MapPathA et VDir::MapPathW qui permettaient une attaque DoS grâce a une lettre de volume bidouillée.

MAJ de modules

  • File::Spec et notamment la fonction canonpath() vue plus haut.

Compilation

  • Configure script gère gcc 5.
  • Fix -DPERL_MEM_LOG qui était casse. Mais qu'est-ce que PERL_MEM_LOG ? Avec ce flag, on va faire en sorte de logger quand on fait de l'allocation mémoire. A l'exécution, Perl ira lire la variable d'environnement. $ENV{PERL_MEM_LOG} pour connaitre le format et la destination des logs. Par défaut ça part sur la stderr.
  • D'autres fixes principalement sur la compilation sur du platform specific (Darwin, ppc64el, Tru64) ou sur libnm et DTrace.

Correction de bogues

Here-docs

Plusieurs bugfixes sur les here-doc. Petit rappel sur les HERE-DOCS même si on a la même chose en shell :

my $str = <<'END_MESSAGE';
Hello here-doc
    indent
END_MESSAGE

print $str;

Et à l'exécution :

perl here.pl
Hello here-doc
    indent

Les problèmes étaient :

  • Un crash possible si perl trouve la fin d'un fichier sans trouver la fin d'un HERE-DOC.
  • Une possible libération de mémoire sur un problème de parsing de HERE-DOC
Pack et UTF8

Premier bugfix sur pack avec UTF8(voir 5.24.4 [CVE-2018-6913]).

Profitons de l'occasion pour parler un peu de pack : pack et unpack sont de formidables outils détaillés sur la page perlpacktut. Ils sont utilisés dans 2 principaux groupes de cas :

  1. Le formatage de chaine (et la lecture de chaine formatée). Par exemple pour lire/écrire des champs dans un tableau texte de dimension fixe.
  2. Le traitement des données binaires et la conversion dans de nombreux formats (comme le ferait sprintf mais en BEAUCOUP plus puissant) comme nombre flottant, entier, UTF8, hexadécimal etc… On peut facilement corriger un problème d'endianness… Bref c'est des outils très génériques qui peuvent travailler sur des chaines de bytes.
Autres
  • Le C99 hexadécimal floating point notation support ajoute en 5.22.0 n'était pas tout à fait correct, corrigé.
  • De nombreux fix de segfaults sur des aborts provoqués, des meilleures explications quand le code utilise le mauvais contexte, ou quand on compile un pattern avec des classes de caractères non terminées. Bref principalement des améliorations pour le code faux :D
  • Perl utilise semctl()… si possible.
  • Fix d'une optimisation trop brutale de uc, ul, ucfirst et lcfirst (modification en place parfois).
  • Optimisation de la compilation de regex avec des caractères spéciaux, en attendant mieux en 5.24.0 :)

5.24.0

Améliorations du cœur de Perl

Combo ordre et précision dans printf et sprintf

On peut maintenant mixer précision et ordre des arguments de printf et sprintf. Exemple d'ordre des arguments

printf '%2$d %1$d', 12, 34;

qui donne 34 12 (on affiche argument 2 puis argument 1).

Exemple de précision

printf '<%.2f>', 1;

qui donne <1.00>.

On peut donc en 5.24.0 faire ce genre de chose

sprintf '|%.*2$d|', 2, 3

qui donne |002| soit l'argument choisi par 2$ avec la précision définie par 3 (l'autre argument). C'est quand même une feature assez sympa :)

Hashbang

Avec la sortie récente de Perl 6 (au moment de cette release, pas au moment où cette dépêche est publiée), il était bien que l'interpréteur perl redirige un script avec hashbang contenant perl6 vers perl 6 (ou son alias Raku apres la réflexion sur le besoin d'un alias pour Perl 6) tout comme il le fait quand il trouve un hashbang ne contenant pas la chaine perl. On verra en 5.24.1 que ce n'était pas une bonne idée (en tout cas l'implémentation en 5.24.0). Pour comprendre exactement de quoi on parle, il faut rentrer dans les détails :

Lorsque qu'on exécute un fichier sans préciser comment l'exécuter (exemple ./monscript.pl), c'est le hashbang qui est lu et qui sert à choisir. Mais dans le cas où on appelle l'interpréteur Perl et qu'il ne se reconnait pas dans le hashbang, il passe la main à un autre programme. Par exemple, le fichier jesuispython.pl contient ceci :

#!/usr/bin/env python
import os;

print "Hello from Python";
print os.environ["SHELL"];
print os.environ["_"];

import time;

while True:
    time.sleep(5)

Ça ressemble à du Python, ça a l'odeur du python et bien c'est parce qu'en fait c'est bien du Python :) Et ce n'est PAS un fichier Perl valide, on peut d'ailleurs s'en assurer avec un petit coup de syntax check perl -c jesuispython.pl qui nous donne :

perl -c jesuispython.pl
syntax error at jesuispython.pl line 6, near "environ["
syntax error at jesuispython.pl line 7, near "environ["
syntax error at jesuispython.pl line 8, near "environ["
jesuispython.pl had compilation errors.

En lançant le fichier avec perl, tout se passe bien, car l'interpréteur est intelligent et donne le script à Python :

perl jesuispython.pl
Hello from Python
/usr/bin/zsh
/usr/bin/perl

Et si on vérifie bien qui fait vraiment tourner ce script :

perl jesuispython.pl &; ps aux | grep "jesuispytho[n]"
[1] 15745
61531    15745  0.0  0.0  18468  3608 pts/64   R    13:39   0:00 python jesuispython.pl
Hello from Python
/usr/bin/zsh
/usr/bin/perl

(penser à faire le ménage avec kill)

Si on pousse un peu plus loin, on n'obtient pas le même comportement côté Python. Si dans un fichier jesuisperl.py on met ceci (à peu près la même chose qu'en Python) :

#!/usr/bin/env perl

my $a = "Hello from Perl";
print "$a\n";
print "$SHELL\n";
print "$_\n";

while (1) { sleep 5; }

On a un fichier Perl valide mais Python ne passe pas la main et Python nous retourne simplement :

python jesuisperl.py
  File "jesuisperl.py", line 3
    my $a = "Hello from Perl";
       ^
SyntaxError: invalid syntax
Post‐déréférencement

Post‐déréférencement n’est plus expérimental. Post‐déréférencement c’est ce genre de chose :

my @new = $old->@*;

La forme plus classique pour obtenir le même résultat est

my @new = @$old;

ou encore

my @new = @{ $old };

(notation circumfix)

Autre
  • Support unicode 8 (unicode 8 ajoute des milliers de nouveaux symboles).
  • L'interpréteur râle (exception) si on ne peut pas fermer un fichier édité en place.
  • Nouveau \b{lb} dans les regex. \b{} est pour boundaries et lb pour linebreak.
  • Extended bracketed character classes (déjà parlé plus haut dans la dépêche dans bugfix 5.22) est à présent compatible avec UTF-8.
  • Comportement des shifts (>> et <<) des entiers mieux définis, quelle que soit l'implémentation C dessous.
  • Amélioration de sigaction qui sert à donner une fonction à exécuter lors d'un signal. L'amélioration consiste (quand c'est possible, donc que le système le gère) à ajouter un hash contenant des infos sur le processus.

Sécurité

  • Fix umask donné à mkstemp (déjà vu plus haut en 5.22.2).
  • [CVE-2015-8608] Bugfix sur les fonctions VDir::MapPathA et VDir::MapPathW (déjà vu plus haut en 5.22.2).
  • [CVE-2015-8607] Bugfix dans File::Spec (déjà vu plus haut en 5.22.2)
  • Fix accès mémoire non initialisée par la fonction crypt() (déjà vu plus haut en 5.22.2).
  • [CVE-2016-2381] Fix sur environ (déjà vu plus haut en 5.22.2).

Changements incompatibles

  • La version 5.24.0 interdit la feature expérimentale autoderef c'est à dire qu'on ne peut plus faire perl -e 'use experimental 'autoderef'; my $a = []; push $a, "a"' (il faut faire push @a, "a"). Ça interdit donc le push to ref et on peut suivre sur perlbanjo la vie et la mort de autoderef.
  • Suppression de la variable lexicale $_. C'est apparu en 5.10 puis passé en expérimental en 5.18. En gros on laisse perl gérer cette variable spéciale (globale).
  • Le boundary word blank ne suit plus scrupuleusement les règles Unicode mais fait plus ce qu'attend perl (et ressemble a \b tout seul mais en mieux). Respecter scrupuleusement Unicode ne semble pas être le mieux adapté pour détecter les frontières de mots. On parle de cas marginaux comme des espaces puis un tilde puis un espace vertical…Ça reste du best effort tout de même. Plus de détails.
  • Certaines regex qui étaient en erreur au runtime ne compilent plus du tout. Ici il s'agit d'unicode properties (wikipedia dans les \p{} et \P{} (perluniprops). Ce genre de déplacement des erreurs est bon, car le code "casse" 100% du temps alors qu'il cassait qu'en atteignant la regex fautive avant.
  • Une expression unicode name vide comme ceci \N{} (qui ne sert à rien) devient fatale quand on active use re "strict".
  • Les déclarations imbriquées deviennent interdites my($toto, my($tata)). Au passage, my $toto n'est pas toujours pareil que my ($toto) (lors d'une affectation). Et même sans affectation my($toto, $tata) n'est pas my $toto, $tata; !
  • La classe de caractère \C n'existe plus du tout (erreur de compilation). Déprécié depuis 5.20, warning depuis 5.22.
  • La fonction chdir ne peut plus s'utiliser comme ceci chdir('') ou chdir(undef) pour aller dans $HOME. Mais chdir() fera tout simplement l'affaire.
  • Plus de caractères invisibles dans les noms de variables. Même ceux de la table ASCII !
  • Fix une config de Carp
  • Seuls \t et un espace sont autorisés dans les Extended Bracketed Character Classes. Il n'y a évidemment pas que ça dans les Extended Bracketed Character Classes mais tab et space sont ignorés :)

Dépréciations

  • Limitation Unicode code points. Jusqu'alors Perl autorisait les valeurs unicodes qui sont au delà du maximum unicode existant (donc qui ne correspondaient à aucun caractere…). Ça posait problème dans certaines transformations ou comparaisons. La valeur du code est à présent limitée.
  • L'opérateur de bitwise associé à une chaine travaille sur des bytes, travailler sur des choses plus grandes (des caractères encodes sur plus d'un byte) nécessite un découpage. Donc il y aura un warning à ce sujet.
  • sysread(), syswrite(), recv() et send() émettent un warning si on les utilise avec un filehandle marqué :utf8

Performances

  • Moins d'overhead sur les changements de contexte.
  • Lorsqu'une langue est insensible à la casse, en le sachant avant, on peut optimiser les fonctions comme ucfirst ou les regex avec modifier /i
  • La recherche de chaines fixe dans une regex peut être plus rapide (majorité des cas) ou parfois plus lente.
  • Les calculs arithmétiques sont plus rapides (le support du 64-bits avait mis un coup de frein).
  • Pre/Post Increment/Decrement ont été optimisés (grâce à de la modularisation de code en fonctions).
  • Optimisation debugger, moins de structures de données créées car inutiles.
  • Les assignements d'un seul argument dans une liste comme ($v) = ("toto"); et ($new) = ($old); sont plus rapides.
  • Pic de mémoire réduit à la compilation de regex. Une compilation de regex se fait en utilisant qr// (en fait perl décide ou non de compiler)

Compilation

  • Option -O donnée par défaut à Configure.
  • Plus de support de libnm.
  • Configure : test newlocale, freelocale et uselocale.
  • Support Bison 3.0.
  • On peut changer la date affichée par le binaire perl (perl -V) en modifiant la variable PERL_BUILD_DATE.
  • Incompatibilité entre NO_HASH_SEED et PERL_HASH_FUNC_ONE_AT_A_TIME_HARD (algo par défaut).
  • Configure : meilleure gestion des espaces dans les chemins (path).
  • Plus de génération des tables EBCDIC POSIX-BC. EBCDIC signifie "Extended Binary Coded Decimal Interchange Code" et il s'agit d'un codage de caractère qui existe sur les mainframes.
  • Support du build en parallèle pour Windows GNU Make.
  • Support de MSVC++ sur Windows avec GNU Make.
  • miniperl a getcwd. miniperl est une mini version de perl utilisée pour se construire lui-même. En prenant les sources on va compiler d'abord miniperl qui va aider ensuite à compiler perl.
  • Configure prend en compte -Dusequadmath pour calculer alignbytes. On verra plus tard (5.24.3) que -Dusequadmath est incompatible avec -Duselongdouble.
  • Un test de compilation en parallèle est ajouté dans le makefile pour Windows.
  • Support d'AmigaOS réintègré dans le build.
  • Utilise fdclose() fonction de FreeBSD si disponible.
  • Shared libperl compile sur toutes les variantes Solaris.
  • Sur VMS, Perl implémente son propre killpg.
  • D'autres choses sur MacOS, Tru64, IRIX, EBCDIC, cygwin, Win32 et ppc64el.

Changement internes

  • Refactorisation du code de context stack system et ses API. Macros remplacées par static inline fonctions. Changement de naming (cx_ ou CX_ préfixe).
  • Une structure écrite pour Perl 1 a été supprimée (PL_timesbuf). Bravo a PL_timesbuf pour sa longévité :)
  • Emulation de signbit() améliorée. signbit() est une fonction pour connaitre le signe d'une valeur passée en paramètre.

Bugfixes

  • Si vous vous souvenez des perluniprops eh bien ici ça va plus loin car on parle de mettre des propriétés utilisateur et non-définies au moment de la compilation de la regex comme ceci qr/\p{sheldon::bazinga}/i. Ça ne marchait pas et c'est fixe en 5.24.0.
  • Il existe des versions "fallback" de fonctions comme memcpy(), memset() memmove() et memcmp() mais elle sont pas tout à fait comme les originales. D’ailleurs comme le dit bulk88 sur le tracker We aren't eating out own dog food car Perl est compilé avec les version originales. Ça ne prouve pas que les fallback sont cassés, mais ça ne prouve pas le contraire non plus :) C'est fixé en 5.24.0
  • Problème avec la substitution et le modifier /r (substitution non destructrice et retourne la nouvelle valeur) donc ce genre de chose s///r. Le problème vient quand on compile perl avec -DPERL_NO_COW. Attention cette variable ne dit pas que perl ne doit pas contenir de vaches mais interdit la Copy On Write :)
  • Meilleur reporting avec strict
  • Meilleur report d'erreur sur les regex. Des messages à la place de simplement "Assertion failed", des erreurs générées sur des classes de caractères non terminées
  • Il y avait une petit range de valeur où la fonction caller donnait des numéros de lignes négatifs, c'est fixé.
  • Un warning sur unless( $v = "abc") par exemple perl -e 'use warnings; unless(my $v = "toto") { print "a"; }' donne Found = in conditional, should be == at -e line 1. si warnings est activé.
  • Un cas très marginal de here-doc non terminé (map d<<<<) ne génère pas de assert failed ou de crash mais bien une erreur.
  • Problème avec tie et untie. Ces fonctions servent à faire de l'orienté objet.
  • Bugfix sur la directive #line sans fichier donc un truc comme #line 0000000
  • Un warning sur les regex et les classes POSIX [[:alpha:]] lorsqu'elles sont mal écrites comme [[:alpha]]. Ca ressemble à une classe POSIX, c'est presque une classe POSIX mais ce n’est pas une classe POSIX. Donc perl préfère prévenir.
  • Régression en 5.20 sur les classes et les synthetic start class. Un code qui bug est comme ceci /_?[^\W_0-9]/
  • Amélioration du support C99 notation hexa a virgule flottante ajouté en 5.22
  • Malgré l'activation du mode strict, ce genre de code use strict; my %h = (); my $v = $h{+toto}; n'émettait pas d'erreur.
  • Un bug sur ce genre d'expressions :
&{0==&{0==0}}.0
&{0==0}/&{0==0}&0
&{0*&{0==0}==0}/0
&{0==0}*&{0==0}
# Appels imbriqués (ou pas) avec **&**. L’étoile est un **typeglob** (le bug n'est pas lié à ça).
  • Meilleur rapport d'erreur quand perl attend un opérateur et trouve un tableau.
  • Bugfix sur les regex. Le bug apparaissait en mélangeant \G et chaines utf8. l'expression \G permet de matcher seulement à la position (on la set avant grâce a pos()
  • Bugfix sur le parsing de here-docs bizarres
  • Fixe un bug lié aux variables spéciales $a et $b dans des cas comme @a = sort{ *a=0; 1} 0..1;
  • Plusieurs problèmes sur le récent format %a
  • Amélioration du boundary espace \b{sb}. Les tests sur 5.22.0 étaient faits sur des chaines trop petites, en ajoutant de nombreux tests sur des chaines plus longues, on s'est aperçu que cette expression n'était pas parfaite.
  • De nombreux bugs sur les boundaries en général \b{gcb}, \b{sb}, \b{wb}, \B{gcb}, \B{sb}, et \B{wb}.
  • De NOMBREUX bugs sur Extended Bracketed Character Classes. Il s'agit de bug sur des expressions incomplètes (incorrectes donc) mais au lieu de faire une erreur perl panique. Par exemple sur (?[\ &!]), (?[!()]), (?[(\c]) ou ?[ () ]
  • Les quantifiers imbriqués (regex) doivent produire une erreur, et non être ignorés.
  • Le parsing des nombres hexadécimaux à virgule flottante a été amélioré.
  • Bugfix sur pack 'H' ou pack 'h' (chaine hexa). On a déjà vu ce genre de problème (5.22.2) et c'est toujours pareil, de l'UTF8, une fin prématurée et une fonction pack qui lit trop de bytes.
  • Plusieurs fixes de segfault.
  • Les commentaires dans les regex ((?#...)) n'étaient pas possibles partout. La question s'est posée de savoir si c'était by design ou si c'était un bug. Finalement je crois que la solution est entre les 2 (maj de doc + fix)
  • La tentative de création d'une stack énorme avec par exemple @a = (1) x $big_number (attention x est l'operateur de répétition qui fait répéter une chaine) faisait crasher perl. Apres le fix ça fait une exception :)
  • Bugfix dans les expressions conditionnelles dans les regex ((?(condition)si-oui|si-non)) avec ?! qui ne donnait pas le bon comportement. Le code print /(?(?!)(?{print "Yes"})|(?{print "No"}))/ doit donner No et il donnait rien du tout.
  • Les backtracking control verbs prennent tous potentiellement des arguments.
  • dup un filehandle fermé ne crée plus de fichier poubelle.
  • Warnings fatal ignore en rembobinant la stack pour éviter la récursion infinie. Car un fatal fait rembobiner la stack et si on voit un fatal on rembobine etc…
  • Bugfix sur l'option perl -Cnn (qui active unicode). Ca a été touché en 5.22
  • Si on passe une valeur négative à votre alarm() ou sleep(), avant, la valeur était transmise à la fonction C, avec un résultat potentiellement surprenant. Maintenant on a un warning et ça retourne undef
  • Les grandes valeurs de caractère bien après Unicode dans les regex ne crashent plus.
  • Gestion des limites en utilisant l'opérateur range par exemple 1...888888888888888 (il faut que ça dépasse l'espace d'adressage)
  • Transformations avec ce genre de chose tr/\x{101}-\x{100}// était mal gérées.

5.24.1

Pas de changements incompatibles.

Sécurité

Tout d'abord, il ne faut pas avoir peur des CVE, la majorité du temps c'est les développeurs Perl eux-mêmes qui demandent à créer l'identifiant CVE. Mais bon, bonne nouvelle quand même, il n'y en a pas dans la 5.24.1 :)

  • Bugfix d'un problème d'output de PerlIO qui n'attendait pas de lire les switchs (flags de Perl dans le hashbang ou la ligne de commande) et pouvait créer un fichier même lorsque le switch -T ou -t n'était pas d'accord.
  • Les core modules ne cherchent plus dans "." pour les modules optionnels. C'est quelque chose d'important car même si en général le répertoire courant est le dernier dans @INC, ça pouvait permettre de faire exécuter des morceaux de code en posant un module dans un répertoire où va être lancé un script Perl par un autre utilisateur.

On peut regarder le contenu de @INC de cette manière par exemple

perl -e 'print join "\n", @INC'

ou même

perl -e 'foreach my $i (@INC) { print "[$i]\n"; }'

qui va sortir quelque chose comme ça :

[/tools/production/lib/perl5/]
[/tools/local/current/lib]
...
...
[/usr/lib/perl5/vendor_perl]
[.]
# (on note bien que "." a été ajoute par Perl à @INC)

Quand on dit que les modules ne cherchent plus dans ".", en fait il ne s'agit pas de tous les core modules, un core module résiste encore et toujours à l'envahisseur… Non plus sérieusement le travail sur le module base n'a pas pu être fait et est attendu pour la version patch 5.24.2. base.pm est un module qui sert pour la programmation objet pour définir la classe parente.

Bugfixes

  • L'implémentation naïve en 5.24.0 de la redirection de l'interpréteur vers perl6 est incorrecte. Il s'agissait de rediriger si on trouve perl6 dans le hashbang, mais ça posait problème pour le cas par exemple d'une install de perl à l'endroit /opt/perl64/perl

MAJ de modules

  • Fix de sécurité sur XSLoader (chargement de fichier binaires hors de @INC) détails ici

5.24.2

Sécurité

  • Cette fois le travail pour arrêter de charger les modules optionnels à partir de "." a été fait pour base.pm
  • Un autre bugfix sécurité sur la PATH. En Perl le mode taint considère que tous les path relatifs sont taintés, mais on pouvait jusqu'alors protéger un séparateur avec un antislash. Donc PATH=/tmp/toto\:./repertoire/dangereux/ était vu par Perl comme /tmp/toto/repertoire/dangereux/ donc safe mais l'OS n'est pas forcement d'accord avec cet échappement et donc continue à avoir le /tmp/toto/:./repertoire/dangereux/ dans son PATH. C'est corrige.

Bugfixes

  • Un bug concernant s///l (substitution avec jeu de caractère local) lorsqu'on essaye d'un autre côté de forcer une substitution sur un jeu de caractère qui ne correspond justement pas bien au locale par exemple un code comme my $v='ɕ'; $v =~ s/0*(\w)//l doit casser.

5.24.3

Sécurité

  • [CVE-2017-12837] Bugfix d'un possible heap overflow avec le case insensitive modifier (/i) qui permet de faire des regex qui match sans se soucier de la casse et les caractères unicodes nommes \N{MON NOM UNICODE}. En parlant de casse et d'unicode, ce n’est pas évident le passage en majuscule ou en minuscule d'un caractère. Par exemple en minuscules c'est ß ou ss ?
  • [CVE-2017-12883] Bugfix d'un over read dans les regex avec quelque chose comme ça m'\N{U+.}';. Le comportement du bug dépendait de la version de perl ou de la plateforme mais en général produisait une lecture et un report (message d'erreur) de données potentiellement sensibles ou simplement un crash.
  • [CVE-2017-12814] Un bugfix sur un possible stack buffer overflow. La chaine étant bien préparée, le mécanisme de buffer pour la copie est obsolète et le buffer est supprimé. Plus de buffer plus de problème.
  • [Pas de CVE id] Grosse vulnérabilité dans sprintf. On peut produire un buffer overflow en faisant quelque chose comme ceci print sprintf("%2000.2000f this is a spacer %4000.4294967245a", 1, 0x0.00008234p+9);. On élargie le buffer puis on donne une valeur qui va faire overflow.

Bugfixes

Beaucoup de bugfixes pour une version patch mais c'est du à de nombreux reports issues du fuzzing. Ici l'outil utilise est American Fuzzy Lop par l'intermédiaire de la commande afl-fuzz et les cas en doubles sont ensuite réduits grâce a afl-tmin (qui fait partie de la suite American Fuzzy Lop)

Vieux bug de double négation

Un très vieux bug sur les expressions logiques avec && et ||. Par exemple sur ce genre d'expression !r || !n'

En fait, 2 optimisations par le compilateur interfèrent et produisent ce bug : perl commence par optimiser la double négation en une seule négation devant une parenthèse et remplacer le || (ou or) par un && (ou and). Or il commence par enlever les négations et remplacer l'opérateur logique or et il se marque sur un petit papier de côté pour plus tard de "penser à mettre !() autour de mon expression". D'après la table de vérité, c'est tout à fait juste et permet d'optimiser à une seule négation :

r      n      !r     !n     !r or !n    r and n    !(r and n)
0 0 1 1 1 0 1
0 1 1 0 1 0 1
1 0 0 1 1 0 1
1 1 0 0 0 1 0

Mais voilà, lorsqu'il s'agit de constantes, perl prend un raccourci et le petit papier est perdu et ça termine en un r or n. Ce qui n'est pas du tout pareil. Ça reste un cas très marginal (à cause des constantes) mais c'était un gros bug !

perl -x

Avec le switch -x, les numéros de lignes sont faux. Le switch perl -x sert à exécuter du code mélangé dans un texte. Imaginons un fichier texte mail.txt :

Salut DLFP,

J'espère que la dépêche vous plait :)

Bisous

#!/usr/bin/env perl
print "Bazinga\n";
__END__

Tout ceci est CC-BY-SA

Avec un perl mail.txt j'ai une erreur mais avec perl -x mail.txt j'ai bien mon Bazinga :)

Autre
  • Un bugfix pour éviter les scripts bizarres comme /@0{0*->@/*0 de crasher.
  • Un bugfix sur le mot clé reset (à mon avis assez peu utilisé). reset permet de reset une variable à sa valeur initiale, mais seulement les variables globales, ou de réactiver un pattern de maching à usage unique dans une boucle.
  • Fix crash sur du code marginal comme /${*::::::=0}$0{*::::=0}/
  • Un bug sur le bitwise AND assign operator &= mis en lumière par ce genre de code use feature':all';@0&=0. Le problème vient de ce qui est à gauche du bitwise (un tableau) mais le code est faux mais ne doit pas crasher.
  • Fix error code retourne par socket (passe le code d'erreur du système)
  • Fix memory leak lorsqu'on importe et utilise le mode strict pour contrôler une regex. use re qw(strict) permet d'avoir des warnings lorsqu'une regex commence à être ambiguë. Par exemple qr/\xABAB/ est plus ou moins ambigu et le strict regex va générer une erreur pour forcer le développeur à préciser sa pensée (avec des accolades).
  • Un autre bugfix sur du code très bizarre open my $fh, ">", \ (my $buf = ""); my $sub = eval q|sub {die}|; $sub->(). Dans ce genre de cas très précis ou $fh et sub sont déclarés dans cet ordre et sont des variables lexicales, la fermeture implicite de $fh entraine la libération mémoire de $sub.
  • Des problèmes de parsing de regex sur les extended patterns comme /(?<=/ ou /(?<!/. Les extended patterns commençant par (? permettent de faire plein de choses différentes, comme par exemple un commentaire dans la regex ou bien changer le modifier. Dans les cas /(?<=/ et /(?<!/ il s'agit de pattern matching (avec ou sans négation). Apres le fix, on a un message d'erreur Sequence (?... not terminated").
  • Un bugfix sur gethostent quand c'est utilisé avec torsocks. La fonction n'était pas bien protégée contre un bug cote torsocks.
  • Une erreur de syntaxe sur les constantes dans ce genre d'expression sub ub(){0} ub ub (2 constantes à la suite…) était mal gérée. C'était une régression assez récente (5.20) et c'est fixé.
  • Un autre régression encore plus récente (5.24) sur l'usage de la fonction fchown a été corrigée. Les valeurs négatives n'étaient plus acceptées pour fchown alors que c'est une valeur tout à fait possible dans certains cas (d'ailleurs la doc n'était pas d'accord avec le code :D).
  • Un mauvais code mélangeant ouverture de tableau, code de contrôles et passages à la ligne comme celui-ci @ { \327 \n produisait une sortie incorrecte ou tronquée (comment traduit-on exactement garbled output ?). Le bug est bien expliqué sur le tracker par un dev. Ce à quoi répond un autre contributeur par un "Ça a l'air drôle. Je peux le prendre ?". Un autre lui répond "Il est bien commode que les gens aient une vision bien différente de ce qui est drôle. Allez-y prenez le :)" ticket perl #128951.
  • Une autre régression récente (5.24) sur l'utilisation combinée de la regex de remplacement de caractères tr/// avec les caractères unicodes (encore eux !). Cette fois avec la valeur \N{U+190D} (qui est vulgar fraction three quarter c'est à dire ¾).
  • Un bugfix sur printf "%a". Le %a est l'hexadécimal à virgule flottante. Beaucoup de travail sur ce format. C'est très technique, on va s'arrêter là sur ce sujet. Plus léger, j’ajoute en citant printf perldoc Don't fall into the trap of using a printf when a simple print would do. The print is more efficient and less error prone. (même si je ne crois pas que beaucoup de monde tombe dans le piège :D)
  • Bugfix d'un possible crash de evalbytes suivi d'un mot sans quotes. evalbytes et comme eval mais réduit aux bytes (donc généralement lira en ASCII pour une partie et pour le reste ca dépend de ce qu'on a configuré).
  • Encore une erreur de syntaxe dans les regex mal reportée, les expressions incomplètes entre (?[ ]).

Compilation

  • Bugfix d'un problème avec GCC 6 et -flto (optimisation du temps de linkage)
  • -Duselongdouble et -Dusequadmath sont incompatibles, Configure doit s'arrêter et c'est l'objet du fix.
  • Bugfix sur la naming : ne pas doubler le suffixe -quadmath
  • Configure reconnait le compilateur C VSI Il concerne OpenVMS, j'apprends d'ailleurs grâce à Wikipédia que L'uptime le plus élevé d'une machine OpenVMS est de 17 ans, aux chemins de fer irlandais (uptime)
  • Bugfix sur clang build avec -DPERL_GLOBAL_STRUCT ou -DPERL_GLOBAL_STRUCT_PRIVATE. Reoccurrence en 2018 :(
  • Des problèmes de compilation GCC 6 sur Windows (et un build 64 bits)

5.24.4

Pas de changement incompatible.

Pas d'update de module à part Module::CoreList (qui sert à lister les modules…)

Sécurité

  • [CVE-2018-6797] Bugfix d'un possible heap buffer overflow lorsqu'on utilise unicodes names \N{LE NOM} ou \N{U+N} (avec N le numéro dans la table) et qu'on donne la valeur exacte d'un caractère avec \x. Si J'ai bien compris, \N force un contexte unicode mais \xBF est hors range UTF-8 et \N devrait lancer un reparse mais ne le faisait pas. Un exemple de regex causant le bug : /00\N{U+0}\xDF/i
  • [CVE-2018-6798] Bugfix sur le même genre de problème. Une expression du type $x="(?il)\x{100}|\x{100}"; "\xff" =~ /$x/; fournit un caractère partiel et Perl pourrait lire après le buffer.
  • [CVE-2018-6913] Bugfix sur un possible heap buffer overflow. Le problème se situe dans le l'allocation mémoire du pack (mauvais calcul dans le nombre d'items). Un exemple de code fautif ressemble à ça : pack c9f999999999B9999999K9
  • Bugfix sur un possible crash de Perl lorsqu'on donne des caractères de contrôles comme nom d'un caractère unicode (rappelez-vous le \N{MON NOM UNICODE})

Bugfixes

Vieux bug de readpipe

Un vieux bug (depuis 5.7.0) relatif à readpipe qu'on peut (pouvait) reproduire avec

./perl -wle 'print readpipe($^X, "-e", q(printp "12\n"))'

ou

$^X

correspond au nom du binaire qui exécute le script avec comme argument
-e (/usr/bin/perl -e est simplement un début de oneliner Perl, pour prendre un exemple non-perlish c'est comme /bin/sh -c).

Le bug est la façon de parser readpipe.

Sortie de Perl 5.26

5.26.0

Sécurité

Répertoire courant dans le PATH peu sûr (unsafe dot)

En 5.24.1 et 5.24.2 on voyait un premier travail sur les core modules pour ne plus charger les modules optionnels dans le PATH courant. Cette fois ça va beaucoup plus loin. Jusqu'alors, le répertoire courant, soit la valeur ., était ajouté par le compilateur dans le @INC à la fin de manière automatique. On peut le vérifier avec cette commande :

perl -e 'print join "\n", @INC; print "\n"'
/etc/perl
/usr/local/lib/perl/5.18.2
/usr/local/share/perl/5.18.2
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.18
/usr/share/perl/5.18
/usr/local/lib/site_perl
.
# (oui cette commande est lancée sur une ubuntu 14.04, c'est un **5.18**)

Ici on voit que la dernière entrée de @INC est ., c'est le programme perl lui-même qui décide de l'ajouter (à l'exécution). Les autres entrées sont :

  • Soit ajoutées en dur au moment de la compilation.
  • Soit ajoutées dans le script via use lib ou push @INC, "/pushme" ou local::lib
  • Soit ajoutées à la ligne de commande avec -Idir comme ceci perl -Itest test/myscript.pl
  • Soit ajoutées grâce à une variable d'environnement PERL5LIB

Voici un exemple avec $PERL5LIB :

export set PERL5LIB=/tmp/toto && perl -e 'print join "\n", @INC; print "\n"'
/tmp/toto
[Les autres entrées...]
.

C'est assez courant de mettre une entrée dans le bashrc pour faire aller pointer vers notre répertoire de modules perso (ou même un répertoire partagé entre plusieurs machines).

Donc nous disions que le répertoire . était ajouté automatiquement… À partir de 5.26.0, . n'est plus dans le @INC.

Prenons un cas avant 5.26.0. dans un répertoire ~/test on crée 2 fichiers. Un module mymodule.pm et un fichier client myscript.pl.

Voici ce que contient mymodule.pm :

sub bazinga() {
    print "Bazinga !\n";
}

1;

On a mis une fonction bazinga et un code 1; pour dire que tout s'est bien passé au chargement du module. Par curiosité on peut exécuter mon module perl mymodule.pm ce qui ne fait rien. Très bien :)

Dans le second fichier myscript.pl on met :

#!/usr/bin/env perl
use mymodule;
bazinga();

On va chercher notre module et on appelle une fonction. Ce module n'est pas dans la liste des répertoires de modules comme /etc/perl mais il est dans le répertoire où nous sommes.

L'exécution de perl myscript.pl ou ./myscript.pl nous donne bien Bazinga !

En fait, perl a fait comme si nous avions mis use lib "." dans le script comme ceci :

perl -e 'use lib "."; print join "\n", @INC; print "\n"'
.
[Les autres entrées]

ATTENTION ici le répertoire courant est placé en premier.

Si nous faisons cd .. Et essayons de lancer perl test/myscript.pl ça ne marche plus !!!

Can't locate mymodule.pm in @INC (you may need to install the mymodule module) (@INC contains: /tmp/toto /etc/perl /usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18 /usr/local/lib/site_perl .) at test/myscript.pl line 4.

BEGIN failed--compilation aborted at test/myscript.pl line 4.

Car le . ajoué dans le @INC n'est plus celui du script…

On pourra arranger ce problème en modifiant le script en ajoutant :

use File::Basename;
use lib dirname(__FILE__);

Ou bien en donnant le répertoire dans la ligne de commande perl -Itest test/myscript.pl

En 5.26.0, même en étant DANS le même répertoire, on aura cette erreur.

On pourra changer ce comportement grâce à PERL_USE_UNSAFE_INC=1 ou en compilant perl avec -Udefault_inc_excludes_dot

Ce changement de comportement était un vrai séisme.

  • La commande do est utilisable pour remplacer un use donc exécuter un perl module ou bien simplement exécuter un autre fichier.

Le fichier autre.pl:

#!/usr/bin/env perl

do "myscript.pl";

Si on l'exécute comme ceci perl autre.pl il va donner une erreur :

do "myscript.pl" failed, '.' is no longer in @INC; did you mean do "./myscript.pl"? at autre.pl line 1.

perl nous explique donc pourquoi ça marche pas. On peut le fixer avec do "./myscript.pl"; ou bien do "myscript.pl"; ou encore export PERL_USE_UNSAFE_INC=1 && perl autre.pl

De la même manière qu'on peut exécuter un script avec do on peut également inclure un perl module par exemple comme ceci do "mymodule.pm";

Autre
  • On retrouve également les bugfix de 5.24.1 et 5.24.2 sur PerlIO -Di et le problème de : dans le PATH
  • POSIX::tmpnam() pas safe et déprécié en 5.22 disparait
  • Fix sur XSLoader qui pouvait charger un fichier binaire en dehors de @INC

Améliorations du core de perl

Here-docs indentés que dans le code source

Une limitation un peu gênante des here-doc était le fait de devoir casser l'indentation lorsqu'on les écrivait. On peut maintenant faire ignorer l'indentation

print <<~EOF;
    Je suis indente dans mon code source...
    mais pas dans execution :)
    EOF

Qui nous donne comme prévu :

Je suis indenté dans mon code source...
mais pas dans exécution :)
Declaration de références

Nouvelle feature expérimentale… Déclaration de référence \o/

Ce qui signifie qu'on pourra faire

use experimental 'declared_refs'; my \$rr; $$$rr = "toto"; print "$$$rr\n"

ou même déclarer une référence et faire un alias d'une autre référence

my \$alias = \$var;

A noter qu'on peut placer l'antislash avant le my comme ceci

\my $rr;

Plus d'infos ici

CORE et main

On peut appeler les fonction CORE avec le sigil de fonction & ou faire des références.

CORE est le package du core de Perl qui contient les fonctions builtin.

Attention le package de base s'appelle main et non CORE.

Pour declarer une variable dans le package de base, il ne faut pas utiliser my pour que la variable puisse s'attacher au package courant.

Lorsqu'on déclare une variable dans le package de base on peut faire ce genre de chose :

$var = "toto"; 
print "$::var\n"; # AFFICHE "toto"

ou

$var = "toto"; 
print "$main::var\n"; # AFFICHE "toto"

(cf doc package)

Mais si on declare avec my ca ne marchera PAS :

my $var = "toto"; # FAUX
print "$main::var\n"; # AFFICHE RIEN
Autre
  • Les lexical subs ne sont plus expérimentales. Mais ça ne veut pas dire qu'il faut les utiliser :) Cet article de blog explique pourquoi l'utilisation des lexical subs est "complexe"
  • Nouveau modifier /xx qui se comporte comme /x (ignore les espaces) mais permet de les ignorer également dans les classes de caractères entre crochets /[ ^ a-e r-z ]/xx
  • Nouveaux mots-clés pour les captures de regex @{^CAPTURE}, %{^CAPTURE}, et %{^CAPTURE_ALL}. C'est plus des alias qu'autre chose.
  • Support Unicode 9.0 (7500 caractères, 72 émojis, 6 scripts)
  • Toujours Unicode, améliorations de la gestion des scripts unicode. Un script unicode va nous permettre de tester une famille de caractères. Par exemple \p{sc=Braille} nous permettra de tester un caractère Unicode braille
  • Perl sait mieux trier l'UTF8 en utilisant LC_COLLATE.

Changements incompatibles

  • Une accolade (pour matcher une accolade) dans une regex doit être protégée par un antislash ou 2 crochets sinon la compilation échoue. Le but de ce changement est d'ouvrir de nouvelles possibilités pour les regex. C'était déprécié depuis 5.16
  • Nouveau comportement de scalar(%h) qui retourne le nombre de clés.
  • Meilleure consistance concernant les fonctions à lvalue en contexte de liste. Il s'agit ici d'aligner le comportement de keys %hash (en assignement lvalue)
  • Le module pour forcer l'encoding sort du core, on peut continuer à le faire avec un module CPAN.
  • On ne peut plus donner un nom absolu (::Ici::La::MonModule) pour inclure un module
  • Plus de caractères de contrôles dans les noms de variables. Honnêtement ça ne va pas manquer. Est-ce que vous appelez vraiment vos variables $\cx\cx\cx ? Si oui, je ne peux plus rien pour vous :P
  • Les caractères nommés ne doivent plus contenir d'espace.

Dépréciations

  • Les délimiteurs de chaines doivent être des graphemes.
  • Les caractères de contrôle ne sont plus acceptés dans les chaines mais ils ne deviennent plus dépréciés non plus. Ici on parle des caractères de contrôles qui n'ont pas d'alias (\n est un alias. Et on peut s'amuser avec perl -e 'print "Je\cJsuis\cJbeau\cJ";' qui produit :
Je
suis
beau

Performances

Prototypes et signatures

Implémentation des signatures de routines plus rapide.

Puisqu'on aborde les fonctions, on va prendre un moment pour en parler. Le mécanisme de fonction en Perl est très flexible et ne ressemble pas forcément aux autres langages.

À l'origine et dans pas mal de code Perl, on trouve des fonctions sans prototype comme par exemple sub func { mon corps de fonction }. On récupère alors les arguments tout simplement en piochant dans le tableau des arguments @_ :

  • sub f { my $a1 = shift @_; print $a1 } f("abc"); nous donne bien abc
  • Même chose si on oublie le @_ my $a1 = shift; fait exactement le même travail.
  • Ou si on utilise la notation indexée my $a1 = $_[0];
  • Ou encore on peut forcer le contexte en liste et récupérer un seul item my ($a1) = @_;

Maintenant que se passe-t-il si on donne plusieurs arguments ? Rien !

f("abc", "def"); se comporte pareil, le second argument est bien dans @_ mais n'est jamais récupéré, seul le premier est pris.
On peut le récupérer avec un deuxième shift my $a1 = shift; my $a2 = shift; ou en indexant avec my $a1 = $_[0]; my $a2 = $_[1]'; mais on aussi réutiliser la méthode avec le contexte de liste à gauche de l'assignement my ($a1, $a2) = @_;

Une propriété de Perl est d'aplatir les tableaux et donc ((("a", "b")), "c") est pareil que ("a", "b", "c"). Lorsqu'on veut passer des choses plus compliquées (comme des tableaux) dans des appels de fonctions, ce principe de array flattening ne permet pas de savoir pour f(@a, @b) où commencent et où finissent les tableaux. C'est pour cette raison aussi que les tableaux de tableaux ou les hashs de hashs utilisent les références (sinon tout s'aplatit !)

On doit donc donner une référence et déréférencer ensuite dans la fonction :

sub f { my $ref = shift; print @$ref } my @a = ("a", "b"); f(\@a, "c");

et là on a bien délimité notre tableau et notre c ne se retrouve pas dedans.

En Perl, on peut choisir d'être très expressif ou non.

Personnellement, je déclare mes fonctions en début de fichier et j'utilise les prototypes. C'est plus déjà pour les humains avant d'être un besoin.
Mais tout le monde n'est pas d'accord (on a les 2 sortes de partisans sur ce thread) car le prototype sert plus à donner à l'interpréteur une indication sur la façon d'évaluer l'argument qu'à lui dire de faire la vérification de type.
La notion de prototype n'est donc pas forcément exactement ce que vous pouvez attendre d'elle. Si vous attendez des prototypes de fonction Perl principalement des vérifications du typage, ce n'est pas vraiment le but premier, même si ça sert aussi un peu à ça.

Les prototypes permettent 3 choses :

  • Émuler la conversion implicite des builtins.
  • Faire de la vérification de type.
  • Dire aux humains comment s'utilise la fonction.
  • (Parfois, ne pas avoir à mettre des parenthèses dans l'appel d'une fonction)

Qu'est-ce que la conversion implicite des builtins ? Les fonctions builtins pratiquent une conversion implicite des paramètres c'est à dire que push @array, 12 va convertir @array en une référence et donc travailler sur le tableau et non ses valeurs. C'est pour cette raison que la valeur du tableau est modifiée à la sortie.
Si on essaye de faire la même chose avec une fonction à nous, on n'y arrivera jamais, car (1) on récupèrera toujours un tableau de valeurs contenant toutes les valeurs et (2) il nous faut une référence pour travailler sur le tableau et non les valeurs elles-mêmes.

Pour y parvenir, il faut préciser le prototype comme ceci f(\@$) qui dira "je veux un tableau qui sera converti en référence en arrivant dans la fonction" et un "scalaire".
On appellera la fonction avec f(@tab, 12).

La notation \@ permet de :

  • Vérifier que l'argument à l'appel commence bien par @ (donc vérification du typage)
  • Convertir implicitement le tableau en référence . On peut faire à peu près la même chose en déclarant la fonction comme ceci f($$) et en appelant avec f($ref, 12) mais cette fois il n'y a NI CONVERSION IMPLICITE, NI VERIFICATION f(11,12) est joyeusement accepté même si c'est faux. Et même f(@a,12) !

Avec les prototypes, que ce soit la version avec ou sans vérification du typage, on a tout de même une vérification du nombre d'arguments. Donc f(11) n'est pas accepté car la fonction souhaite 2 arguments. Pareil avec f(11,12,13) qui est refusé par perl.

On peut rendre les prototypes flexibles très facilement grâce à 2 méthodes.
La première est de mettre un tableau comme dernier argument :

sub f($$@) {
        my $a = shift;
        my $b = shift;
        my @c = @_;
        # Mon code
}
f(11,12,13,14,15);

Le tableau @c va "manger" tous les arguments restant.

Ou en utilisant les arguments optionnels. Notez bien le ; dans le prototype :

sub f($$;$$$) {
        my $a = shift;
        my $b = shift;
        my $c = shift;
        my $d = shift;
        my $e = shift;
        # Mon code
}
f(11,12,13,14,15);

Tout ce qui se trouve après le ; est optionnel.

Un appel comme f(11,12,13,undef,15); ou f(11,12,13,undef,15); gardera bien l'ordre des argument mais attention f(11,12,13,,15); se transforme en f(11,12,13,15); et ne fera probablement pas ce que vous souhaitez.

ATTENTION nous avons parlé jusque la des prototypes or les signatures ne sont pas la même chose que les prototypes !

Pour ce qui concerne les signatures, il s'agit d'aller plus loin que la prototype avec des paramétres nommés :

use feature qw(signatures);
no warnings qw(experimental::signatures);

sub hello($name) {
    print "Hello $name !\n";
}   

hello("DLFP");

Qui produit donc Hello DLFP !

On pourra donner des valeurs par defaut aux arguments :

sub fourchette($min = 0, $max = 10) {
    $min..$max;
}

print fourchette();

Qui affiche

012345678910

Le mécanisme d'arguments optionnels ne fonctionne pas de la même manière qu'avec les prototypes simples. Ici on n'utilise pas ; mais on donne une valeur par défaut a l'argument :

use feature qw(signatures);
no warnings qw(experimental::signatures);

sub hello($name, $age, $ville = undef) {
    print "Hello $name, ton age est $age";
    print " et tu habites $ville" if $ville;
    print "\n";
}   

hello("Tux", "23");

Et ca nous donne Hello Tux, ton age est 23 — oui Tux a 23 ans en 2019, il a été dessiné par Larry Erwing sur une idée d'Alan Cox et Linus Thorvald.

En conclusion je vous donne un très bon article de blog écrit par Brian D Foy sur les signatures si vous en voulez encore plus :D

Assignement

Des optimisations à l'assignement :

  • Optimisation de l'assignement de références entre elles.
  • Optimisation de l'assignement des hash/array (lorsqu'ils sont à gauche du égal)
  • Optimisation du split
Autre
  • Nouvel algo de hash pour les machines 64 bits. Clés courtes, variante de One At A Time Hard et clés longues Siphas 1-3. Perfs améliorées pour clés courtes et longues.
  • Meilleures performances des hash en contexte booléen.
  • La lecture des fichiers avec <> est plus rapide (code qui teste le retour à la ligne a été optimisé)
  • On utilise le COW plus souvent
  • Conversion chaine mono digit plus rapide.
  • À partir de 5.26.0 on applique le constant folding également pour les chaines. Donc my $s = "a" . "b"; est compilé comme my $s = "ab";

Changement internes

  • Time::HiRes module (timers très précis) est compilé avec C++11
  • Nouveau message d'erreur Version control conflict marker si perl détecte un marqueur de VCS comme un conflit git.
  • De nombreuses nouvelles fonctions pour gérer UTF8
  • Perl compile par défaut avec PERL_OP_PARENT qui permet à un opérateur de connaitre son parent
  • Des nouveaux opérateurs pour gérer les signatures de fonctions.
  • Une fonction op_class() pour connaitre la classe d'un opérateur
  • Sortie en ASCII art de op_dump()
  • Meilleur mode debug

Compilation

  • On en a parlé longuement déjà, nouvelle option -Ddefault_inc_excludes_dot pour ne plus ajouter . au @INC à l'exécution.
  • On peut désactiver PERL_HASH_SEED et PERL_PERTURB_KEYS. Désactiver c'est mettre le comportement de base tout simplement.

Si on donne une valeur à PERL_HASH_SEED alors on force la graine pour le côté aléatoire du parcours de hash. C'est potentiellement une mauvaise idée… et ça va forcer PERL_PERTURB_KEYS (si pas défini) :

  • PERL_PERTURB_KEYS = 0 alors traverser un hash se fait toujours de la même manière, même lors d'une seconde exécution de programme
  • PERL_PERTURB_KEYS = 1 alors traverser est totalement aléatoire
  • PERL_PERTURB_KEYS = 2 alors l'ordre des clés change à l'insertion mais de manière reproductible entre les exécutions de programme

Cela se fait à l'aide de cette variable configure -Accflags=NO_PERL_HASH_ENV.
Pareil pour PERL_HASH_SEED_DEBUG qu'on pourra désactiver avec -Accflags=-DNO_PERL_HASH_SEED_DEBUG

  • Fin du support de nombreux algos de hash non recommandés.
  • Plus de warning Warning: perl appears in your path car Perl est quasi toujours dans le path :)

Des améliorations au niveau du padding :

  • Mise à zéro pour l'alignement.
  • Format de sortie change pour perl -V
  • Fixes sur clang, gcc 6 flto et cross-compilation
  • PATH séparateur sur VMS devient : lorsque le shell est un shell Unix
  • Fin du support du format a.out. Je cite Linux has used ELF for over twenty years. :)
  • Toujours pas de support pour pid, gid, uid avec SA_SIGINFO sur OpenBSD 6
  • Un test qui ne finit pas est désactivé sur FreeBSD
  • Support de setproctitle() sur DragonFly BSD
  • Pas de support des nombres flottants infinis sur NetBSD. 98% des test sont bons.
  • D'autres trucs sur VAX, Hurd, HP-UX, EBCDIC, Darwin

Bugfixes

Parsing %::

Un bugfix sur un mauvais parsing de code comme use re %:=0. %: n'est rien mais %:: est le main stash (équivalent de %main::).

Si on déclare une variable sans my elle s'attache au main stash et on peut lister le contenu du main stash comme un autre hash :

perl -e 'my $toto = "a"; $tata = "b"; foreach my $k (keys %::) { print "$k\n"}' | grep "tata\|toto"
tata

# NB : toto n'est pas dans le main stash et un `foreach` sur `%:` ne fait rien du tout.

Ou accéder à la variable comme ceci :

perl -e '$tata = "b"; print "$main::tata\n"' 
b
Parsing de $foo::$bar

Le parsing de "$foo::$bar" a changé en 5.18. Le parsing "normal" consiste à traiter ça comme $foo:: . $bar, donc

my $foo = "abc"; my $bar = "def"; print "$foo::$bar"

produit def. Mais avec le changement de parsing $foo."::".$bar, ça donnait abc::def. Les perl porters n'étaient pas sûrs du bon comportement, mais partant du principe de rester cohérent avec $foo::%bar ils ont remis l'ancien parsing.

Regex recursion infinie

Dans certains cas, l'exécution de code embarqué dans une regex pouvait aboutir à une récursion infinie de la stack C (pas la même que la stack Perl). Un exemple de code est celui-ci /(?{ s!!! })/. Il faut que le pattern qui match soit lui-même.

Lorsque rien n'est spécifié c'est $_ qui est matché :

$_ = "toto"; print "Get it\n" if /to/;

nous donne donc Get it.

perl -le '/(?{ m##, s|||})/'
Segmentation fault (core dumped)

Pas besoin de préciser le premier m car le slash suffit mais le second m est obligatoire.
Au niveau fonctionnel ce code est un non-sens en tout cas.

LHS RHS

Changement de comportement dans le cas d'assignement avec RHS n’ayant pas assez d'éléments par rapport au nombre d'éléments LHS.

LHS et RHS signifient à gauche du égal et à droite du egal (cf LHS/RHS).

Dans le cas où on avait plus d'éléments à gauche on a bien le comportement normal de Perl qui fait du mieux qu'il peut et retourne un maximum d'éléments. Mais si un tableau s'était glissé dans le groupe alors seulement un élément était retourné.

La mort de "dollar dash"

Fix d’une utilisation du tas après un free ou un buffer overflow avec la variable dépréciée $# (plus d'infos sur cette variable). Attention $# n'est PAS $#array. On en reparle en 5.30.0

Autre
  • Plus de crash lors en utilisant setlocale avec certaines valeurs (bug libc).
  • Fix d'un memory leak avec les captures nommées (chercher par ici)
  • Un fix sur la commande magique et mystérieuse formline
  • Un autre fix sur un accès possible à de la mémoire libérée avec formline
  • Le combo regex et smart match ne fonctionnait pas bien (smart match converti en regex), c'est fixé
  • Fix bug dans des cas obscurs contenant ?{code} qui permet d'exécuter du code dans une regex
  • De même forcer un local dans un ?{} pouvait rester bloqué à la sortie.
  • use utf8 concerne bien le fichier dans sa globalité à présent alors qu'avant seules les parties entre quotes étaient concernées.
  • Fix range operateur .. pour fonctionner avec les unicode_strings
  • Bugfix d'une allocation insuffisante par split sans pour autant être un problème de sécurité (inexploitable…)
  • Bugfix implémentation de sort() avec des grands entiers
  • Fix coredump généré par chop ou chomp et ce genre de code chop(@x =~ tr/1/1/)
  • Un commentaire dans une regex avec modifier /x pouvait être ignoré parfois, c'est fixé.
  • Ignorer {}->$x plutôt que crasher quand $x n'est pas défini.
  • Des lectures de données non initialisées dans un cas très particulier de tr/// ou avec une backreference comme \1
  • Bugfix de crash possible ou réclusion infinie avec les forward déclaration comme sub c { sub c; }
  • Fix assertion failure dans des regex utilisant des regex_sets
  • Fix crash d'un code invalide comme \sort = 1.
  • Fix d'un crash possible avec evalbytes (vu en 5.24.3)
  • Fix d'erreurs de lexer.
  • Plusieurs problèmes de regex avec utf8 (crash avec s/// et buffer overflow)
  • Fix segfault avec option -DC (pas grave, c'est du debugging)
  • Fix lexer sur ce genre de chose (notez le backslash en dernier) print "<<`\". En fait l'interpreteur va lire trop loin car il ne trouve pas la fin (il est dupé par les caractères échappés).
  • Dans certains cas le tri en place @tab = sort { ... } @tab pouvait crasher. C'est fixé
  • Fix report de warning inapproprié avec pack("p", …)
  • Plus de memory leak sur des tests de définition de typeglobs (déjà parlé avant) comme defined *{'!'}
  • Le classique format %a du printf a eu de nombreux fixes et également le support pour subnormals (ou denormals) c'est à dire les nombres flottants à virgules très très petits.
  • Plus de warnings sur @DB::args. Profitons-en pour parler de DB qui est une interface pour accéder au debugger perl. Et @DB::args contient les arguments de la fonction courante. Warning présent qu'avec le switch -w et non le use warning blablabla
  • Plus de warning non plus sur les builtin tableaux. Le warning Possible unintended interpolation… était en fait lié au fait que les tableaux n'étaient pas déclarés (or ils n'ont par définition pas besoin de déclaration car intégrés à perl)
  • Fix d'une régression de 5.24 sur tr/\N{U+...}/foo/ avec le caractère compris entre 128 et 255. C'est fou le nombre de bugs autour d'Unicode… :/
  • Les délimiteurs de chaine c'est à dire le caractère spécial comme q// ou q?? ou qmm ne pouvait pas être un code point trop grand car confondu avec d'autres caractères. Dans les faits ça signifie que q\x{fffffff}machaine\x{fffffff} ne marchait pas.
  • Un code faux comme @{\cX (déréférencer un tableau caractère de contrôle) puis retour à la ligne crashait en plus de donner une erreur de syntaxe.
  • Fix d'un crash quand on joue avec les stash et typeglobs comme ceci sub P::f{} undef *P::; *P::f =sub{};. Fonction f dans stash P. Suppression du symbole P. Redéfinir fonction f dans symbole P inexistant.
  • Meilleur report pour /(?<=/ et /(?<!/ (séquence non terminée plutôt que assertion failure)
  • Meilleur report pour until quand on met = a la place de == (par exemple)
  • Fix bug du bitwise assignement quand on assigne dans un hash ou un array par exemple @array &= 0.
  • Bugfix d'un require conditionnel dans ce genre de cas inclure_ou_pas() ? require : require $_. C'est particulier, car en omettant l'argument de require on veut $_ bref c'était cassé.
  • Fix runtime erreur avec vec "Can't coerce" lorsque le premier argument de vec est un hash ou un tableau. A présent, l'erreur est à la compilation.
  • Meilleure erreur lorsqu'un \N { n'est pas fermé dans une regex.
  • Un fix sur un bug du lexer avec une fin de ligne avec un code UTF8 trop court.
  • Un bugfix sur UTF8 et les alternations dans les regex. Alternations kesako ? Simplement | :)
  • Pas d'erreur de compilation sur un do "monfichier\0dutexte" alors que perl doit partir en erreur.
  • Vous vous souvenez que le comportement de chdir (en 5.24.0) avait changé ou au moins avait été limite. Pour aller dans le home il faut maintenant faire chdir sans argument.
  • Lorsqu'on fait un undef du typeglob du tableau courant comme ceci sub f() {undef *_; shift} f(); perl crash. Attention, ça ne crash que dans une fonction.
  • Le parsing des classes de caractère POSIX peut entrainer une fuite mémoire. Une classe de caractère POSIX est une sous sorte de classe de caractères.

Problèmes connus

  • Déjà mentionné dans Compilation/Plateforme mais travailler avec des virgules flottantes très très petites peut être arrondi a zéro tout simplement (à cause de g++ 6)

5.26.1

Sécurité

  • [CVE-2017-12837] Bugfix d'un possible buffer overflow lorsqu'une regex avec modifier case-insensitive et une expression \N{}
  • [CVE-2017-12883] Bugfix d'un buffer overflow avec une erreur de syntaxe comme par exemple \\N{U+.}.

MAJ de modules

Encore du travail sur le module base.pm vis à vis de la suppression du répertoire courant dans @INC

Compilation

  • Fix build avec g++ sur FreeBSD. Le compilateur par défaut pour FreeBSD 11 et FreeBSD 12 semble être clang.
  • Fix modules XS compilation avec gcc 6 en 64-bits

Bugfixes

  • Fix cas de panique lors de certains cas de return de fonctions. Par exemple ce code sub test { my @x; (@x,@x); }; test(); (il faut que les tableaux soient vides).
  • Une référence symbolique combinée avec une post déréférencement (->@* ou ->%* ou ->$*) produisait une assertion failure alors qu'il ne faut pas. Attention les symbolic ref sont déconseillées à l'usage notamment si on utilise use strict.
  • Bugfix sur un assignement de liste. En rapport avec la stack de la mort (f3ar !). Plus d'infos en 5.28.0.
  • Fix d'un crash de perl quand on veut mettre un attribut à une variable globale mais qu'une fonction existe déjà avec ce nom. Je pense que les attributs sont en quelque sorte des decorators. Les attributs sur les variables globales sont gérés à la compilation. On trouve plus d'explications ici.
  • Tenter d'exécuter une référence de fonction qui a été déclarée à travers un typeglob sur le stash main comme ceci $::{"A"} = sub {}; \&{"A"} peut produire un crash (il faut aimer le risque). C’est fixé.
  • Bugfix sur atof2().
  • Des bugs occasionnels sur certains caractères UTF8. Le bug est initialement reporté par Benjamin Bayart sur la liste debian puis géré dans le gestionnaire de tickets Perl. Bugs occasionnels car ça crash 50% du temps environ.
  • La mise en place du code pour gérer les exceptions perl est paresseuse, tellement paresseuse que certaines exceptions pouvaient apparaître avant la fin de la mise en place et le code pouvait sauter à une adresse pas encore bien configurée et crasher. C’est fixé :)
  • Une régression (malgré un cas de test) sur le parsing des classes de caractères POSIX. perl simplement reportait des warnings là où il n'y a pas lieu d'être.

5.26.2

Sécurité

  • [CVE-2018-6797] Un fix sur encore un problème de regex avec \N{U+0}. Quand on lit le ticket, honnêtement on peut tirer son chapeau à ces uber programmers qui arrivent à fixer ce genre de problème.
  • [CVE-2018-6798] Possible buffer overflow avec une regex contenant \x{nombre} avec modifier case insensitive applique sur une autre valeur \x{nombre}
  • [CVE-2018-6913] Problème avec pack avec un nombre d'item très large. On a déjà vu ça par le passé, mais c'était pas la même root cause.

Bugfixes

Regex alambiquées

J'aime le terme utilisé pour décrire les regex qui produisent ce bug. Il est dit convoluted kinds of regexp qui se traduit par alambiquées. À quoi ressemble une regex alambiquée ? Eh bien ça ressemble à ça :

'0(0?(0||00*))|'
Rapport d’erreur et arrêt plus précoce

Plutôt que d'essayer de donner de meilleurs messages d'erreur en crashant parfois, certaines erreurs vont être reportées plus tôt et s'arrêter ensuite.

Comme on peut voir, de très nombreux bug fix concernent du code incorrect. Un code qui crash peut au minimum est utilisé pour faire un DoS, donc il faut le prendre au sérieux.

Autre
  • Plus de vérifications à la compilation pour readpipe(), ça évite la corruption à l’exécution.
  • Fix un use-after-free bug lorsqu'on a des espaces et des retours à la ligne après une déclaration partielle de fonction.
  • Un fix du tokenizer sur le parsing des identifiers avec espaces.
  • L'aliasing des variables $a et $b variables magiques au sein d'un sort était mal fait et un nouvel alias n'était pas forcement compté alors qu'un unalias était bien noté. Cela pouvait entrainer un free sur variable alors qu'elle n'était plus comptée comme utilisée et perl n'était pas d'accord.
  • Bug avec -flto et -mieee-fp. -flto on en a déjà parle (optimiser la vitesse de compilation) quant à -mieee-fp, il sert à Contrôler ou non si le compilateur utilise des comparaisons à virgule flottante IEEE. Ce qui permet de gérer correctement le cas où le résultat d'une comparaison est non ordonné. (man gcc)

5.26.3

Sécurité

Faille dans Archive::Tar

[CVE-2018-12015] Un bug intéressant. L'implémentation de tar dans Perl est Archive::Tar qui permet de faire tout ce que vous pouvez faire en ligne de commande. Normalement Archive::Tar empêche d'extraire en dehors du répertoire courant mais une feinte avec un symlink permet de bypasser facilement cette limitation.

Je reprends l'exemple très bien expliqué du ticket de Jakub Wilk :

tar -tvvf traversal.tar.gz

lrwxrwxrwx root/root 0 2017-09-30 15:36 moo -> /tmp/moo
-rw-r--r-- root/root 4 2017-09-30 15:36 moo

pwd
/home/jwilk

ls /tmp/moo
ls: cannot access '/tmp/moo': No such file or directory

perl -MArchive::Tar -e 'Archive::Tar->extract_archive("traversal.tar.gz")' 

ls /tmp/moo
/tmp/moo
Autre
  • [CVE-2018-18311] En mettant une valeur très grande dans une variable d'environnement par exemple une très grande chaine composée de la même lettre 0xFFFFFFFF fois on peut écrire après le buffer alloué. C’est fâcheux.
  • [CVE-2018-18312] (basé sur \x), [CVE-2018-18313] (basé sur \N{}) et [CVE-2018-18314] (base sur les classes de caractère étendus) Des regex peuvent crasher à la compilation et lire après le buffer ou bien écrire après

Sortie de Perl 5.28

5.28.0

Améliorations du core de perl

Hash slices et slices clé/valeur

En 5.20.0 ont été ajoutées 2 nouvelles sortes de slice : les key/value hash slices et les index/value array slices. Ces 2 sortes de slices s'appliquent sur un hash contrairement aux slices de base.

Les key/value hash slice sont en fait un façon d'obtenir un sous ensemble d'un hash par exemple en faisant my %petit = %grand{'cle1', 'cle2'}; qui va sélectionner les deux paires de clé/valeurs pour faire un nouveau hash.

Les index/value array slice suivent un peu le même principe mais on sélectionne avec les index et on récupère une liste index/valeur. Voici un exemple : @petit = %grand[1,3];
Les slices standard (si on peut dire) s'appliquent sur les tableaux et permettent également de récupère un sous tableau :

perl -e 'my @joueuses = ("le sommer", "gauvin", "henry", "thiney", "cascarino"); print join " ", @joueuses[1,3,4]; print "\n";'
gauvin thiney cascarino

Avec 5.28.0 on peut maintenant utiliser delete sur les array slices et hash slices c'est à dire pas du tout ce que je viens de présenter :-) Un exemple :

my %hash = ( cle1 => "valeur1", cle2 => "valeur2", cle3 => "valeur3" ); delete @hash{cle2}; foreach my $k (keys %hash) { print "$k\n";}

qui donne

cle3
cle2

Attention, comme on peut le voir, le sigil a changé c'est bien @hash{} avec un arobase. En Perl, il peut exister @var, $var et %var simultanément.
Pour s'en convaincre, ajoutons une autre variable @var :

my @var = ("a", "b"); my %var = ( cle1 => "valeur1", cle2 => "valeur2", cle3 => "valeur3" ); delete @var{cle2}; foreach my $k (keys %var) { print "$k\n";} print @var;

qui donne

cle1
cle3
ab
Regex lookaround

Des synonymes pour les expressions lookaround qui sont des expressions regex pour tester des choses comme :

/foo(?=bar)/

je veux le mot foo suivi par le mot bar mais sans l'inclure dans le match.

Quel est l'avantage des lookaround assertions ? (oui assertions car on parle de tester sans consommer le caractère)

En fait examinons un cas simple ou je veux matcher un a qui n'est pas suivi par un b. Si j'utilise une classe de caractère avec négation a[^b] ça signifie un a SUIVI par quelque chose et cette chose est autre chose que b… Donc la chaine "archlinux" va matcher et le match va contenir "ar". Mais la chaine "fedora" ne va pas matcher… Car il n'y a rien après le "a". Grâce à un lookaround assertion comme ceci a(?!b) (lookahead negatif) on va matcher les deux chaines et on aura bien que le "a" même pour "archlinux".

Autre
  • Support de unicode 10.0 qui ajoute environ 8500 caractères dont le signe bitcoin, des émojis encore dont la tête qui explose et les magiciens/fées/sirènes
  • Meilleure gestion des unicode script run
  • L’édition en place avec -i devient safe. Une copie du fichier à traiter est faite pendant le travail. perl -i.bak va prendre le fichier en entrée et s'en servir comme output (en faisant au préalable un backup ici avec l'extension .bak. Si on ne précise pas d'extension, le mode legacy unsafe est utilisé.
  • Une variable lexicale persistante peut maintenant être déclarée et initialisée si c'est un tableau ou un hash par exemple state @a = qw(x y z). Une variable persistante c'est une variable qui garde sa valeur entre les appels de fonction.
  • Sur les plateformes qui utilisent des inodes plus grandes que le type entier natif de Perl, Perl gère maintenant ces inodes dans des chaines.
  • Une petite amélioration concernant sprintf %j (choisit la taille du champ)
  • Les filehandles sont plus souvent ouverts avec le flag close-on-exec ce qui protège de passer accidentellement le filehandle à un autre programme.
  • La feature bitwise en 5.28.0 n'est plus expérimentale !! Hourra !!
  • Le changement de locale est thread safe sur les plateformes qui le gèrent. La variable ${^SAFE_LOCALES} sert justement à dire si la plateforme est locale thread safe ou non.

Sécurité

  • On retrouve les CVE de 2.26.1 donc [CVE-2017-12837], [CVE-2017-12883] et [CVE-2017-12814]
  • En 5.26.0 de nombreux algo de hash ont ete retirés des options Configure. En 5.28.0 ajoute des options pour configurer les principaux algos :
    • -DPERL_HASH_FUNC_SIPHASH
    • -DPERL_HASH_FUNC_SIPHASH13
    • -DPERL_HASH_FUNC_STADTX
    • -DPERL_HASH_FUNC_ZAPHOD32
    • -DPERL_HASH_USE_SBOX32_ALSO=0
    • -DSBOX32_MAX_LEN=16

Changements incompatibles

Here-docs sans delimiteur

Généralement on utilise les heredocs avec un texte de fin comme END. Mais on peut également utiliser une ligne vide comme délimiteur :

my $var = <<"";
toto

print $var

Ou encore la version implicite :

my $var = <<;
toto

print $var

Cette dernière version était dépréciée et devient interdite.

Readline delimiteur

Mettre une valeur bizarre dans $/ qui sert à dire à Perl quel est le délimiteur de ligne (quand on lit ligne par ligne). Il n'est plus autorisé de mettre une valeur négative. Cette valeur est utilisée par le readline ou <> et également par chomp(). Exemple si on dit à Perl que le séparateur de ligne est la lettre b :

$/ = "b";
while(<>) {
    print "[$_]\n";
}

Et on pourra tester avec un :

echo -n "ababa" | perl sep.pl

Le séparateur peut être plusieurs lettres ou undef dans ce dernier cas un readline va simplement lire toute l'entrée en une fois. Petite précision, le contenu de $/ ne peut pas être une regex.

Yada yada usage restreint

L'opérateur yada yada qui sert de placeholder pour le code non implémenté (lance une exception unimplemented). Il était accepté comme expression autorisant ce genre de chose ... . "toto" Or il ne doit être accepté que comme statement. Pas de panique (oui j'en vois qui paniquent xD), on pourra toujours simuler une expression avec do{...}.

Algo de tri

Les subpragamata de sort pour choisir l'algorithme de classement disparaissent. Restent le pragma sort pour spécifier la stabilité du classement :

use sort 'stable';          # guarantee stability
use sort 'defaults';        # revert to default behavior
no  sort 'stable';          # stability not important
Autre
  • Changements dans le feature expérimentale des signatures et les attributs (l'attribut ne se place plus au même endroit)
  • Attribut :locked et :unique supprimés. Ces attributs étaient utilisés pour le multithreading, or la gestion du multithreading a changé et ces attributs ne servent plus à rien depuis longtemps. C'était prévu depuis 5.12 et 5.10, il fallait s'y attendre :D
  • L'expression vide \N{} devient fatale. Cette expression ne fait strictement rien.
  • Ouvrir un filehandle et un dirhandle dans la même variable n'est plus autorisé.
  • Interdiction de donner des codes Unicode au-delà de IV_MAX (dépend de la plateforme). Plus d'infos sur l'entrée dans perldeprecation
  • B::OP::Terse disparait au profit de B::Concise::b_terse. Le module B est un core module qui sert à aller fouiller dans le backend du compilateur de Perl.
  • Une feature accidentelle de AUTOLOAD est supprimée. Qu'est-ce exactement qu'autoload ? L'autoloading est une façon de définir un comportement par défaut pour les fonctions non définies.
  • Plus de backslash pour échapper les : dans le PATH (sécurité…)
  • Plus d'option -DH pour builder perl, c'est cassé depuis longtemps.
  • En octal ou binaire il était possible de donner des nombres hors base après la virgule dans un nombre a virgule flottante. Ce bug est fixé.
  • Changement de comportement de unpackstring() en C.

Dépréciations

Démarrer ses tableaux avec un index original

Changer la valeur de *`{mathjax} [** va devenir interdit. Cette variable magique permet de changer l'index de départ d'un tableau (pour s'amuser ou pour s'approcher du style de certains autres outils comme fortran). En effet, la philosophie de Perl est TIMTOWTDI (Tim Toady) mais dans ce cas bien précis, changer la valeur de *`[** dans un coin d'un programme peut rendre un programme totalement illisible et pose des problèmes de maintenabilité donc. On peut utiliser un autre module pour faire ça si on en a vraiment besoin. On peut suivre la vie de $[ sur perlbanjo.

Autre
  • On ne doit plus utiliser vec avec des chaines ayant des points de code après 0xff car leur représentation se fait en UTF8 et vec travaille sur des bits.
  • En 5.26.0, l'usage des accolades non échappées dans un regex devenait fatal. Fait intéressant, ça avait cassé GNU autoconf et c'est un cas intéressant de gros logiciel qui fait plier une dépendance puisque Perl a fait un fix de dernière minute pour être plus laxiste vis à vis des accolades. Ce fix est désormais appliqué pour tout le monde :)
  • Bientôt plus d'arguments pour hostname()

Mises à jour de modules

Suppression de Local::Codes du core

Suppression prévue de Local::Codes. La suppression est demandée par son auteur, Dans le cadre de cette suppression et comme discuté sur la liste, les autres modules cpan qui consomment cette dépendance doivent se mettre à jour et il est donc nécessaire de les prévenir. J'en profite pour glisser un lien qui permet de lister les dépendances DECLAREES d'un module cpan. Les modules qui posent problème n'apparaissent pas dans cette page.

Autre
  • Suppression de B::Debug.
  • Suppression du pragma use vars partout où c'est possible.
  • Remplacer DynaLoader par XSLoader. Dynaloader et XSLoader sont des modules Perl pour faire du dynamic linking en gros du dl_open.
  • MAJ de Archive::Tar suite au fix de sécurité en 5.26.?.?
  • MAJ de B::Deparse et fix bug avec les attributs
  • MAJ Carp. Bug fix sur la constante ISA, le comptage des références et l'overloading.
  • MAJ de zlib pour fixer un problème de sécurité de la lib zlib
  • Amélioration de Data::Dumper output
  • Devel::PPPort prend du grade et devient core module
  • File::Copy utilise Time::HiRes si possible
  • POD::Html génère un title
  • On fait plus attention aux locales dans le module POSIX.
  • XSLoader doc
  • Suppression compatibilité VMS::stdio

Performances

Multi Concat

Les concaténations multiples sont optimisées donc

my $var = "a"; $var .= "$b $c $d\n"

est vue comme une seule concaténation.

En parlant du temps de concaténation, on perd en performance des qu'on mélange constantes et variables et utf8 et non utf8 chaine mais c'est aussi là qu'il y a le plus à gagner en terme de performances :) sprintf aussi bénéficie de cette amélioration.

Require

Appeler require sur un module déjà chargé est plus rapide. require est une fonction qui permet soit de spécifier une version Perl, soit d'exécuter un code externe. Voici une belle explication stackoverflow sur la différence entre do/use/require mais en gros :

  • use : lit fichier, vérifie, exécute et fait import
  • require : lit fichier une fois, vérifie et exécute
  • do : lit et exécute fichier
Autre
  • Perl plus rapide au démarrage de la compilation des p{} (propriétés unicodes)
  • ref() devient plus rapide car il ne construit plus la représentation chaine de caractère.
  • keys appliqué sur rien ou sur une variable qui n'est pas un hash est plus rapide.
  • Le classique if(index() != -1) { #J'AI PAS TROUVE :/ } est optimisé
  • Optimisation des boucles for (et foreach car je rappelle que for et foreach sont des alias en Perl)
  • Le core module File::Glob recoit des optimisations. Ce module sert à faire ce genre de chose my @sources = <*.{c,h,y}>; soit les BSD glob routines.
  • Optimisations sur des fonctions retournant des entiers qu'on utiliserait par exemple en contexte booléen.
  • Petite optim sur le parsing des noms de symboles
  • Meilleures perf pour les classes de caractère ascii [[ascii]].
  • Des optimisations sur certaines regex. Dans de bonnes circonstances, on peut gagner pas mal.
  • D'autres optimisations concernant la gestion d'UTF8

Compilation et plateformes

  • C89 minimum requis ! Documente depuis 1998
  • Option GCC -Werror=pointer-arith par défaut. On peut toujours faire de l'arithmétique de pointers, mais pas avec n'importe quoi
  • Ajout d'un .travis.yml pour que les devs qui forkent perl sur github puissent avoir le build dans Travis CI. Le git officiel de Perl5 est sur git.perl.org mais il y a un miroir sur github
  • Plus de support du format .bz2, seuls les formats .xz (compresse mieux et plus vite) et .gz (peu gourmand en mémoire) seront utilisés
  • Centos 5 fixé
  • Suppression de PowerUX et Power MAX OS
  • Cygwin <3 quadramath
  • Perl utilise correctement les fonctions réentrantes de Darwin
  • Perl s'aligne sur -O2 sur FreeBSD

Changements internes

Weak references

Nouvelle fonction sv_rvunweaken() qui complète sv_rvweaken(). Weaken ou unweaken sont en rapport avec les weak references.

Une weak référence en Perl n'incrémente pas le compteur de référence pour l'objet, et donc ne protège pas l'objet d'une garbage collection destruction à cause du compteur de référence qui fait son ménage.

Les références sont liées à leurs scopes donc une variable dans une boucle pourra être détruite dès la sortie de la boucle.

UTF8 invariance

Ajout de la fonction is_utf8_invariant_string_loc qui fait comme is_utf8_invariant_string mais assigne l'index de l'endroit où on trouve le premier caractère variant.

Si j'ai bien compris le principe, il s'agit de vérifier les caractères qui sont encodés de la même manière en ASCII ou en UTF8 c'est à dire que A est code 01000001 en ASCII et 01000001 en UTF8 donc c'est invariant.

Mais é est codé 11101001 en ASCII et 11000011 10101001 en UTF8 donc c'est variant.

Changement de locale

Nouvelle fonction sync_locale pour synchroniser les threads au niveau du local même si la doc précise que changer la locale est antisocial et dangereux sur les systèmes multi-threadés qui n'ont pas d'operations locales multi-thread safe.

Autre
  • L'outil perlbug qui sert à envoyer des rapports de bugs, reçoit un argument --help et --version. Vous n’avez plus aucune bonne raison de ne pas reporter un bug si vous en découvrez un.
  • Amélioration du multithreading
  • Nouveau flag SORTf_UNSTABLE pour forcer le comportement instable du mergesort lorsqu'on spécifie no sort stable.
  • Pour les modules XS donc non pure-perl on peut spécifier #define PERL_REENTRANT pour que les fonctions reentrantes soient utilisées (et ce de manière transparente).
  • En 5.26.0 le build par défaut se faisait avec PERL_OP_PARENT qui permet à un opérateur de connaître son parent. À partir de 5.28.0, son contraire PERL_NO_OP_PARENT n'est plus supporté.
  • Nouveau define pour le compilateur THX_DEBUGGING qui permet d'avoir le thread contexte pour le XS et C
  • Nouvelle fonction setlocale qui est thread safe.
  • Nouvelle sorte de scalar magique, le nonelem scalar

Correction de bogues

La stack de la mort

Dans certains cas très rares un assignement de liste pouvait faire l'allocation sur la stack de la mort (ou mortal stack) au lieu de de l'allouer correctement. Cela laissait l'entrée non assignée et pouvait provoquer un crash.

D'après la documentation : Pour une ref, être "mortelle" signifie qu'elle est possédée par la stack temporaire, une des nombreuses stack internes de perl, et qu'elle va être détruite "dans pas longtemps". (cf perlguts)

Stringification

Un peu de fork. Depuis 5.16.0, la stringification des arguments de system se faisait plus tard et donc on a ce comportement :

print $$;
system 'echo', "$$";
system 'echo', $$;
32480
32480
32488

Notez bien le dernier, la conversion de

$$

en

"$$"

se fait dans le fils et non le parent.

Ce fut l'objet d'un fix en 5.28.0

eval fait son ménage

eval fait mieux le ménage en nettoyant par exemple $@ qui contient le message d'erreur d'eval.
C'est débile vous allez dire ?! Car on veut cette valeur si le eval n'a pas réussi… Oui et non (spoiler c'est non) : si on enchaine les eval, par exemple le premier eval plante puis le second est un succès (donc ne met rien dans cette variable), alors on aura une variable $@ polluée avec le message d'erreur du premier eval.
C'est donc utile dans le cas de eval imbriqués.

Autres
  • Meilleure gestion de split avec Unicode. En gros, les caractères Unicode codés sur un byte mais n'étant pas du ASCII et représentant un espace n'étaient pas reconnus par split.
  • Les variables magiques de capture de regex peuvent être indexées dans les chaines donc "${^CAPTURE[0]}" peut être utilisé pour aller chercher le premier élément du tableau @{^CAPTURE}
  • Si une variable avec un nom en UTF8 était déclarée comme symbole puis supprimée et déclarée mais sans UTF8, alors elle était toujours flaguée UTF8. On parle bien du nom de la variable.
  • sprintf retravaillée pour corriger des petits bugs sur la spécification de longueur et la représentation d'entier larges. Et la fonction est plus rapide également !
  • Perl partait en erreur si aucun exposant n'est donné dans ce genre d'expression 1e--3.
  • Une regex de match comme ceci m/$nada/ avec $nada qui est juste vide ne va plus ajouter le modifier /o si le match précédent l'avait. En parlant des autres modifiers, voilà ce que dit la doc a propos de /o : "prétend optimiser votre code, mais en fait introduit des bugs" :D :D :D
  • Jouer avec les opérations I/O sur des non-glob fait des erreurs avec ${^LAST_FH}. C'est fixé
  • Certaines fonctions XS font de meilleures vérifications (tester si le pointeur donné en paramètre est nul) pour éviter des comportements indéfinis.
  • Pour donner des valeurs par défauts aux paramètres d'une fonction (donc en mode signature expérimental) il faut utiliser =. D'autres operateurs étaient possibles, mais par erreur.
  • Les warnings émis par prototype incluent à présent le package.
  • Fix bug avec exec lorsque LIST est vide comme ça : exec {"true"} ()
  • On peut de nouveau exécuter des commandes d'une seule lettre avec l'argument concatène dans le debugger comme p$^V.
  • Splice devient consistant avec push et renvoie une erreur si on essaie de la faire travailler sur un tableau read only.
  • stat (plein d'infos sur un fichier) et lstat (pareil mais sur un symlink). Et la variable magique $! est bien settée si un problème arrive.
  • Lorsqu'on fait des tests sur un fichier et que certaines opérations ne sont pas possibles car n'existent pas sur cette plateforme, Perl va d'abord vérifier si le fichier existe et éventuellement donner un message d'erreur plus fin avant de se précipiter à dire "pas dispo sur cet OS de faible".
  • Encore des bugfix en rapport avec \N{} soit un leak de mémoire quand c'est vide, soit un problème avec le transliteration operator in perl (c'est le nom de tr///)
  • Essayer d'exécuter un répertoire ou un device de block avec do c'est con, mais bon perl retourne à présent un message d'erreur compréhensible.
  • Alors là accrochez-vous, dans une regex de substitution, si on met du code qui retourne un texte à l'aide d'une fonction overloadée comme "", alors on avait un problème de taintification (gestion des inputs safe/non safe).
  • Un autre problème avec do et la déclaration de fonctions lexicales qui pouvaient altérer la stack.
  • Support de 64 bits pour pack et unpack
  • Fix d'une possible corruption de stack avec reverse sans argument. Un problème de réallocation qu'on peut mettre en valeur avec for$0(0..1000){()=(0..$0,scalar reverse)} (reverse travaille dans ce cas sur $_).
  • Plus de problème de réentrance avec system, exec et leurs amis.
  • Fix un problème grave d'allocation d'une grande quantité de mémoire sur une machine 64 bits (> 1 Giga)
  • Fix un crash avec les tests de fichiers empilés dans un sort (oui on peut trier sur beaucoup de choses exemple sort { -s $a <=> -s $b } @files). On pouvait reproduire le crash avec sort{ -s -s -b } () tout simplement.
  • Fix d'un comportement indéfini parfois quand perl lit un chiffre qui est tellement peu significatif qu'il ne peut modifier la valeur du nombre à virgule.
  • open en plus d'ouvrir un fichier, crée un filehandle et l'ajoute à la table des symboles. Donner une valeur bizarre, peut aboutir à un memory leak. C'est le cas de open $$scalarref et c'est l'objet du fix.
  • Bug fix sur les typemaps. Un typemap est une façon de représenter les input/output des fonctions C à interfacer.
  • L'arrondi des nombres à virgule avec perl est à présent juste (printf %.0f)
  • Fix une erreur Cannot printf Inf with 'c' quand un tableau commençait par Inf et qu'on avait une autre erreur
  • getcwd est amélioré (retourne si erreur, set correctement $!)
  • Un très vieux bug (2002 !!) fixé au sujet de la vivification des tableaux
  • Un autre très vieux bug (2001) fixé à propos d'accolades optionnelles et de déréférencement
  • Des bugs sur tr/non_utf8/long_non_utf8/c avec des caractères de remplacement trop grands et aussi sur tr/non_utf8/non_utf8/cd à cause des modifier cd
  • Bugfix sur un problème de nombre à virgule flottante avec un séparateur qui n'est pas un point en environnement threadé (quel rapport ?)
  • Fix certaines assertions failures dans la compilation de regex qui doivent être simplement des erreurs de compilation.

5.28.1

Sécurité

[CVE-2018-18311] : Un overflow lors d'une addition d'entiers dans la fonction Perl_my_setenv() :

void Perl_my_setenv(pTHX_ const char *nam, const char *val) {
...
         const int nlen = strlen(nam);
...
         vlen = strlen(val);
         new_env = (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char));

nam et val sont la paire clé/valeur et ici en donnant une ou des valeurs très grandes on peut obtenir un overflow d'entier. On alloue alors trop peu de place et ensuite quand on utilise nlen et vlen pour des memcopy on écrit hors de la mémoire allouée.

[CVE-2018-18312] : Un sérieux bug qui peut faire un buffer/heap overflow. C'est à cause d'une regex mal parsée. Et en ajoutant des caractères de contrôles non ASCII, on peut déplacer le curseur dans la mémoire. Vous voulez un exemple ? Vous êtes sûrs ?
OK (désolé)
(?[(?^:(?[\\\x00]))\\]\x00|2[^^]\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80])R.\\670

Corrections de bogues

  • L'optimisation faite en 5.28.0 sur la comparaison d'index -1 (souvenez-vous if(index() != -1) { #J'AI PAS TROUVE :/ }) produisait un warning dans la construction when. C'est fixé
  • Un bug dans le matching regex de décimaux par le biais des scripts run
  • Problème avec l’édition en place (option -i) qui a été changée en 5.28.0. Il y avait un nombre limité de fichiers après quoi ça ne marchait plus.

5.28.2

Changements incompatibles

Un changement sur les scripts run dans les regex. C'est un changement incompatible sur une "release patch" mais c'était tout simplement cassé alors ce n'est pas un problème.

Compilation et plates‐formes

Compilation sur MAC OS X avec -Duseshrplib fonctionne avec SIP (System Integrity Protection = réduction des droits de root, certaines variables d'env pas partagées ce qui pose problème pour le chargement dynamique de libperl, pendant le build).

Corrections de bogues

  • L’édition en place avec -i est mieux gérée si le programme s'arrête mais n'a pas d'erreur, le fichier est bien écrit.
  • Fix régression de 5.28.0 lorsqu'on stdin dans le parent puis on rouvre dans l'enfant close(STDIN); open(CHILD, "|wc -l")'. C'est parce que stdin était fermé dans l'enfant aussi.
  • Fix un bug avec pack "u" quand il n'y a pas de deuxième argument. La valeur retournée était mal terminée. pack "u" c'est pour uuencode ça vous rappelle peut être quelque chose ? Moi des bouts de textes dans les ezines
  • Fix un bug avec formline et un format mal terminé.

Sortie de Perl 5.30

5.30.0

Le 22 mai 2019, Sawyer X a annoncé la sortie de Perl 5.30.0.

Améliorations du cœur de Perl

Lookbehind à longueur variable

On a déjà parlé des expressions de regex lookaround eh bien 5.30.0 accueille une nouvelle feature concernant les lookbehind (donc le lookaround vers l'arrière).

Il s'agit des lookbehind à longueur variable c'est à dire par exemple

/(?<=a{1,6}b)\w+/

On peut donc faire ça avec cependant une limitation de longueur à 255. Et un warning est émis car le comportement n'est pas forcement bien définitif.
Cette limite s'applique uniquement au lookbehind car il n'y a pas de limitation de ce genre en lookahead.

Et pour conclure, une méthode pour émuler cette feature existait déjà dans les versions précédentes de Perl mais c'était compliqué (le lien c'est pour les guerriers).

AdopteUnEmoji

Support de unicode 12.1… Pourquoi pas unicode 11 ?
Parce que unicode a changé son cycle de releasing donc ça rajoute unicode 11.0 (684 nouveaux caractères) ainsi que unicode 12.0 (554 caractères) et unicode 12.1 qui ajoute exactement 1 caractère.

Au fait, savez-vous qu'on peut adopter un caractère unicode ? Google a par exemple adopté l'émojis burger, IBM le nuage, Ford des voitures et ballantine's… devinez :D

Autres
  • Toujours côté regex, la limite de longueur variable des expressions (quantifiers) passe à 65534 dans les expressions de ce type {n,m}. En ce qui concerne la version sans max comme ceci {n,} la valeur du max dépend de la plateforme (mais est plus que 65534, en général 2**31 - 1)
  • Une restriction sur la compilation des regex entre simples quotes est levée. Il s'agit de qr'\N{name}' qui est n'est plus interdit donc.
  • Meilleure gestion de la casse avec l'UTF8 et la langue turque qui est visiblement spéciale de ce côté-là.

Changements incompatibles

Mort de certaines variables magiques

L'utilisation de $* et $# sont interdites :

$* servait à faire du multi line matching. Mais depuis longtemps les modifiers /m et /s font le même job. Quant à $#, il a deux sens : l'un pour formater les nombres (celui-là est donc interdit maintenant), l'autre pour obtenir le dernier index d'un tableau, comme ceci (celle-là ne risque pas d'être dépréciée) :

my @a = qw(a b c);
print $#a;

L'utilisation supprimée peut être obtenue avec printf ou sprintf et la raison de supprimer cette feature est de libérer $# pour un possible nouvel usage.

Index de départ des tableaux

Comme prévu, c'est devenu interdit de changer la valeur de `[. Pour résumer, cette variable qui permet de changer l'index de départ d'un tableau (déjà parle en 5.28.0, details sur cette variable). En fait on peut assigner quelque chose dans $[ mais seulement la valeur "0"…
L'important c'est d'avoir l'impression d’être libre :)

Autres
  • Depuis 5.24.0 on avait un warning pour sysread(), syswrite(), recv() et send() si on les utilisent avec un filehandle marque :utf8. A partir de 5.30.0, c'est tout simplement fatal ! C'est intéressant de voir le cycle d'interdiction sur le ticket car il y a d'abord eu un warning et ça a laissé du temps pour les modules qui utilisaient cette "misfeature" d'être adaptés (c'est le cas du module File::Slurp).
  • On ne peut plus faire de ce genre de déclarations my $x if 0. Mais attention une déclaration comme my $f = 0; my $x if $f marche toujours.
  • Utilisez CORE::dump() a la place de dump()
  • Le wrapper File::Glob::glob() ne faisait qu'appeler File::Glob::bsd_glob() tout en ressemblant a CORE::glob(). Pour éviter la confusion, il faut utiliser la fonction wrappée et non le wrapper.
  • La fonction pack va croak (warn and die) plutôt que de générer de l'UTF8 malformé.
  • Le comportement par défaut du core module JSON::PP a changé et maintenant allow_nonref est active. Ce qui est beaucoup plus pratique.

Securité

Rien :)

Dépréciations

L'utilisation de certaines macros pour gérer UTF8 dans du code XS est reporté à 5.32.0.

Performances

Meilleure transformation UTF-8 vers Unicode code point

La transformation de UTF-8 vers le code point représenté (regardez des exemples de correspondances dans cette table de caractères) utilise maintenant un automate fini déterministe. Cela permet un gain de plus de 10 % du nombre d’instructions par traduction. Le même genre d’amélioration est appliqué lors des vérifications de validité UTF-8.

Plus de dépassement de pile sur les fonctions gigantesques

Des fonctions très très grandes (taille du code dans le corps de la fonction) pouvaient générer un stack overflow. C'est dû à une récursion dans le code qui analyse. Pour donner une idée de très très grand, il s'agit d'un code avec 100000 elsifs. La récursion a été supprimée en 5.30.0.

Optimisation sur le character folding

Des optimisations des classes de caractères et le character folding. C'est quoi le character folding ? Il s'agit, par exemple lors d'une comparaison, de passer une chaine en minuscule ou d'enlever les accents.

Autres
  • Optimisation de la conversion de IV vers UV. IV est une variable interne à perl pour contenir un pointer. UV est la même chose en unsigned.
  • Optimisation de la conversion en chaine d'un entier en prenant 2 chiffres à la fois (moins d'instructions).
  • Le code de perl est passé dans un outil d'analyse (LGTM) et certaines remarques (on peut voir les alertes sur la page lgtm de perl)
  • Optimisation de la regex qr/[^a]/ et les choses similaires. L'optimisation ne concerne pas toutes les valeurs après la négation, seules celles en ASCII. Les autres pourraient en bénéficier mais demandent trop de spécialisation du code.

Mises à jour des modules

  • MAJ de File::Find : la valeur par défaut de dont_use_nlink est 1 soit ne pas faire confiance au filesystem et faire plus de vérifications pour bien traverser les filesystem.
  • MAJ IO::Compress pour ajouter le support de l'algorithme de compression Zstandard et LZMA
  • MAJ de Math::Bigint pour modifier bnok (binomial coefficient). Math::Bigint est un module pour gère les entiers de taille arbitraire dans sans la limitation des 4 bytes.
  • Moins de warning sur PerlIO::encoding sauf si on les demande.
  • Possibilité d'être en mode "non-interactif" pour le module Storable (qui normalement demande des valeurs limites pour la limite de récursion ou l'allocation par exemple)
  • Toujours Storable, dans le cadre du fix de [CVE-2015-1992], un code malicieux mais pas dangereux était fourni en test de perl. Comme une sorte de vaccin en fait… Or il était reconnu par certains antivirus comme un virus !!! Le code a été remplace par un test fonctionnel.
  • Plus de trace pour threads::shared.
  • Un bugfix sur use vars. Une commande désactivait une autre.

Changements internes

  • Une passe a été supprimée de l'évaluation des regex par perl. Il s'agit de la passe de dimensionnement qui sera faite en option si besoin est.
  • Nouvelle fonction strtod dans l'API perl qui correspond à la fonction c strtod.
  • On ne peut plus allouer plus de mémoire que ce que les structures de données pourront utiliser.
  • Nouveaux regnodes.
  • print_bytes_for_locale() a présent défini aussi en debugging mode.

Compilation et plates‐formes

  • On peut compiler un code pour être toujours thead-safe avec -Accflags='-DUSE_THREAD_SAFE_LOCALE' même si perl n'est pas compilé pour être en multi-thread (quelle utilité ?).
  • Définir -Drv en plus de -DDEBUGGING permet de mettre le mode verbeux pour les regex.
  • Configure : meilleure détection de memrchr, strlcat, strlcpy et memmem.
  • Des améliorations concernant -DPERL_GLOBAL_STRUCT et un fix sur -DPERL_GLOBAL_STRUCT_PRIVATE.
  • Fix un problème obscur sur HP-UX 11.11 avec pack.
  • Support minix 3 remis.
  • Cygwin ne retourne plus cuserid.

Corrections de bogues

Ouverture filehandles et ulimit -n

Fix un bug de leak de file handles, les conditions du bug étant d'ouvrir de nombreux répertoires (plus de 1019 environ sous GNU/Linux), avec l'option d'édition en place. La valeur magique 1020 est en fait ulimit -n moins les file handles déjà ouverts.
Perl ouvrait le répertoire mais ouvrait le suivant avant de refermer le dir handle, provoquant le leak. La source du problème vient de la feature de safe in place editing introduite en 5.28.0. Il est d'ailleurs proposé de mettre ce fix dans 5.28.1 ce qui n'est finalement pas fait.

Réécriture de propriétés Unicode en C

Réécriture des propriétés unicodes définies par l'utilisateur. Ça permet d'écrire nos propres tests. La réécriture de pure Perl vers C apporte de nombreux changements :

  1. Mieux intégré dans le reste du code, plus d'informations accessibles pour reporter des erreurs.
  2. Plus contraignant sur le naming de la fonction et son package
  3. La récursion est détectée à la compilation et produit une erreur
  4. D'autres erreurs s'arrêtent à la compilation.
  5. Meilleurs vérifications des fourchettes (fourchettes illégales)
  6. Les propriétés sont compilées le moins souvent possible (les propriétés sont des fonctions Perl, qui sont ensuite exécutée dans une regex)
  7. Plus (moins ?) de blocage ou race conditions
Corrections de bogues de dernière minute, gel et arbitrage du pumpking

Un bug fix de dernière minute sur un panic lorsqu'on fait sort untrucenUTF8. Dans le ticket, les discussions tournent aussi autour du freeze, des remerciements à Sergey Aleynikov qui a reporté pas mal de bug avec un outil de fuzzing, et un arbitrage de l'actuel possesseur de la citrouille empaillée (Sawyer X).

Perl ne sait pas garder un secret ;)

Des erreurs avec les regex et les modifiers /di. C'est quoi /di ?

  • i c'est insensible à la casse
  • d c'est pour l'usage interne de Perl

La documentation dit "ne vous en occupez pas" mais également "(…) since Perl can't keep a secret, and there may be rare instances where they are useful, they are documented here (…)". Et donc, comme ce n'est pas un secret ou du moins que Perl ne sait pas le garder… d permet de forcer un vieux et problématique set de caractères de Perl 5.14. :)

Autres
  • Fix compilation avec -DPERL_MEM_LOG (log de l'allocation mémoire) et -DNO_LOCALE
  • Petit fix sur l'optimisation du index introduit en 5.28.0 (optimisation dans la comparaison avec -1). Cette optimisation introduisait un warning quand on utilisait index dans un given/when.
  • Fix un warning sur le constant folding
  • Un problème de lexer à cause du multiconcat (ajoute récemment)
  • Meilleure output pour calloc quand on compile avec -Dm pour tracer la mémoire.
  • Philippe Hazel qui est le père de la bibliothèque PCRE (attention PCRE est une lib autonome qui implémente les regex comme Perl mais qui n'est pas utilisée par Perl) reporte qu'une nouvelle feature ne semble pas marcher correctement. Il s'agit des unicode script runs. Certaines fourchettes de valeurs unicodes n'étaient pas bien gérées dans les regex.
  • Parfois le mieux est l'ennemi du bien :) Sur certaines plateformes, la façon de déterminer $^X (soit le nom du binaire ayant lance le script) était optimisée. Le problème étant que lorsque certaines conditions ne permettaient pas de faire cette optimisation (/proc pas monte) alors le fallback était cassé. Régression depuis 5.28.0.
  • Meilleure gestion des bases de données corrompues avec SDBM_File. Qu'est-ce que ce module ? Une façon d'ouvrir un base de données et de la lier à une variable. De telle sorte que pour ajouter/modifier/supprimer des choses dans la base de données, il suffit de travailler sur le hash et tout sera bien sauvé à la fermeture du programme. L'échange de fichier SDBM n'était et n'est toujours pas un format d'échange entre plateformes.
  • On a déjà parlé de l'assignement vers une référence (feature récente). En fait, une expression comme \@a = était traitée implicitement comme local \@a =. C'est simplifié, car le bug n'existe qu'avec les slices.
  • Fix un problème de reportant d'errno sur FreeBSD lié au realloc.C'est un cas observable uniquement sur cette plateforme mais pourtant standard au niveau de C. Vu sur FreeBSD 13.0
  • Des problèmes de bootstraping liés au module Cwd qui peut maintenant fallback sur certaines fonctions systèmes. Ça aide pour les installations multi plateformes (1 perl pour 2 machines ou plus sur le réseau)
  • Fix un problème avec le contenu de `^R. Pour faire court, cette variable contient le retour d'une assertion dans une regex.
  • Fix un bug sur le modifier /g en regex qui permet de faire un match global c'est à dire que sur un remplacement, le remplacement se fera plusieurs fois s'il faut. C'est un problème de décision dans le découpage des chaines.
  • Un comportement incohérent entre perl -e 'eof() or die' /dev/null et perl -e 'eof or die' /dev/null qui produit Died at -e line 1.
  • Un format syntaxiquement incorrect est maintenant traité comme une erreur de compilation.
  • Un bug reporté chez Red Hat pour une erreur d’édition en place. L'erreur est dans la gestion des erreurs (die). Le bugfix permet d'écrire le fichier même lorsque le script perl est mort avec une exception.
  • Fix des problèmes de comportement dans le cas de compilation avec les flags -DNO_LOCALE_NUMERIC et -DNO_LOCALE_COLLATE

CONCLUSION

J'espère que ce grand tour des changements Perl des dernières années a été intéressant/utile. C'était l'occasion de parler du vénérable Perl et de redécouvrir Perl dans son ère post moderne.

Perl saves the world

(d'après xkcd lien - Licence CC-BY-NC)

Aller plus loin

  • # En tout cas ...

    Posté par (page perso) . Évalué à 10 (+8/-0).

    C'est de la news de qualité !!!

    J'ai un peu délaissé Perl ces dernières années au profit de Python, ça m'a donné envie de m'y remettre un peu :)

    • [^] # Re: En tout cas ...

      Posté par . Évalué à 4 (+2/-0).

      Pareil …

      Coté puissance du langage rien à redire
      par contre la lisibilité … c'est mieux ou pas changé ?

      • [^] # Re: En tout cas ...

        Posté par . Évalué à 1 (+0/-0).

        tous les vieux tricks sont accessibles mais la communauté perl a eu tendance a mettre de jolis modules avec de la jolie syntaxe devant (comme le framework objet Moo https://metacpan.org/pod/Moo plutot que de faire des bless à la main, Path::Tiny pour accéder à tes fichiers , … ). les signatures sont arrivés, comme plein de petites améliorations ici et là dans le langage qui permettent des choses assez élégantes.

        après: perl reste perl avec ces blocks anonymes, ses variables magiques (mais tellement pratiques), l'expressivité des sigils et ses choix de comportement par défaut qui nécessite de comprendre immédiatement ce qui est vendu comme de la killer feature avancée dans les autres langages (comme le spread operator de JS ou le ** de python

        perso je dirais que ca ne vaut plus le coup d'apprendre perl5 (ou js ou python ou tout autre langage de plus de 20 ans d'age) si on en a pas besoin: perl6 a posé la barre bien plus haut en terme d'expressivité en plus d'avoir une cohérence qu'aucun vieux langage ne peut assurer

        • [^] # Re: En tout cas ...

          Posté par . Évalué à 4 (+2/-0).

          Alors la … perl6 est super bien vendu bravo …

          Je suis passé de perl a python pour une seule raison la lisibilité
          Je dois encore maintenir 3000 lignes de perl (suivi de fab version texte + lecture code barre) qui fètera ses 15 ans de bon et loyaux services l'année prochaine.
          problème : la moindre modif c'est 3 jours :

          1 jour pour me remettre a relire du perl
          1 jour pour faire la modif + test
          1 jour pour la mis en prod

          perl6 … va falloir que je regarde …

  • # on peut modifier l'article ?

    Posté par . Évalué à 5 (+5/-1).

    je n'ai pas encore tout lu mais en diagonal:

    • rakudo n'est pas une vm! c'est l'implémentation de la spec perl6 en NQP ce qui permet d'avoir plusieurs VM (a ce jour moarvm, la vm officielle, jvm et transpilation vers js).
    • pug était un interpreteur écrit en haskell. pas une vm non plus donc
    • [^] # Re: on peut modifier l'article ?

      Posté par . Évalué à 5 (+4/-0).

      bon en fait c'est l'article wikipédia qui dit de la merde. je note dans ma todolist

    • [^] # Re: on peut modifier l'article ?

      Posté par (page perso) . Évalué à 3 (+1/-0).

      et on peut changer l'image du § CHANGELOG par https://xkcd.lapin.org/index.php?number=519#strips ainsi que l'image de fin pour https://xkcd.lapin.org/index.php?number=208#strips qui ont le mérite d'être en français :-)

      • [^] # Re: on peut modifier l'article ?

        Posté par . Évalué à 1 (+0/-0). Dernière modification le 09/07/19 à 16:33.

        Je pense qu'on peut plutôt mettre celle-ci : Perl problems

        :-P

        NdM : dépêche éditée pour corriger le lien.

        Il n'y a pas de mauvais outils, il n'y a que de mauvais ouvriers

    • [^] # Re: on peut modifier l'article ?

      Posté par (page perso) . Évalué à 3 (+1/-0).

      Avant de vous précipiter pour corriger les propos de l'auteur, cherchez un peu qui c'est, svp. Il connaît particulièrement bien Perl.

      "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

      • [^] # Re: on peut modifier l'article ?

        Posté par . Évalué à 2 (+1/-0).

        oui mais là vraiment je suis sur de moi: ca fait des années que je surveille perl6

        • [^] # Re: on peut modifier l'article ?

          Posté par (page perso) . Évalué à 2 (+0/-0).

          Si ça avait été tourné différemment, j'aurais pris ça pour une simple simplification rakudo = moarvm + rakudo, comme si on vulgarise et parle de JVM pour la vm et le frontend java : après tout, c'est une notion subtile (d'ailleurs, autant mieux parler simplement de compilateur dans ce cas). Dans ce genre de compilos avec un JIT, le terme VM est même un peu flou, puisque c'est souvent traduit à la volée en code natif et la vraie VM au final, c'est l'OS.

          Ceci dit, en effet, Rakudo n'a plus rien à voir avec Parrot et tel que c'est écrit, c'est pas clair, en particulier le « continuité/spécialisation de Parrot » de la dépêche devrait être plutôt : « Rakudo a remplacé Parrot par Moarvm (et/ou la JVM) ».

          Je proposerais quelque chose comme : « Le compilateur Rakudo pour Perl6 a laissé tomber la VM Parrot au profit de la VM Moarvm ».

          • [^] # Re: on peut modifier l'article ?

            Posté par . Évalué à 1 (+0/-0).

            la distinction est de taille: si moarvm est clairement la vm de choix pour perl6, rakudo vise plusieurs backends (celui de la JVM par exemple ne me laisse pas indifférent: il y a des milliards de dollars qui ont été balancés dans écosystème java. se dire qu'on peut réutiliser tous ces outils sans avoir à se tapper des langages tels que java ou kotlin me parait bien agréable). aussi c'est dommage de passer NQP sous silence.

            • [^] # Re: on peut modifier l'article ?

              Posté par (page perso) . Évalué à 2 (+0/-0).

              Ça aurait été une distinction intéressante pour une dépêche sur Perl6, bien sûr. Si Perl6 est mentionné ici, je pense que c'est juste que tout article sur Perl5 se sent obligé de mentionner Perl6 pour éviter les confusions. La réciproque est vraie aussi, le nommage maladroit de Perl6 n'a pas fini de créer des confusions, mais trop tard pour changer complètement (“Raku” remplacera par complètement Perl6), donc à prendre positivement :-)

  • # Prototypes et signatures

    Posté par . Évalué à 3 (+2/-0).

    J'aime beaucoup Perl mais je lui reproche souvent la manière dont sont passés les arguments des sous-routines.
    En effet, je me retrouve souvent à écrire beaucoup de code pour gérer les arguments des sous-routines plutôt que le code de la sous-routine en elle-même :

    sub f{
        my $arg_ref;
    
        my $a;
        my $b;
    
        $arg_ref = shift @_ or croak 'Must provide one argument (a reference to an hash).';
    
        if(not defined reftype $arg_ref or reftype $arg_ref ne reftype {}){
            croak 'The argument must be an hash reference.';
        }
    
        $a = $arg_ref->{a} or croak 'Field a is empty';
        $b = $arg_ref->{b} or croak 'Field b is empty';
    
        # Code de la sous-routine.
    }

    J'aimerai donc signer mes sous-routines mais ce n'est pas forcément recommandé.
    Est-ce que les signatures sont désormais mieux prises en charge ?

    • [^] # Re: Prototypes et signatures

      Posté par (page perso) . Évalué à 2 (+0/-0).

      Les signatures sont encore officiellement expérimentales je crois, mais il me semble que c'est plutôt stable et aussi performant maintenant. Ceci dit, ça ne capture au fond qu'un petit nombre de bugs : nombre d'arguments et bugs de typage basiques (hash ou tableau ou scalaire essentiellement) ; des bugs qui sont souvent détectés via les tests de toutes façons. Mais il y a un autre avantage de mon point de vue, c'est que c'est parfois plus clair à lire (on a une idée dès le début des arguments, arguments par défaut, etc.).

  • # Corrections

    Posté par . Évalué à 2 (+1/-0).

    Quelques suggestions de corrections :

    Paragraphe regex set :

    (?[ () ]), (?[(\c]), (?[!!(\w]) ou encore (?[[0]+()+])

    Dans l'article les parties entre quotes ne s'affichent pas correctement. Soit il manque les backquotes de début et de fin de ligne, soit c'est un bug markdown qui panique un peu quand l'article est trop long (ça m'est déjà arrivé dans un autre contexte) -> dans ce cas, tenter un expression par ligne ?

    sysread(), syswrite(), recv() et send() émettent un warning si on les utilisent avec un filehandle marqué :utf8

    -> utilise

    La recherche de chaines fixe dans une regex peut être plus rapide (majorité des cas) ou parfois plus lent.

    -> lente

    Optimisation debugger, moins de structure de données créées car inutiles.

    -> structures

    Les assignement

    -> assignements

    Configure tient en compte

    -> Configure prend en compte

    Si un modo se sent de modifier tout ça dans cet énorme article, bon courage à lui. :)

    • [^] # Re: Corrections

      Posté par (page perso) . Évalué à 6 (+6/-2).

      J'espère que ça ne dérange pas si c'est une modo qui a fait le boulot.

      Sinon c'est corrigé à part pour celles de "Paragraphe regex set :", je n'ai pas compris où était le problème et comme c'est du code je préfère ne pas y toucher.

      Merci pour le signalement des corrections à faire.

      OS préféré Mageia 6 et Mageia 7, CMS préféré SPIP, suite bureautique préférée LibreOffice, logiciel de dessin préféré Inkscape.

    • [^] # Re: Corrections

      Posté par (page perso) . Évalué à 3 (+1/-0).

      Paragraphe regex set

      est-ce meilleur comme ça ?

      "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

  • # Questions

    Posté par . Évalué à 3 (+2/-0).

    Tout d'abord un grand bravo à l'auteur (ou aux auteurs) de la dépêche. Ça a dû prendre un temps énorme à rédiger / relire / corriger.

    Chapeau.

    Et puis j'ai deux petites questions :

    Plusieurs petits fixes sur des usages de regex qui doivent terminer en erreur. Comme le cas des nested quantifiers. Un nested quantifier c'est ce genre de choses /ab{2}??c/. Ou encore certaines séquences non terminées /(?i/. C'est tout simplement des regex fausses mais perl doit gérer correctement cette erreur.

    Si j'ai bien compris la phrase, /ab{2}??c/ doit générer une erreur ?

    Si c'est le cas, pourquoi ?

    Le point d'interrogation ne doit-il pas s'appliquer au (groupe de) caractère(s) précédent ?

    Dans ce cas, je le lis comme « a suivi de (((2 b) 0 ou 1 fois) 0 ou une fois) c »

    Soit abbc ou ac.

    C'est pas une manière très efficace d'écrire la regex, mais je ne vois pas pourquoi ça ne devrait pas être valide.

    On peut changer la date affichée par le binaire perl (perl -V) en modifiant la variable PERL_BUILD_DATE.

    o_O ?

    Dans quel cas voudrait-on changer la date affichée par perl -V ?

    • [^] # Re: Questions

      Posté par . Évalué à 4 (+3/-0).

      Dans quel cas voudrait-on changer la date affichée par perl -V ?

      Une hypothèse : pour les systèmes de build reproductibles ? J'avais vu pas mal d'exemple où les gens patchaient par exemple python pour avoir des sorties identiques indépendamment de la date de compilation de tout le paquet.

    • [^] # Re: Questions

      Posté par (page perso) . Évalué à 3 (+1/-0).

      Tout d'abord un grand bravo à l'auteur (ou aux auteurs) de la dépêche. Ça a dû prendre un temps énorme à rédiger / relire / corriger.

      à modérer aussi :-)

      "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

  • # Réutiliser une syntaxe

    Posté par (page perso) . Évalué à 3 (+1/-0).

    L'utilisation supprimée peut être obtenue avec printf ou sprintf et la raison de supprimer cette feature est de libérer $# pour un possible nouvel usage.

    Y'a que moi que ça choque de réutiliser une variable pour autre chose ? Est-ce possible d'avoir un code compatible 5.12 et 5.32 ?

  • # Désolé!

    Posté par . Évalué à 2 (+0/-0).

    C'est idiot mais ce n'est qu'après avoir pertinenté que j'ai vu la note de cette dépèche (42). Si vous cherchez l'idiot qui a cassé tout ça, ben le quarante-troisième, c'est moi. Je l'ai pas fait exprès, j'le jure. Enfin si, cette dépêche est absolument formidable. Et j'ai honte d'avoir honte…

    J'ai juste une question et je vous assure qu'elle est sérieuse: ça rend pas un peu zinzin de travailler avec Perl? Me rappelle qu'au début, quand je suis passé à Linux, par curiosité, j'ai voulu inspecter des scripts Perl (sais plus si c'était ceux de Webmin ou autre chose) et je me suis dit «mince, c'est quoi ce truc?» J'y comprenais que dalle.

    Puis bon, depuis, je me suis attardé sur Python et du coup, ça va déjà beaucoup mieux.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.