Platzhalter sind in PHP "nicht wirklich sinnvoll"
bearbeitet von Google weiß alles> @Google weiß alles
>
> Okay, mal so als Denkanstoß:
>
> Hier eine Liste der von mir bemerkten Tippfehler in [`myTemplateToPHP.sh`](https://code.fastix.org/showFile.php?file=Projekte/PHP%2CBash%3ATemplate-%C3%9Cbersetzer/myTemplateToPHP.sh), Version 1.1.2:
>
> - Zeile 13: `replacementrRight`
> - Zeile 16: `replacementrRight`
> - Zeile 26: `replacementrRight`
Ok. Sind Tippfehler, die sich aber im Programmablauf nicht bemerkbar machten, weil ich **an jeder Stelle** `replacementrRight` statt `replacementRight` notierte. Hab es aber geändert und weil es tatsächlich Tippfehler sind möchte ich nicht verfehlen, mich für den Hinweis zu bedanken.
> - Zeile 49: `Yoy`, `sedile`
Ok. 'Yoy' ist ein Tippfehler (Es muss natürlich "You" heissen, der sich aber im Programmablauf nicht bemerkbar machte, weil er nur in der informativen Ausgabe ab Ende auftritt. Und nur wenn Fehle aufgetreten sind.
> Eine Liste der bemerkten Logikfehler oder inhaltlichen Fehler:
>
> - Zeile 15: XSS-Angriff möglich. `htmlspecialchars` benötigt den Parameter `ENT_QUOTES` (für Platzhalter in HTML-Attributen) und eigentlich auch noch eine `encoding`-Angabe ([Hintergrund](http://php.net/manual/en/function.htmlspecialchars.php#refsect1-function.htmlspecialchars-changelog)).
Mein. Oder Ja. Das Skript kann natürlich nur das Template von Text nach PHP übersetzen. Es entsteht ein Template. Wenn man es ganz genau nimmt, dann ist es eine Frage des konkret geplantes Ablaufes, ob die, für die Ausgabe angezeigten Änderungen an Variableninhalten im Template definiert werden oder im Programm und zwar dort, wo die Daten unter Beachtung der jeweiligen Quelle in den hash "$TPL" eingefügt werden. Eine allgemeingültige Anforderung ist hier nicht formulierbar.
Das gilt auch für den Zeichensatz. Der wird "eher nicht" im Template festgelegt, sondern zentraler. Trotzdem: Danke für den Hinweis.
> - Zeile 30: Überschreibt nachfolgend vermutlich die Eingabedatei, falls diese nicht auf `.txt` endet.
Nein. In Zeile 30 wird nur der Name der Ausgabedatei ermittelt. Und richtig: Wenn die Eingabedatei auf .php endet, dann würde diese in Zeile 33 überschrieben, genau genommen geleert. Das ist zwar auch eine Frage der Vereinbarung, aber Du hast Recht, das kann man einfach verhindern. Kommt in die Version 1.1.3. - Danke für den Hinweis.
> - Zeile 36: `hasErrors` könnte durch eine vorherige Eingabedatei den Wert 1 haben, wird hier aber auf 0 zurückgesetzt. Fehler werden dadurch potenziell verdeckt.
> - Zeile 48: `hasErrors` könnte nicht initialisiert sein.
Das ist in genau einem Fall nicht initialisert, nämlich wenn keine Eingabedatei existiert. Das ist aber kein Fehler im Programmablauf, also wird nichts "geflaggt", also wird auch kein Fehler - der ja nicht auftrat - gemeldet. Trotzdem: Danke für den Hinweis.
> In die Ausgabe kann beliebiger PHP-Code injiziert werden.
Das ist NUR unter der Annahme richtig, dass die Inhalte in $TPL 1:1 'usergeneriert' sind, z.B. durch Übernahme aus GET, POST, COOKIE, ... (oder auch immer.) Wie schon geschrieben kann und sollte man das an anderer Stelle regeln, nämlich bei der Übernahme in $TPL. Trotzdem: Danke für den Hinweis.
> - Für `htmlSafeMode="yes"`:
>
> - Eingabe:
>
> ~~~
> foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar
> ~~~
>
> - Ausgabe:
>
> ~~~
> foo <?=htmlspecialchars( $tpl[' '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' '] );?> bar
> ~~~
Ich habe das mit
~~~php
$tpl['FARBE'] = 'foo {{ \'])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[\' }} bar';
~~~
in webseite.php versucht und das Template mit `htmlSafeMode="no"` übersetzt.
Die Ausgabe lautet:
~~~html
Kleine foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar Männchen stammen vom Mars.
~~~
Hast Du eventuell den visuellen Kontextwechsel durch die Darstellung im Browser nicht beachtet? Falls nicht zeige mir, was Du GENAU gemacht hast und ich entscheide dann ob es ein Future oder ein Bug ist.
> - Für `htmlSafeMode="no"`:
>
> - Eingabe:
>
> ~~~
> foo {{ ']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[' }} bar
> ~~~
>
> - Ausgabe:
>
> ~~~
> foo <?=$tpl[' ']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[' '];?> bar
> ~~~
Das habe ich mit
~~~php
$tpl['FARBE'] = 'foo {{ \']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[\' }} bar';
~~~
versucht und das Template mit `htmlSafeMode="yes"` übersetzt.
Ergebnis nach Aufruf mit php webseite.php:
~~~
foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar
~~~
Nun, ich weiß ja nicht was Du vorhast. Aber so lange man das Ergebnis der Vereinigung von Daten und Template, **also die Ausgabe**, nicht nochmal von PHP interpretieren lässt (was wohl eines Probleme von Wordpress ist oder war) kann hier nichts passieren. Es sei denn natürlich, die Browser stellen gänzlich unerwartet von Javascript auf PHP um oder jemand holt die resultierende Webseite und lässt diese dann mit PHP interpretieren. Was auch ziemlich ungewöhnlich ist.
> Das war jetzt ein Code Review mit den offensichtlichen Problemen in 52 Zeilen Code (inklusive Leerzeilen und Kommentare). Das dauerte länger als 3 Sekunden, war aber dafür vermutlich auch ergiebiger.
Danke für die Tippfehler und Hinweise. Was in Deiner Darstellung wie ein "richtiger" Fehler aussah konnte ich nicht nachvollziehen.
Platzhalter sind in PHP "nicht wirklich sinnvoll"
bearbeitet von Google weiß alles> @Google weiß alles
>
> Okay, mal so als Denkanstoß:
>
> Hier eine Liste der von mir bemerkten Tippfehler in [`myTemplateToPHP.sh`](https://code.fastix.org/showFile.php?file=Projekte/PHP%2CBash%3ATemplate-%C3%9Cbersetzer/myTemplateToPHP.sh), Version 1.1.2:
>
> - Zeile 13: `replacementrRight`
> - Zeile 16: `replacementrRight`
> - Zeile 26: `replacementrRight`
Ok. Sind Tippfehler, die sich aber im Programmablauf nicht bemerkbar machten, weil ich **an jeder Stelle** `replacementrRight` statt `replacementRight` notierte. Hab es aber geändert und weil es tatsächlich Tippfehler sind möchte ich nicht verfehlen, mich für den Hinweis zu bedanken.
> - Zeile 49: `Yoy`, `sedile`
Ok. 'Yoy' ist ein Tippfehler, der sich aber im Programmablauf nicht bemerkbar machte, weil er nur in der informativen Ausgabe ab Ende auftritt.
> Eine Liste der bemerkten Logikfehler oder inhaltlichen Fehler:
>
> - Zeile 15: XSS-Angriff möglich. `htmlspecialchars` benötigt den Parameter `ENT_QUOTES` (für Platzhalter in HTML-Attributen) und eigentlich auch noch eine `encoding`-Angabe ([Hintergrund](http://php.net/manual/en/function.htmlspecialchars.php#refsect1-function.htmlspecialchars-changelog)).
Mein. Oder Ja. Das Skript kann natürlich nur das Template von Text nach PHP übersetzen. Es entsteht ein Template. Wenn man es ganz genau nimmt, dann ist es eine Frage des konkret geplantes Ablaufes, ob die, für die Ausgabe angezeigten Änderungen an Variableninhalten im Template definiert werden oder im Programm und zwar dort, wo die Daten unter Beachtung der jeweiligen Quelle in den hash "$TPL" eingefügt werden. Eine allgemeingültige Anforderung ist hier nicht formulierbar.
Das gilt auch für den Zeichensatz. Der wird "eher nicht" im Template festgelegt, sondern zentraler. Trotzdem: Danke für den Hinweis.
> - Zeile 30: Überschreibt nachfolgend vermutlich die Eingabedatei, falls diese nicht auf `.txt` endet.
Nein. In Zeile 30 wird nur der Name der Ausgabedatei ermittelt. Und richtig: Wenn die Eingabedatei auf .php endet, dann würde diese in Zeile 33 überschrieben, genau genommen geleert. Das ist zwar auch eine Frage der Vereinbarung, aber Du hast Recht, das kann man einfach verhindern. Kommt in die Version 1.1.3. - Danke für den Hinweis.
> - Zeile 36: `hasErrors` könnte durch eine vorherige Eingabedatei den Wert 1 haben, wird hier aber auf 0 zurückgesetzt. Fehler werden dadurch potenziell verdeckt.
> - Zeile 48: `hasErrors` könnte nicht initialisiert sein.
Das ist in genau einem Fall nicht initialisert, nämlich wenn keine Eingabedatei existiert. Das ist aber kein Fehler im Programmablauf, also wird nichts "geflaggt", also wird auch kein Fehler - der ja nicht auftrat - gemeldet. Trotzdem: Danke für den Hinweis.
> In die Ausgabe kann beliebiger PHP-Code injiziert werden.
Das ist NUR unter der Annahme richtig, dass die Inhalte in $TPL 1:1 'usergeneriert' sind, z.B. durch Übernahme aus GET, POST, COOKIE, ... (oder auch immer.) Wie schon geschrieben kann und sollte man das an anderer Stelle regeln, nämlich bei der Übernahme in $TPL.
> - Für `htmlSafeMode="yes"`:
>
> - Eingabe:
>
> ~~~
> foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar
> ~~~
>
> - Ausgabe:
>
> ~~~
> foo <?=htmlspecialchars( $tpl[' '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' '] );?> bar
> ~~~
Ich habe das mit
~~~php
$tpl['FARBE'] = 'foo {{ \'])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[\' }} bar';
~~~
in webseite.php versucht und das Template mit `htmlSafeMode="no"` übersetzt.
Die Ausgabe lautet:
~~~html
Kleine foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar Männchen stammen vom Mars.
~~~
Hast Du eventuell den visuellen Kontextwechsel durch die Darstellung im Browser nicht beachtet? Falls nicht zeige mir, was Du GENAU gemacht hast. und ich entscheide dann ob es ein Future oder ein Bug ist.
> - Für `htmlSafeMode="no"`:
>
> - Eingabe:
>
> ~~~
> foo {{ ']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[' }} bar
> ~~~
>
> - Ausgabe:
>
> ~~~
> foo <?=$tpl[' ']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[' '];?> bar
> ~~~
Das habe ich mit
~~~php
$tpl['FARBE'] = 'foo {{ \']?> <?php var_dump(filemtime(__FILE__)); ?> <?=$tpl[\' }} bar';
~~~
versucht und das Template mit `htmlSafeMode="no"` übersetzt.
Ergebnis nach Aufruf mit php webseite.php:
~~~
foo {{ '])?> <?php var_dump(filemtime(__FILE__)); ?> <?=($tpl[' }} bar
~~~
Nun, ich weiß ja nicht was Du vorhast. Aber so lange man das Ergebnis der Vereinigung von Daten und Template, **also die Ausgabe**, nicht nochmal von PHP interpretieren lässt (was wohl eines Probleme von Wordpress ist oder war) kann hier nichts passieren. Es sei denn natürlich, die Browser stellen gänzlich unerwartet von Javascript auf PHP um oder jemand holt die resultierende Webseite und lässt diese dann mit PHP interpretieren. Was auch ziemlich ungewöhnlich ist.
> Das war jetzt ein Code Review mit den offensichtlichen Problemen in 52 Zeilen Code (inklusive Leerzeilen und Kommentare). Das dauerte länger als 3 Sekunden, war aber dafür vermutlich auch ergiebiger.
Danke für die Tippfehler und Hinweise. Den anderen Fehler konnte ich nicht nachvollziehen.