Crash php sur ob_get_contents() conditions difficiles à déterminer, aucune piste : help

Avatar du membre
Mammouth du PHP | 1609 Messages

23 mai 2015, 13:17

Je pense que tout le monde a compris qu'il y avait une erreur dans la mise en forme du message il fallait lire "après" dans le code que j'avais un tout petit peu mis en forme avec un copier coller alors que le code comprend des notes.
Ce n'est pas ça que je soulignais trebly, oui je me doutais bien que tu voulais écrire "après", ce que je soulignais c'est que dans ton html généré tu n'as pas mit la trace d'après le ob_get_contents et ce que je disais, c'est que cette trace s'affiche belle et bien.

Bref j'imagine que tu voulais illustrer le cas de plantage afin de démontrer que ton hypothèse est fondée... ceci dit, sans connaitre le code qui s'exécute après, ça ne prouve aucunement que le ob_get_contents provoque une sortie de la fonction. C'est une déduction précipitée si l'on a pas attentivement épluché le code venant après. Ce n'est qu'une fois qu'on s'est clairement assuré que le problème ne vient pas du code d'après que l'on peut éventuellement en venir à ta conclusion.

Tu dis que tu as 2 cas différents, un cas avec un article et un cas avec une liste d'articles et que le plantage se produit dans le cas avec liste d'articles. Ne penses tu donc pas qu'il pourrait y avoir un problème avec ton code dans le cas de la liste d'articles ?

Je ne comprends pas bien où tu en es, es tu toujours sur l'idée du ob_get_contents qui provoque une sortie de la fonction ou es tu parti sur une autre hypothèse ?

Si ton hypothèse est toujours la même (ob_get_contents provoquant une sortie de fonction) je vais te proposer quelque chose de très simple pour nous en assurer : ajoute un exit(); juste après le ob_get_contents et assure toi que l'exit n'est pas appelé dans le cas de plantage. Si l'exit se fait, tu pourras alors en conclure que ton hypothèse est erronée et que le problème vient probablement du code qui suit et si effectivement le exit() ne se fait pas, alors déplace le avant le ob_get_contents. Si l'exit se fait alors ok, il y a visiblement une sortie de la fonction lors du ob_get_contents mais s'il ne se fait pas on pourra alors en conclure que lors du cas de plantage la fonction n'est pas appelée et que le problème est ailleurs (mais d'après ce que tu nous a dis cette hypothèse est à priori invraisemblable).
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 19 Messages

30 mai 2015, 17:20

Bonjour,

La désactivation de tous les plugins en même temps, puis une réactivation aléatoire, a fait disparaître deux problèmes : le ob_get_content et un blocage clavier sur l'édition d'une "page"...
Et le plugin contenant le ob_get_content s'est mis à se comporter parfaitement normalement.

J'ai rapproché le problème d'une bizarrerie intervenue il y un a deux mois : écran blanc après une modif d'un plugin -> pas d'erreur détectable, j'avais découvert en éditant en Hexa que des doubles lignes injustifiées étaient en fait des CRCRLF que j'ai remplacé par CRLF, le plantage avait disparu.

Le bug est en fait le suivant :
Wordpress, lors de l'importation de plugin zippés, recopie les fichiers texte (php, js, css) en environnement Linux comme des binaires en maintenant les fins de lignes en CRLF. Ces fichiers s'il sont modifiés en environnement Windows voient les eol devenir au minimum CRCRLF, et de manière variable suivant l'éditeur vont se trouver avec des fins de lignes hétérogènes parfois multiples.

php qui ne bronche pas sur des CRLF inattendus en environnement Linux semble, après avoir rencontré certaines suites de fin lignes peu orthodoxes avoir un comportement aléatoire dont le ob_get_content() est un exemple, ainsi que le retour avec écran blanc (un plantage sec restant en cause inconnue sans outil de debug actif) et probablement d'autres cas de dysfonctionnements. Le fait fait de modifier simplement de manière masquée des CRCRLF ou CRLFCRCRLF etc. anormaux entre les lignes "sensibles" fait disparaître les phénomènes (une fois la première hétérogénéité introduite on peut avoir à peu près n'importe quoi au fur et à mesure des mises à jour et transferts).

