Encoding Probleme mit minidom

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Danke Dir :) Werd ich morgen mal probieren!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben:Oh, sorry, habe deinen Post ganz übersehen,
Hyperion hat geschrieben:Und das andere Problem? Irgend eine Ahnung, wie ich den form-Parameter nun in unicode wandeln kann?
Form-Parameter?

Du kannst Bytestrings alle mit ``bytestringobjekt.encode('encoding_des_bytestrings')`` zu machen (wobei ``encode()`` natürlich einen Unicode-String zurückgibt und nicht den Bytestring ändert, versteht sich).
Naja, man muss die Parameter des form per .decode("kodierung") in unicode wandeln ;) Egal, jetzt hab ichs kapiert.

Dennoch stellt sich mir nun eine Frage: Wie kann ich denn bitte bei einem CGI-Script sicherstellen, dass das richtige "Coding" ankommt bei meinem Script? Ok, beim form-Tag in HTML kann man die Kodierung zwar einstellen, aber erstens wird das sicher nicht durch jeden Browser unterstützt und zweitens kann man ein Script ja auch umgehen! Gibt es für dieses Problem eine Lösung?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Gegen mutwillig falsche Encodings kannst du nichts machen. Du kannst versuchen das Encoding zu raten, aber sauber wäre es einfach dem Formular zu sagen, dass du ein bestimmtes Encoding erwartest und fertig. Man kann nicht auf jede erdenkliche Blödheit von Browsern reagieren (wobei ich jetzt nicht wüsste welcher halbwegs aktuelle Browser kein UTF-8 schicken könnte). Letztendlich ist ein falsches Encoding auch kein Beinbruch, die Umlaute sehen dann eben zerhackt aus, aber es ist kein Sicherheitsproblem und man könnte es auch in Einzelfällen manuell wieder richten indem man es umkodiert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok, danke! Prinzipiell hast Du damit wohl Recht. Kann man denn ein Script zum Absturz bringen, wenn man bewusst in ner falschen Zeichencodierung sendet? Also wenn ich UTF-8 erwarte und man mir sonst was schickt ... oder ist es prinzipiell sinnvoll utf-8 zu erwarten?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Zum Absturz bringen: ja, du kannst einen UnicodeDecodeError bekommen, wenn du versuchst einen Unicode-String in in ein Encoding zu kodieren welches nicht alle Zeichen des Unicode-Strings darstellen kann. Häufigstes Beispiel: Unicode-Strings mit Umlauten werden versucht in ASCII zu kodieren - kann nicht funktionieren.

Aber da musst du eben aufpassen, dass du intern Unicode verwendest und extern UTF-8 erwartest und das auch rausgibst. UTF-8 ist definitiv eine gute Wahl, für ein Datenaustausch-Encoding.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ja klar, nach außen UTF-8 rausgeben ist ja kein Problem! Und intern mit Unicode arbeiten ist auch kein Problem. Also ist quasi die einzige Schwachstelle die "Eingabe"! Naja, ich hoffe mal, dass ich da mit UTF-8 keine Probleme haben werde.

Ist es nicht so, dass UTF-X Sachen für alle Zeichen der Welt ausgelegt ist? Wenn ja, sollte es doch prinzipiell keine Zeichen geben, die zumindest mal nicht interpretierbar wären! Damit wäre ja dann der Text ggf. schrottig in seiner Darstellung, wenn eben kein UTF-8 eingegeben worden ist, aber bei der Wandlung nach Unicode sollte es doch dann keine Probleme geben, sehe ich das richtig?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wenn du einen Text der, sagen wir mal in KOI8-R kodierst ist, versuchst mit UTF-8 in Unicode zu dekodieren bekommst du nur Garbage im Unicode-String. Das liegt daran, dass die Zeichen interpretiert werden und das was Я in KOI8-R ist, kann in UTF-8 ganz was anderes sein.

Code: Alles auswählen

>>> s = u"Я"
>>> s
u'\u042f'
>>> print s
Я
>>> s.encode('koi8-r')
'\xf1'
>>> _.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.4/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf1 in position 0: unexpected end of data
In dem Fall funktioniert es nicht einmal, da die KOI8-R Sequenz von Я kein gültiges UTF-8 ist.

