Matthias Apsel: utf8_encode, aber \n, \r\n, \r sollen erhalten bleiben

Om nah hoo pez nyeetz, alle!

In einem HTML-Formular befindet sich ein textarea-Element, dessen Inhalt auch Zeilenumbrüche enthalten dürfen.

Der Inhalt wird in einer SQL-Datenbank gespeichert, so dass aus den Zeilenumbrüchen beispielsweise "\r\n" wird.

Wenn dieses Formular wieder aufgerufen wird, wird per

echo "foo.value = '" . utf8_encode($bar) . "';";

die Textarea gefüllt. Das scheitert, wenn Zeilenumbrüche drin sind, die dann beispielsweise zu

foo.value = 'ein  
Zeilenumbruch';

führen, was natürlich die Fehlerkonsole auf den Plan ruft.

Welche Möglichkeiten gibt es da?

PS: Kontextwechsel sind beachtet
Matthias

--
1/z ist kein Blatt Papier.

  1. Lieber Matthias Apsel,

    PS: Kontextwechsel sind beachtet

    das ist nur anscheinend der Fall. Der tatsächlich übersehene Kontextwechsel ist $string -> $scriptsprachenquellcode. Du möchtest wohl etwas in dieser Art haben:

    echo sprintf(  
        "foo.value = '%s';\r\n",  
      
        utf8_encode(  
            str_replace(  
                array("\r", "\n"),  
                array('\\r', '\\n'),  
                $bar  
            )  
        )  
    );
    

    Ob jetzt utf8_encode() nach der Stringersetzung oder vorher angewendet werden muss, darfst Du ausprobieren.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Om nah hoo pez nyeetz, Felix Riesterer!

      echo sprintf(

      "foo.value = '%s';\r\n",

      utf8_encode(
              str_replace(
                  array("\r", "\n"),
                  array('\r', '\n'),
                  $bar
              )
          )
      );

        
      Ja, sowas möchte ich haben, na mal sehen ...  
        
      Matthias
      
      -- 
      1/z ist kein Blatt Papier.  
      ![](http://www.billiger-im-urlaub.de/kreis_sw.gif)  
      
      
  2. Tach!

    Warum meinst du überhaupt utf8_encode() verwenden zu müssen? Das sieht mir neben dem übersehenen Scriptcode-Kontextwechsel auch noch nach einem Fehler aus. Oder hast du eine (externe) Datenquelle, die nur ISO-8859-1 liefern kann?

    dedlfix.

    1. Om nah hoo pez nyeetz, dedlfix!

      Warum meinst du überhaupt utf8_encode() verwenden zu müssen? Das sieht mir neben dem übersehenen Scriptcode-Kontextwechsel auch noch nach einem Fehler aus. Oder hast du eine (externe) Datenquelle, die nur ISO-8859-1 liefern kann?

      Hmm. Das ist eine Frage, die ich mangels Fachwissen nicht beantworten kann. Um der Sonderzeichenproblematik Herr zu werden, schreibe ich mit utf8_decode() in die DB. Auf die Idee, die DB auf UTF-8 umzustellen, bin ich gar nicht gekommen.

      Ja, da hab ich was zum ausprobieren.

      Matthias

      --
      1/z ist kein Blatt Papier.

      1. Hallo,

        Um der Sonderzeichenproblematik Herr zu werden, schreibe ich mit utf8_decode() in die DB.

        ... und gehst davon aus, die Quelldaten in UTF-8 zu bekommen? Und nimmst in Kauf, bei der Umwandlung Zeichen zu verlieren, nämlich die, die in ISO-8859-1 nicht existieren?

        Auf die Idee, die DB auf UTF-8 umzustellen, bin ich gar nicht gekommen.

        Das überrascht mich, weil ich bisher den Eindruck hatte, dass du in der Thematik recht aufmerksam und gewieft bist.

        Ciao,
         Martin

        --
        Die meisten Menschen werden früher oder später durch Computer ersetzt.
        Für manche würde aber auch schon ein einfacher Taschenrechner genügen.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Om nah hoo pez nyeetz, Der Martin!

          Um der Sonderzeichenproblematik Herr zu werden, schreibe ich mit utf8_decode() in die DB.

          ... und gehst davon aus, die Quelldaten in UTF-8 zu bekommen?

          Ja, denn die Daten kommen aus einem UTF-8 - HTML-Dokument.

          Auf die Idee, die DB auf UTF-8 umzustellen, bin ich gar nicht gekommen.

          Das überrascht mich, weil ich bisher den Eindruck hatte, dass du in der Thematik recht aufmerksam und gewieft bist.

          aufmerksam ja, gewieft eher weniger aber auf jeden Fall lernend.

          Matthias

          --
          1/z ist kein Blatt Papier.

      2. Tach!

        Um der Sonderzeichenproblematik Herr zu werden, schreibe ich mit utf8_decode() in die DB.

        Damit tötest du die Nicht-ISO-8859-1-Zeichen aber wirksam. Es gibt keine Ersatzschreibweise, wie du es aus HTML mit NCRs oder Entitys kennst. Du bekommst nur Fragezeichen und die bleiben beim encode solche.

        Auf die Idee, die DB auf UTF-8 umzustellen, bin ich gar nicht gekommen.

        Den Weg dorthin nicht vergessen (mysql(i)_set_charset/SET NAMES).

        dedlfix.

  3. hi,

    echo "foo.value = '" . utf8_encode($bar) . "';";
    PS: Kontextwechsel sind beachtet

    Achterbahn-Kontextwechsel mit Entgleisung. Warum?:

    echo() gibt Oktetten aus auf STDOUT. Das ist OK, denn STDOUT erwartet Oktetten. utf8_encode() jedoch macht aus Oktetten einen UTF-8-kodierten String.

    Einfacher Test (heute noch, zack, zack!!!11), Quelldatei in UTF-8:

    echo 'ä', utf8_encode('ä');

    Das 'ä' ist OK, der Rest ist Murks ;)

    Hotti

    1. Tach!

      echo() gibt Oktetten aus auf STDOUT. Das ist OK, denn STDOUT erwartet Oktetten.

      In Perl vielleicht. Ob STDOUT mit von der Partie ist oder nicht, spielt in PHP in der Regel keine Rolle. In der Modulvariante wird PHP wohl kaum einen Umweg über STDOUT machen und stattdessen in die entsprechenden Apache-Puffer schreiben.

      utf8_encode() jedoch macht aus Oktetten einen UTF-8-kodierten String.

      In PHP sind die Strings nach wie vor byte-orientiert. utf8_encode()/utf8_decode() schreiben lediglich ein paar Bytes um.

      Einfacher Test (heute noch, zack, zack!!!11), Quelldatei in UTF-8:
      echo 'ä', utf8_encode('ä');
      Das 'ä' ist OK, der Rest ist Murks ;)

      Was genau willst du damit aussagen?

      dedlfix.

      1. hi,

        echo() gibt Oktetten aus auf STDOUT. Das ist OK, denn STDOUT erwartet Oktetten.

        In Perl vielleicht.

        Generell. Alles was auf Handler geht, alles was IO ist.

        Das 'ä' ist OK, der Rest ist Murks ;)

        Was genau willst du damit aussagen?

        Das 'ä' sind utf-8-kodierte Oktetten (Quelldatei utf-8, swo.). Die werden auf STDOUT richtig ausgegeben. Mach den Test.

        Hotti

  4. Moin!

    In einem HTML-Formular befindet sich ein textarea-Element, dessen Inhalt auch Zeilenumbrüche enthalten dürfen.

    Ok.

    Der Inhalt wird in einer SQL-Datenbank gespeichert, so dass aus den Zeilenumbrüchen beispielsweise "\r\n" wird.

    Nein, nicht IN der DB. Da stehen die Bytes "13" und "10" drin, also die ASCII-Zeichen für den Windows-Zeilenumbruch.

    Wenn dieses Formular wieder aufgerufen wird, wird per

    echo "foo.value = '" . utf8_encode($bar) . "';";

    Im HTML-Kontext fehlt da definitiv das Escaping.

    Und welcher Kontext ist das tatsächlich? Javascript? Dann json_encode() und KEINE Anführungszeichen nehmen, um den Variableninhalt von PHP in einen Javascript-Code zum Definieren einer Javascript-Variablen zu wandeln.

    die Textarea gefüllt. Das scheitert, wenn Zeilenumbrüche drin sind, die dann beispielsweise zu

    Textareas füllt man, indem man den Inhalt zwischen öffnendem und schließendem <textarea>-Tag platziert und html-escaped.

    foo.value = 'ein

    Zeilenumbruch';

      
    Javascript! Kontextwechsel nicht beachtet!  
      
    
    > führen, was natürlich die Fehlerkonsole auf den Plan ruft.  
    >   
    > Welche Möglichkeiten gibt es da?  
    >   
    > PS: Kontextwechsel sind beachtet  
      
    Nein!  
      
     - Sven Rautenberg
    
    1. Om nah hoo pez nyeetz, Sven Rautenberg!

      Moin!

      In einem HTML-Formular befindet sich ein textarea-Element, dessen Inhalt auch Zeilenumbrüche enthalten dürfen.

      Ok.

      Der Inhalt wird in einer SQL-Datenbank gespeichert, so dass aus den Zeilenumbrüchen beispielsweise "\r\n" wird.

      Nein, nicht IN der DB. Da stehen die Bytes "13" und "10" drin, also die ASCII-Zeichen für den Windows-Zeilenumbruch.

      Der Code war unvollständig: nach mysqlrealescape und utf8_decode zeigt mir zumindest phpmyadmin bei sql-Operationen "\r\n" an.

      Wenn dieses Formular wieder aufgerufen wird, wird per

      echo "foo.value = '" . utf8_encode($bar) . "';";

      Im HTML-Kontext fehlt da definitiv das Escaping.

      Auch das ist im Original drin.

      Textareas füllt man, indem man den Inhalt zwischen öffnendem und schließendem <textarea>-Tag platziert und html-escaped.

      JA!eins11

      foo.value = 'ein

      Zeilenumbruch';

      
      >   
      > Javascript! Kontextwechsel nicht beachtet!  
      > > PS: Kontextwechsel sind beachtet  
      >   
      > Nein!  
        
      Da die Fragestellung selbst einen Kontextwechsel darstellt, ...  
        
      Matthias
      
      -- 
      1/z ist kein Blatt Papier.  
      ![](http://www.billiger-im-urlaub.de/kreis_sw.gif)  
      
      
      1. Hi,

        Der Inhalt wird in einer SQL-Datenbank gespeichert, so dass aus den Zeilenumbrüchen beispielsweise "\r\n" wird.

        Nein, nicht IN der DB. Da stehen die Bytes "13" und "10" drin, also die ASCII-Zeichen für den Windows-Zeilenumbruch.

        Der Code war unvollständig: nach mysqlrealescape und utf8_decode zeigt mir zumindest phpmyadmin bei sql-Operationen "\r\n" an.

        Ja, wenn er das in Stringform konvertiert.

        \r und \n sind allerdings in ASCII und UTF-8 genau die gleichen Bytes – dafür braucht’s das rumkodieren also bestimmt nicht :-)

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  5. Hi,

    Welche Möglichkeiten gibt es da?

    Ich würde dir empfehlen, beim Übergang zu JavaScript Daten generell als JSON auszuliefern (Hinweis: auch ein einzelner Wert ist valides JSON). Du kannst also einfach json_encode aufrufen.

    echo "foo.value = " .json_encode($bar) . ";";

    Bis die Tage,
    Matti

    1. Om nah hoo pez nyeetz, Matti Mäkitalo!

      Ich würde dir empfehlen, beim Übergang zu JavaScript Daten generell als JSON auszuliefern

      getan, DB umgestellt (findet man das eigentlich auch irgendwo in der GUI von phpmyadmin?)

      Der String lautet lorem ipsum, die Ausgabe (logischerweise) "lorem ipsum". Gibt es einen eleganteren Weg als substr(json_encode($bar),1,-1), die Anführungszeichen zu eleminieren?

      Matthias

      --
      1/z ist kein Blatt Papier.

      1. Tach!

        Ich würde dir empfehlen, beim Übergang zu JavaScript Daten generell als JSON auszuliefern
        getan, DB umgestellt (findet man das eigentlich auch irgendwo in der GUI von phpmyadmin?)

        Der phpMyAdmin ist nur für seine Ausgaben zuständig, nicht aber für die Ausgaben die irgendeine andere Anwendung aus den Daten generiert.

        Der String lautet lorem ipsum, die Ausgabe (logischerweise) "lorem ipsum". Gibt es einen eleganteren Weg als substr(json_encode($bar),1,-1), die Anführungszeichen zu eleminieren?

        Wenn json_encode() das nicht von selbst mit einer der seit 5.4.0 hinzugekommenen und (noch) nicht wirklich dokumentierten Optionen hinbekommt (oder du kein 5.4 hast) dann geht noch trim().

        dedlfix.

        1. Om nah hoo pez nyeetz, dedlfix!

          DB umgestellt (findet man das eigentlich auch irgendwo in der GUI von phpmyadmin?)

          Der phpMyAdmin ist nur für seine Ausgaben zuständig, nicht aber für die Ausgaben die irgendeine andere Anwendung aus den Daten generiert.

          Schon klar, die Sortierreihenfolge kann ich aber auch per Knopfdruck umstellen, warum nicht den Standardzeichensatz? Das finde ich viel wichtiger.

          Matthias

          --
          1/z ist kein Blatt Papier.

          1. Tach!

            Schon klar, die Sortierreihenfolge kann ich aber auch per Knopfdruck umstellen, warum nicht den Standardzeichensatz? Das finde ich viel wichtiger.

            Die Standard-Kodierung kannst du in der Serverkonfiguration ändern, aber das brauchst du nicht, bzw. solltest dich nicht darauf verlassen, was dort konfiguriert ist. Sie nach dem Verbindungsaufbau auszuhandeln ist sicherer, da weiß man was man hat und nicht nur was theoretisch sein sollte.

            dedlfix.

      2. مرحبا

        Der String lautet lorem ipsum, die Ausgabe (logischerweise) "lorem ipsum". Gibt es einen eleganteren Weg als substr(json_encode($bar),1,-1), die Anführungszeichen zu eleminieren?

        Wenn du auf das Array über einen entsprechenden Key zugreifst bekommst du den Inhalt doch bereits ohne Anführungszeichen. Was machst du mit den Daten?

        mfg

      3. Moin!

        Om nah hoo pez nyeetz, Matti Mäkitalo!

        Ich würde dir empfehlen, beim Übergang zu JavaScript Daten generell als JSON auszuliefern

        getan, DB umgestellt (findet man das eigentlich auch irgendwo in der GUI von phpmyadmin?)

        Der String lautet lorem ipsum, die Ausgabe (logischerweise) "lorem ipsum". Gibt es einen eleganteren Weg als substr(json_encode($bar),1,-1), die Anführungszeichen zu eleminieren?

        Sorry, wenn ich da jetzt doch noch mal unwirsch dazwischenhaue:

        Warum gibst du uns denn nicht mal ein KOMPLETTES CODEBEISPIEL?

        Immer wenn du so ein Fragment wie oben postest, dann schreit es mich an: "Kontext mißachtet!"

        json_encode() tut genau eines: Es wandelt eine PHP-Variable beliebigen Inhalts in eine korrekte Javascript-Notation um, die sinngemäß dieselbe Variable in Javascript erzeugen könnte.

        DAS IST ABER NICHT DIE GANZE GESCHICHTE!

        Denn Javascript steht ja meist nicht allein. Würde man tatsächlich eine eigene Javascript-Datei, die durch einen separaten Request dynamisch entsteht, mit PHP-Variablen befüllen wollen, wäre json_encode() genau richtig. Dann allerdings SIND DIE ANFÜHRUNGSZEICHEN ZWINGEND NOTWENDIG! Sie dürfen nicht entfernt werden, sie gehören zum encodeten Wert dazu. Vielmehr darf man eben keine statischen Anführungszeichen im Javascript-Code verwenden, denn wenn welche notwendig sind, kommen die von json_encode().

        Jetzt wird die ganze Sache allerdings komplizierter dadurch, dass dynamisch generiertes Javascript in der Regel irgendwo in einem HTML-Template steht, somit der Javascript-Code nicht nackt, sondern eingebettet zwischen <script></script> platziert wird, und dass der Browser als allererstes die Template-Ausgabe erstmal durch seinen HTML-Parser jagt und decodiert - und erst DANACH kommt der Javascript-Parser für die gefundenen Script-Inseln der Seite.

        Die Ausgabe von json_encode() muss also, genau wie der gesamte Javascript-Code an sich, auch noch für den HTML-Kontext escaped werden. Und genau da wird's leicht haarig, denn die Browser akzeptieren neben dem offensichtlichen leider auch noch allen möglichen Müll und sind dementsprechend angreifbar, wenn man nicht aufpasst. Beispielsweise beendet jegliches Auftreten der Zeichenkette "</script>" den aktuellen Javascript-Bereich, unabhängig davon, ob das laut Javascript-Syntax dort erlaubt ist, oder nicht. Denn dass der Javascript-Code kaputt ist, interessiert den HTML-Parser nicht im geringsten.

        Insofern also bittebittebitte: Komplette Codebeispiele, nichts reduzieren, insbesondere nicht vorwegnehmen, dass "der Kontextwechsel garantiert beachtet wurde" - denn genau das ist in der gesamten Diskussion dieses Threads zweifelhaft, aber eben nur dann beweisbar, wenn man wirklich komplett von vorn bis hinten und zurück weiß, was passieren soll.

        Wenn ein Kontextwechsel nicht korrekt beachtet wird, entsteht nicht nur eine kaputte Textarea, sondern eine Angriffslücke für XSS. Und sowas ist böse.

        - Sven Rautenberg

        1. Tach!

          Die Ausgabe von json_encode() muss also, genau wie der gesamte Javascript-Code an sich, auch noch für den HTML-Kontext escaped werden. Und genau da wird's leicht haarig, denn die Browser akzeptieren neben dem offensichtlichen leider auch noch allen möglichen Müll und sind dementsprechend angreifbar, wenn man nicht aufpasst. Beispielsweise beendet jegliches Auftreten der Zeichenkette "</script>" den aktuellen Javascript-Bereich,

          Laut HTML-4-Spec reicht dazu bereits </. Ob HTML5 da was anderes vorgibt, weiß ich nicht. Weiterhin gilt, dass der Inhalt des Script-Bereichs nicht weiter gemäß HTML dekodiert wird. Im Script-Bereich muss also außer dem </ nur der Javascript-Kontext beachtet werden. Anders ergeht es Code in einem HTML-Attribut (wie Eventhandlern), der wird nach HTML-Regeln behandelt.

          dedlfix.

          1. Om nah hoo pez nyeetz, dedlfix!

            Die Ausgabe von json_encode() muss also, genau wie der gesamte Javascript-Code an sich, auch noch für den HTML-Kontext escaped werden. Und genau da wird's leicht haarig, denn die Browser akzeptieren neben dem offensichtlichen leider auch noch allen möglichen Müll und sind dementsprechend angreifbar, wenn man nicht aufpasst. Beispielsweise beendet jegliches Auftreten der Zeichenkette "</script>" den aktuellen Javascript-Bereich,

            Laut HTML-4-Spec reicht dazu bereits </. Ob HTML5 da was anderes vorgibt, weiß ich nicht. Weiterhin gilt, dass der Inhalt des Script-Bereichs nicht weiter gemäß HTML dekodiert wird. Im Script-Bereich muss also außer dem </ nur der Javascript-Kontext beachtet werden. Anders ergeht es Code in einem HTML-Attribut (wie Eventhandlern), der wird nach HTML-Regeln behandelt.

            json_encode liefert das Escaping gleich mit.

            var_dump(json_encode(</script>)); liefert </script>

            Matthias

            --
            1/z ist kein Blatt Papier.

        2. Om nah hoo pez nyeetz, Sven Rautenberg!

          Warum gibst du uns denn nicht mal ein KOMPLETTES CODEBEISPIEL?

          Weil ich
          * befürchte, mich mit meinem Projekt übernommen zu haben,
          * die Projektidee so gut finde, dass ich sie noch nicht publik machen möchte,
          * mich nicht (schon wieder) blamieren möchte,
          * erst seit einem Jahr an Datenbanken im Webkontext umherspiele,
          * nicht als Sockenpuppe gepostet habe,
          * zwar einiges mehr über PHP/SQL/JS weiß als meine Oma, das aber immer noch "Nichts" ist,
          * mir dieses Wissen oft durch trial und error angeeignet habe,
          * mich trotzdem freue, soweit gekommen zu sein und nun
          * befürchte, dass von meinem Erfolg nichts bleibt,

          hätte ich es gern weniger öffentlich.

          Matthias

          --
          1/z ist kein Blatt Papier.

          1. مرحبا

            Weil ich
            * befürchte, mich mit meinem Projekt übernommen zu haben,

            Jetzt mal nicht den Kopf in den Sand stecken.

            * die Projektidee so gut finde, dass ich sie noch nicht publik machen möchte,

            Nicht das Projekt sollst du posten, sondern ein auf dein Fall reduziertes Beispiel.

            Baue das Formular nach, am besten nur mit 2-3 Feldern, neuen Tabellen-Namen und auch die Input-Felder kannst du verfremden, so dass keiner Rückschlüsse auf das Projekt ziehen kann.
            Dann müssen noch die ganzen Ersetzungsfunktionen rein, so wie du sie anwendest.
            Ein kleines Beispiel sollte mit weniger als 200 Zeilen Code machbar sein. Und schämen brauchst du dich auch nicht. Wie willst du lernen, wenn dich niemand kritisiert?
            Ich krieg alle paar Tage zu lesen, "wie Murks meine Scripte sind". Nimm's nicht Persönlich.

            mfg

        3. Om nah hoo pez nyeetz, Sven Rautenberg!

          Folgendes leistet entsprechend meiner Tests das gewünschte:

          Der Nutzer soll mithilfe eines normalen, etwas umfangreichem HTML-Formular Daten speichern können. Das Formular wird grundsätzlich immer ausgeliefert, per display: none; ausgeblendet und mit JS eingeblendet. Für Berechnungen im Formular ist ohnehin JS notwendig, deshalb gibt es keine no-JS-Alternative.

          Für einen neuen Datensatz wird ein leeres Formular eingeblendet

          <form>  
            ...  
            <input type="text" name="person">  
            <label for="notiz">Ihre Bemerkungen:<textarea id="notiz" name="notiz" rows="2"></textarea></label>  
            ...  
          </form>
          

          Die Eingaben werden in die Datenbank gespeichert.

          $abfrage = "INSERT INTO foo (person, notiz) VALUES ('"  
          . mysql_real_escape_string($_POST['person']) . "', '"  
          . mysql_real_escape_string($_POST['notiz']) . "')"
          

          Sollte ein schon bestehender Datensatz aufgerufen werden, wird das Formular gefüllt durch

          echo "f.person.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['name']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";  
          echo "f.notiz.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['notiz']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";
          

          zum schnelleren Lesen:
          1. json_encode
          2. die begrenzenden Anführungszeichen entfernen
          3. htmlspecialchars
          4. & wieder erlauben

          Das htmlspecialchars ist erst nach diesem Thread dazugekommen. Ist das hier wirklich notwendig? Jedenfalls kann ich als Person auch </script> eingeben, ohne das das Script abgebrochen wird.

          Welche Kontextwechsel könnten noch nicht berücksichtigt sein, welche sonstigen Hinweise sind noch zu geben?

          Matthias

          --
          1/z ist kein Blatt Papier.

          1. Moin!

            <form>

            ...
              <input type="text" name="person">
              <label for="notiz">Ihre Bemerkungen:<textarea id="notiz" name="notiz" rows="2"></textarea></label>
              ...
            </form>

            
            >   
              
            
            > Sollte ein schon bestehender Datensatz aufgerufen werden, wird das Formular gefüllt durch  
            >   
            > ~~~php
            
            echo "f.person.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['name']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";  
            
            > echo "f.notiz.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['notiz']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";
            
            

            Und wo hinein echost du das?

            zum schnelleren Lesen:

            1. json_encode

            Im Javascript-Kontext notwendig.

            1. die begrenzenden Anführungszeichen entfernen

            Warum? json_encode liefert die mit, warum was eigenes produzieren? Das Escaping der Anführungszeichen innen basiert auf den Anführungszeichen außen.

            1. htmlspecialchars

            Mit NOQUOTES - was ich erstmal für problematisch halte. Warum dies? -- Relevant ist dafür allerdings der Kontext, in dem die Ausgabe stattfindet, und den enthälst du ja schon wieder vor... :)

            1. & wieder erlauben

            Warum?

            Das htmlspecialchars ist erst nach diesem Thread dazugekommen. Ist das hier wirklich notwendig? Jedenfalls kann ich als Person auch </script> eingeben, ohne das das Script abgebrochen wird.

            Kontext?

            Welche Kontextwechsel könnten noch nicht berücksichtigt sein, welche sonstigen Hinweise sind noch zu geben?

            Siehe oben...

            - Sven Rautenberg

            1. Om nah hoo pez nyeetz, Sven Rautenberg!

              <form>

              ...
                <input type="text" name="person">
                <label for="notiz">Ihre Bemerkungen:<textarea id="notiz" name="notiz" rows="2"></textarea></label>
                ...
              </form>

              
              > >   
              >   
              > > Sollte ein schon bestehender Datensatz aufgerufen werden, wird das Formular gefüllt durch  
              > >   
              > > ~~~php
              
              echo "f.person.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['name']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";  
              
              > > echo "f.notiz.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['notiz']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";
              
              

              Und wo hinein echost du das?

              In ein script-Element eines HTML-Dokuments

              zum schnelleren Lesen:

              1. json_encode
                Im Javascript-Kontext notwendig.
              1. die begrenzenden Anführungszeichen entfernen
                Warum? json_encode liefert die mit, warum was eigenes produzieren? Das Escaping der Anführungszeichen innen basiert auf den Anführungszeichen außen.

              Also in echo "f.person.value = '" einfach das ' weglassen

              1. htmlspecialchars
                Mit NOQUOTES - was ich erstmal für problematisch halte. Warum dies? -- Relevant ist dafür allerdings der Kontext, in dem die Ausgabe stattfindet, und den enthälst du ja schon wieder vor... :)

              Die Ausgabe erfolgt im HTML-Formular als Werte von einem Textarea- bzw. Input-Element, ich dachte, das geht aus meinem Posting hervor

              1. & wieder erlauben
                Warum?

              Damit die "Laus" & Klaus nicht zu die &quot;Laus&quot; &amp; Klaus wird.

              Das htmlspecialchars ist erst nach diesem Thread dazugekommen. Ist das hier wirklich notwendig? Jedenfalls kann ich als Person auch </script> eingeben, ohne das das Script abgebrochen wird.

              Kontext?

              s.o.

              Matthias

              --
              1/z ist kein Blatt Papier.

              1. Tach!

                echo "f.person.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['name']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";

                echo "f.notiz.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['notiz']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";

                
                > > Und wo hinein echost du das?  
                > In ein script-Element eines HTML-Dokuments  
                  
                [Im Script-Element gilt der HTML-Kontext nicht.](http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel/erkennen_und_behandeln#Script-_und_Style-Bereiche_im_HTML-Dokument) Ein &amp; wären dort 5 einzelne Zeichen. Das & muss dort also ein & sein, damit es ein & ist. Im Eventhandler stehender Javascript-Code ist allerdings den HTML-Regeln unterworfen.  
                  
                htmlspecialchars() ist also für den <script>-Bereich nicht sinnvoll, jedoch für Eventhandler notwendig. Für <script> muss man aber die Javascript-Regeln und -Fallstricke beachten und entweder [eine selbst geschriebene Maskierfunktion verwenden](http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel/erkennen_und_behandeln#JavaScript) oder das zusätzlich noch quotierende json\_encode() nehmen. Teilstrings können also mit der Maskierfunktion behandelt eingefügt werden und für komplette Strings inklusive Gänsefüße kann man json\_encode() nehmen.  
                  
                  <?php echo 'var foo = "foo ' . javascript\_escape($bar) . ' qux"'; ?>  
                  
                $bar ist oben ein Teilstring und unten ein eigenständiger, wobei das Ergebnis betrachtet werden muss. Die ' sind PHP-String-Begrenzer und " sind die von Javascript.  
                  
                  <?php echo 'var foo = "foo " + ' . json\_encode($bar) . ' + " qux"'; ?>  
                  
                
                > Also in `echo "f.person.value = '"`{:.language-php} einfach das `'`{:.language-php} weglassen  
                  
                Ja, wenn json\_encode() die letzte ausgeführte Funktion vor dem Einfügen ist.  
                  
                  
                
                > > > 3. htmlspecialchars  
                > > Mit NOQUOTES - was ich erstmal für problematisch halte. Warum dies? -- Relevant ist dafür allerdings der Kontext, in dem die Ausgabe stattfindet, und den enthälst du ja schon wieder vor... :)  
                > Die Ausgabe erfolgt im HTML-Formular als Werte von einem Textarea- bzw. Input-Element, ich dachte, das geht aus meinem Posting hervor  
                  
                Wenn du ein Dokument erzeugst, in dem ein <textarea> und darin Text steht, gehört der ge-htmlspecialchar()t. Erzeugst du aber Javascript-Code, der erst im Browser tätig wird und die Textarea füllt, dann bist du zunächst im Javascript-Kontext (vermutlich im erwähnten <script>-Bereich). Erst zur Laufzeit wechselt der Kontext, wenn du mit Javascript den Text in die Textarea schreibst. Ich bin nicht auf dem Laufenden, was da gerade aktuell ist, aber früher gab es zumindest innerText und innerHTML. innerText interpretiert gar nichts und fügt den Text 1:1 ein, innerHTML parst den String nach HTML-Regeln und erzeugt Elemente.  
                  
                
                > Damit die "Laus" & Klaus nicht zu die &quot;Laus&quot; &amp; Klaus wird.  
                > > > Das htmlspecialchars ist erst nach diesem Thread dazugekommen. Ist das hier wirklich notwendig? Jedenfalls kann ich als Person auch </script> eingeben, ohne das das Script abgebrochen wird.  
                > > Kontext?  
                  
                Das entfällt, wenn du die obigen Kontextwechsel richtig beachtest. Insgesamt ist es immer etwas knifflig, wenn mehrere Kontexte zusammengeschachtelt werden sollen. Hier hilft mitunter schrittweises Vorgehen. Erstmal eine statische HTML-Seite mit syntaktisch korrektem JS-Code und Platzhaltern drin erstellen, dann statt der Platzhalter die mit PHP erzeugten Werte einfügen. Das Ergebnis muss dann wie die statische Seite aussehen.  
                  
                  
                dedlfix.
                
          2. Moin!

            echo "f.person.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['name']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";

            echo "f.notiz.value = '" . str_replace('&amp;','&',htmlspecialchars(substr(json_encode($gkind['notiz']),1,-1), ENT_NOQUOTES, $double_encode = false)) . "';\n";

              
            Ach ja, noch ein Fail: htmlspecialchars hat VIER Parameter, bis auf den ersten alle optional, und dein "double\_encode" ist wohl als vierter Parameter gemeint, geht aber als dritter in die Funktion ein und setzt das ENCODING! PHP ist nicht Python, du kannst optionale Parameter nicht auslassen!  
              
              
             - Sven Rautenberg