CPAN: UTF-8 dekodieren (?)

Beitrag lesen

Dein erstes Programm ist mangelhaft, es kompiliert nicht einmal. Gib doch ein wenig acht, was für Code du postet! Liederliche Programmierer können niemals gute Ergebnisse erzielen.

#Habe ich jetzt mal von dir übernommen, aber ein schlichtes
#$noutf = decode("UTF-8", $xline); geht genauso

Diese Aussage ist falsch, was du selbst hättest beobachten können, wenn du ein wenig ausgiebiger getestet hättest. Fehlerhafte Oktettsequenzen werden nämlich so, wie du es geschrieben hast, einfach mit Unicodeersetzungszeichen verbuttert und ruinieren damit unwiderruflich deine Textdaten ohne irgendeine Warnung oder Fehlermeldung. Deshalb bekommst du diesen Ruin erst mit, wenn es schon zu spät ist, oder womöglich gar nicht.

Nach Behebung der offensichtlichen Syntaxfehler in deinem Programm bleibt festzustellen, dass du für Texteingaben hereinkommende Oktette zwar korrekt nach Zeichen dekodierst, aber dann versuchst, die Zeichen unkodiert auszugeben. Das ist falsch. Du musst Zeichen, wenn sie nach draußen gelangen, in Oktette kodieren, siehe Dokumentation.

Außerdem musst du Inhalte maskieren, wenn sie in HTML-Kontext eingebettet sind; das hast du auch vernachlässigt und somit eine sicherheitsrelevante Cross-Site-Scripting-Lücke geschaffen! Das ist echt schlimm. Lies dir mein Programm noch einmal aufmerksam durch und vollziehe jeden Schritt nach.

Ich schrieb:

Und nun die übliche Belehrung: … Steige um auf PSGI und ein modernes Webframework.

Warum gehst du nicht auf den Rat ein? Mit CGI.pm halst du dir nur unnötig Arbeit und Ärger auf.

if (is_utf8($val))
{
  print "UTF-8: ";
}

Nein, diese Abfrage ist vollkommen falsch und sinnlos und muss entfernt werden.
• Falsch, weil is_utf8 nicht überprüft, ob eine Oktettfolge gültiges UTF-8 ist¹, sondern ob beim skalaren Wert ein gewisser Markierer gesetzt ist. Dieser Markierer ist rein für Perls interne Zwecke und hat nur die Leute zu interessieren, welche XS programmieren².
• Sinnlos, weil du eigentlich prüfen möchtest, ob du Zeichen oder Oktette hast. Perl kann dir das nicht sagen, du musst stattdessen selber Buch darüber führen, welcher Semantik eine Variable unterliegt! Ich rüge die Verwendung von deinen Variablennamen, z.B. $xline, das ist sagt nichts darüber aus, welche Bedeutung der Inhalt halt. Benutze in Zukunft eine Form der ungarischen Notation, bei der man auf einen Blick erkennt, ob eine Variable Oktette oder Zeichen enthalten soll.

¹ Auf gültiges UTF-8 überprüft man einfach, indem man versucht zu dekodieren, wie ich das in meinem Programm geschrieben habe. Wenn es sich um ungültiges UTF-8 handelt, gibt es eine Exception.
² Du programmierst nicht XS.

use bytes;

Das ist Murks, entferne das. Die Verwendung dieses Pragmas ist nahezu immer ein Versuch, etwas mit der groben Keule geradezubiegen. Dabei musst du zwangsläufig scheitern und machst aus Unverständnis nur noch mehr kaputt, siehe Dokumentation.

use XML::DOM;

Dieses Modul ist überholt, man verwendet XML::LibXML.

use CGI qw(-utf8);

Die Verwendung des Imports -utf8 ist problematisch, entferne ihn und dekodiere für Texteingaben hereinkommende Oktette manuell, so wie ich das in meinem Programm gezeigt habe! Für Nicht-Text-Eingaben wie z.B. Uploads verhält sich CGI.pm unter dem Einfluss des Imports -utf8 fehlerhaft und zerstört unwiderruflich die Daten, siehe Dokumentation.

Zum Rest vom Code äußere ich mich vorerst nicht im Detail. Setze meine Ratschläge um und melde deinen Fortschritt.