Ergo: Nein, das das Unicode alle Zeichen darstellen kann heißt nicht, dass man auf einmal Bytestrings alle als UTF-8 ansehen kann. Dekodieren muss man sie immer mit dem richtigen Encoding.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok! Da ist ja wirklich mistig! Also am besten alle Eingaben versuchen aus dem erwarteteten Zeichencodec in Unicode zu wandeln und das ganze in nem try-catch Block und ggf. die Annahme quasi verweigern. Das sollte man mal in einem CGI-Tutorial erwähnen ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das würde ich nicht machen, ich halte es für nicht sonderlich schlau. Letztendlich wird durch das try-except *irgendein* Encoding gewählt, nicht das *richtige* sondern nur eines welches keine Exception wirft.

Ich gebe dir mal ein Beispiel.

Code: Alles auswählen

>>> bg = u"България"
>>> bg_utf8 = bg.encode('utf8')
>>> bg_utf8
'\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd0\xb8\xd1\x8f'
>>> bg_koi = bg.encode('koi8-r')
>>> bg_koi
'\xe2\xdf\xcc\xc7\xc1\xd2\xc9\xd1'
>>> print bg_koi
�������
>>> print bg_utf8
България
Ich erstelle hier einen Unicode-String mit "Bulgarien" als Inhalt. Dieser kommt als UTF-8 Bytefolge rein, weil mein Environment auf UTF-8 gestellt wird. Das passiert implizit, man kann es aber auch explizit machen. Danach erstelle ich zwei Byte-Strings: einen UTF-8 kodierten und einen mit KOI8-R kodierten (ich weiß nicht was man so üblicherweise für ein Encoding in Bulgarien her nimmt, ob es nun KOI8-R ist oder CP1251 oder DOS 866 oder ISO-8859-5 ist). Nun versuche ich beide auszugeben. Der KOI8-R kodierte Text erzeugt bei mir nur Fragezeichen, da meine Konsole UTF-8 erwartet und damit nichts anzufangen weiß (aber keine Ausnahmen wirft). Der UTF-8 kodierte Text wird hingegen einwandfrei angezeigt.

Wenn du nicht auch lauter falsch dekodierte Strings haben willst, dann solltest du ein Encoding festlegen welches du annimmst.
Und bevor du über try-except das Encoding zu raten versuchst, nimm besser `encodinghelper` oder `chardet`. Nur sei dir bewusst, dass man das Encoding eines Textes nur erraten kann, nicht aber es sicher bestimmen.

Edit: Oh, ich sehe dass da was vom Forum zerlegt wurde. Du kannst aber die \???-Escape-Sequenzen verwenden um die Strings einzugeben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben:Das würde ich nicht machen, ich halte es für nicht sonderlich schlau. Letztendlich wird durch das try-except *irgendein* Encoding gewählt, nicht das *richtige* sondern nur eines welches keine Exception wirft.

...

Wenn du nicht auch lauter falsch dekodierte Strings haben willst, dann solltest du ein Encoding festlegen welches du annimmst.
Da hast Du mich glaub ich missverstanden! Ich meinte ja, dass ich im try-except Block das Encoding versuche zu wandeln, welches ich erwarte! Sollte das nicht klappen, so erhalte ich einen Fehler und kann darauf reagieren! Ich wollte nicht endlich viele hintereinanderschachteln, um das richtige / erste ohne Exceptions zu wählen ;)
Und bevor du über try-except das Encoding zu raten versuchst, nimm besser `encodinghelper` oder `chardet`. Nur sei dir bewusst, dass man das Encoding eines Textes nur erraten kann, nicht aber es sicher bestimmen.
Ok, das werd ich mir mal ansehen, danke. Auch für das Beispiel. Ich werds mir morgen mal genauer ansehen und ausprobieren!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Da hast Du mich glaub ich missverstanden! Ich meinte ja, dass ich im try-except Block das Encoding versuche zu wandeln, welches ich erwarte! Sollte das nicht klappen, so erhalte ich einen Fehler und kann darauf reagieren!
Habe dich wirklich vorhin falsch verstanden. So passt es natürlich :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten