Ce qui se passe
Laravel 13.40.0 corrige une exécution de code à distance dans Concurrency::run() quand le driver est process,
le driver par défaut. Le processus parent lisait le résultat de chaque tâche sur la sortie du processus enfant, puis le
désérialisait. Une tâche qui affichait du texte contrôlé par un utilisateur pouvait donc écrire un faux résultat, que
le parent désérialisait. Le défaut a été signalé par @Arr0way (PR #62297). La note de version ne donne pas
d'identifiant CVE.
Désormais, l'enfant écrit son résultat dans une trame signée avec une clé aléatoire que le parent crée pour chaque tâche ; le parent ignore toute trame que la clé ne valide pas. Au passage, l'erreur « Trying to access array offset on null », que provoquait une tâche qui affichait quoi que ce soit, disparaît aussi.
Les nouveautés utiles
Alertes de lenteur. Queue::whenJobRunsLongerThan() et Schedule::whenTaskRunsLongerThan() appellent une fonction
quand un job ou une tâche planifiée dépasse un seuil. Les unités diffèrent : un nombre nu se lit en millisecondes
pour les jobs, en secondes pour les tâches planifiées. Passez plutôt un CarbonInterval.
Queue::whenJobRunsLongerThan(CarbonInterval::seconds(90), function ($job, $duration) {
Log::warning($job->resolveName().' : '.$duration.' ms');
});
Schedule::whenTaskRunsLongerThan(CarbonInterval::minutes(45), function ($task, float $runtime) {
Log::warning('Tâche planifiée : '.$runtime.' s');
});Le premier écoute JobAttempted : il se déclenche aussi pour une tentative qui échoue ou qui est remise en file.
Retard des répliques de lecture. DB::getLastCommitId() renvoie un identifiant de commit après une écriture, et
DB::hasCommitId($id, wait: 2) dit si la réplique l'a reçu, éventuellement en attendant deux secondes.
mergeCommitIds() combine plusieurs identifiants. Cela fonctionne sur MySQL avec GTID, MariaDB avec journal binaire
et PostgreSQL ; l'attente sur PostgreSQL demande PostgreSQL 19. Les autres drivers lèvent une RuntimeException.
C'est une alternative précise au middleware PreventStaleDatabaseReads de la 13.38, qui envoie les lectures vers le
serveur d'écriture pendant une durée fixe.
Entrées de requête. Un argument strict sur integer(), float(), boolean() et string() renvoie la valeur
par défaut au lieu de convertir ?count=abc123 en 0. En mode strict, boolean() n'accepte que 1, true, on,
yes, 0, false, off et no.
Middleware. insertBefore() et insertAfter() (et leurs variantes InGroup) dans bootstrap/app.php placent un
middleware juste avant ou après un middleware natif, sans redéclarer toute la pile.
Transactions. Après une connexion perdue en pleine transaction, Laravel jette le PDO mort et se reconnecte à la requête suivante ; avant, chaque transaction échouait avec « There is already an active transaction » jusqu'au redémarrage du worker ou d'Octane. Un verrou expiré ou un deadlock dans une transaction imbriquée revient maintenant au point de sauvegarde de celle-ci, au lieu de valider les écritures imbriquées.
Comment s'y prendre
composer update laravel/framework
grep -rn "Concurrency::run" app/ routes/Si vous utilisez Concurrency::run() avec le driver process, mettez à jour sans attendre. Réglez ensuite vos seuils en
fonction de l'unité de chaque méthode.
Source : Laravel News, qui reprend le journal des modifications de la 13.40.0. Source en anglais.