Bonjour, on s'est tapé une galère d'une journée parce que l'on n'arrivait pas à entrer dans l'Espace Privé d'un site SPIP (mutualisé).
L'accès à la page était impossible, mais ça échouait silencieusement avec une erreur 500. Rien dans error_log ni dans spip.log.
L'erreur ne sortait pas dans SPIP car la fonction est appelée avec un opérateur @. En fait, c'est l'affichage d'un logo qui faisait tout planter. L'image source du logo était beaucoup trop grosse.
Le test à la main sur l'image donne ça :
$ php -r "imagecreatefromjpeg('/tmp/arton347.jpg');"
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to
allocate 2491 bytes) in Command line code on line 1
Le morceau de code inctiminé dans
ecrire/inc/filtres_images_lib.php est:
$srcImage = @$fonction_imagecreatefrom($image);
if (!$srcImage) {
spip_log("echec gd1/gd2");
return;
}
L'erreur ici est qu'en cas d'épuisement de la mémoire, on arrive
même pas au spip_log(), car PHP fait une erreur 500 après son échec dans
imagecreatefromjpeg().
C'est piégeux. Ne serait-il pas utile que l'erreur soit plus facile à tracer ?
La seule solution que je vois serait de loguer (en mode debug par exemple), l’appel à ce type de fonctions avant qu’il ne soit fait. De manière générale, on pourrait tracer tous les appels de fonctions appelées via charger_fonction().
En fait tu as peut-être raison, php trace peut-être quand même cette
erreur (vu qu'il te l'a affichée en mode client).
+1 donc pour que le '@' soit supprimé, ça ne manque pas de pain
Mmm, sur ma copie de SPIP je l'ai viré et ça continue à échouer silencieusement. Je ne suis plus trop certain de ce que j'avance du coup.
Une autre solution qui me semble plus appropriée: tester que PHP sera capable de faire les manipulations d'images avant de les lancer.
Si pas, générer une erreur_squelette et ignorer le traitement. Avec ça on comprendra tout de suite le problème.
- quand on selectionne GDx il y a un test de manipulation d'image qui cherche la taille d'image la plus grande qu'on sait traiter sans echec, et la memorise dans une meta
- quand on veut faire un filtre image on verifie au prealable que la taille est inférieure à la taille maxi notée dans la meta, et sinon on on ne manipule pas l'image et on essaye de coller a la demande avec un style width/height en dur sur l'image originale
Mais le test de memoire ne peut etre fiable a 100% : car le dépassement mémoire dépend de ce qu'on a fait dans le hit, si par exemple un tableau PHP a été généré et est en mémoire au moment de l'appel, ou si un plugin avec beaucoup d'inclusions a été activé depuis le test etc.
Et oui en cas de dépassement mémoire PHP plante sans aucun log spip/PHP exploitable, seul les logs Apache peuvent permettre de le voir.
Et oui il faudrait mettre en place tout un système de reprise sur echec partout ou on utilise une fonction gd2 : noter en meta ou en cache disque quelle operation on fait, sur quelle image source, positionner une callback shutdown/ob_start(), appeler gd2, effacer la note, et la callback se charge si plantage d'adapter la taille maxi utilisable et de relancer le hit qui devrait alors passer sans planter.
Tout ça à tester/industrialiser/implémenter partout. Un volontaire pour s'en charger ?