Pourtant le principe même de la syntaxe devrait, en éliminant ces caractères quels qu'ils soient, quelque soit la plateforme, rendre php insensible à ce problème (une comparaison binaire automatique de tous les fichiers concernés plus de 5000 et que je n'ai pas pu effectuer : outil ? devrait permettre de voir s'il y a ou non d'autres anomalies, une interaction avec UTF-8 ?).

La question qui reste néanmoins posée, (puisque les manifestations existent d'une différence de comportement de php en fonction de fins de lignes hétérogènes) : quelle est la protection de php contre ces caractères de fin de ligne hétérogènes outre le cas des chaînes Heredoc Nowdoc (que je dois vérifier).

Le problème semble exister aussi avec javascript (là en exécution locale) et même les css (cas totalement inexpliqué de blocage de l'accès clavier pour tous les champs textes d'une page).

Je chercherai à retrouver un exemple (j'ai une version des fichiers générant l'anomalie).

Je n'ai plus d'anomalie, mais cela m'aura coûté un mois à devenir dingue.

La détection , l'alerte et la correction de ces anomalies devrait, à mon sens, être intégrée aux outils mis en jeu dans ces processus. En effet, si Filezilla documente son comportement avec précision, les éditeurs de fichier font de tout et en général sans alerte tant à l'affichage qu'à la sauvegarde quand ils sont en mode "auto" pour la reconnaissance des formats.

Merci de votre réactivité.

Le sujet pourrait être clos si l'on considère le cas particulier, mais il reste cependant pas mal de questions générales en suspend.

Cordialement

Trebly

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

31 mai 2015, 02:25

Je vais encore te répondre la même chose mais tant pis...
:arrow: Donne nous 1 exemple de code qui fait buguer PHP de façon "anormale" sans log.


Moi je veux bien accuser PHP, Linux, Windows, les moteurs d'exécution Javascript, CSS ou même Wordpress de mal gérer certains trucs, mais force est de constater que pour l'instant à aucun moment, tu n'as été capable de fournir un seul exemple concret qu'on puisse regarder.


La seule chose que tu as trouvée si je comprends bien ton message, c'est qu'il y avait des problèmes de retours à la ligne incorrects dans ton code.
Et ça, il n'y a qu'un seul fautif, ce n'est ni Windows, ni Linux, ni la décompression de Wordpress => c'est la faute de ton éditeur de code.

Tous les éditeurs de code décents permettent de gérer correctement les retours à la ligne et n'insèrent pas des CRCRLF en caractère de retour à la ligne.
Utilise Sublimetext ou Scite par exemple et tu pourras voir les caractères de fin de ligne et les gérer proprement.
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 19 Messages

31 mai 2015, 11:22

Et ça, il n'y a qu'un seul fautif, ce n'est ni Windows, ni Linux, ni la décompression de Wordpress => c'est la faute de ton éditeur de code.
Désolé faux, je ne dis pas ça.

Je dis que lors du chargement d'un plugin depuis une machine windows vers une machine Linux, les fichiers textes contiennent exportés l'ont été en mode binaire et les fins de ligne sont des CRLF. Alors après le téléchargement vers windows les fins de ligne sont marquées par CRCRLF. Il n'y a pas d'éditeur impliqué, uniquement deux procédures :
- Upload WordPress
- Filezilla

A noter
Il est rapporté en notes sur le site Filezilla :
Filezilla : Data_Type
Note in Filezilla project https://wiki.filezilla-project.org/Data_Type
FileZilla does not analyse files uploaded as ASCII in any way. So if you have mixed line endings, somewhat "unexpected" things can happen. The native line ending for Windows is CR+LF. As this is what the FTP server expects when transferring files in ASCII, FileZilla on Windows does not apply any line ending translation at all. Now, imagine there is a text file with mixed Windows (CR+LF) and Unix (LF) line endings. Uploading that file from a Windows-based system to a Unix-based system will result in all CR+LF translated to LF only. Downloading that file again will make the FTP server convert all LF to CR+LF while sending it to FileZilla. As a result, all LF effectively are converted to CR+LF.
Another example is a text file with mixed line endings. FileZilla on Windows uploads that file to an FTP server running on Windows - no line ending conversion is done at all. Some text editors transparently handle mixed line endings so in such a text editor, the text file looks fine. However, other programs do not handle these cases and the text file might not work as expected in programs running on the server consuming that text file because they are confused by the still embedded Unix-style line endings (LF).
In yet another example, a Windows (CR+LF) text file was uploaded to a Unix-based FTP server in binary. If that file is downloaded in ASCII, the FTP server translates LF to CR+LF so the CR+LF line endings will be converted to CR+CR+LF. FileZilla on Windows does expect the file to already use CR+LF line encoding (per FTP specification), so no more translation is done. Depending on the text editor used, lines might be separated by an additional empty line now.
La seule chose que tu as trouvée si je comprends bien ton message, c'est qu'il y avait des problèmes de retours à la ligne incorrects dans ton code.
Faux : j'explique que plus de 1000 fichiers texte de l'installation wordpress (plugins chargés) contiennent le problème : fins de lignes CRLF sous Linux devenant normalement CRCRLF après importation vers windows. Et justement ce n'est pas le cas du code que j'ai créé parce que lors de son chargement vers linux les CRLF (windows correctement gérés pas mon éditeur) deviennent naturellement LF seul (convention Unix) comme il convient.

Je dis que j'ai vérifié que le simple fait de remplacer par les moyens adaptés des codes invalides CRCRLF par CRLF suffit (sur un code qui n'est pas le mien) à faire disparaitre un plantage d'exécution php.
Tous les éditeurs de code décents permettent de gérer correctement les retours à la ligne et n'insèrent pas des CRCRLF en caractère de retour à la ligne.
Je n'ai jamais laissé supposer une pareille chose, j'ai décrit avec précision le mécanisme en cause qui n'impliquer pas l'éditeur.
Maintenant il est possible avec un éditeur de texte, paramétré pour nettoyer le code (remplacer CRCRLF par CRLF lors de la sauvegarde ou au chargement, peu importe), de réaliser l'opération, Mais au lieu d'éditer à la suite plus de dix mille fichiers j'ai préféré utiliser WinGrep (seul utilitaire permettant d'effectuer le traitement) qui a traité le problème en quelques secondes. Néanmoins un éditeur binaire (Code affiché en Hexa) est capable de faire l'opération, mais fichier par fichier, et il faut avoir ouvert le fichier pour constater l'anomalie, ou soupçonner quand Scite ou PhpStorm ou PSPad affiche des doubles lignes (interprète par défaut CRCRLF comme CRLFCRLF pour l'affichage)
Bien sur, ensuite ne plus utiliser le processus d'importation de plugin utilisant un Fichier zip téléchargé.

Quand a "phpstorm" que j'utilise majoritairement c'st un excellent éditeur parfaitement fiable, et j'ai je crois signalé que j'ai testé divers éditeurs, dont la liste principale est : "Eclipse", "Scite", "PSPad", "PhpStorm" et vérifié leur comportement lorsque l'on leur donne à traiter des fichiers "anormaux".

Oui, je peux montrer un site qui plante, mais pas comment dans le détail. Par contre le remplacement généralisé des fins de ligne en anomalie fait que le code se met à fonctionner.

Maintenant, je ne suis pas en mesure de présenter un exemple "simple" qui le montre, la réponse est non. Parce que c'est économiquement impossible sauf à avoir beaucoup de chance, ceci en l'absence de moyen de détecter dans l'anomalie (250 000 lignes de code concernées) l'instance ou les instances qui créent la conséquence observée et par quel mécanisme. C'est à dire avoir résolu tout le problème.
Pour l'instant je me contente d'avoir un code qui à un comportement prévisible et le moyen de le déboguer quand l y a lieu.

Cordialement

Trebly