Validome: Korrekte Zeichensatzkodierung ermitteln

Hallo,
im Zuge der Weiterentwicklung von Validome wühle ich mich schon seit Tagen durch die W3C-Specs ohne klärende Antworten zu erhalten.
Diesbezügliche Mails an das W3C blieben unbeantwortet oder wurden nicht sonderlich kompetent beantwortet.
Deshalb möchte ich die Thematik hier zur Diskussion stellen wie denn ein Validator (oder sonstige Software) die für ein Dokument zu verwendete Zeichensatzkodierung ermitteln soll.
Zum Ersten handelt es sich um die Spezifikation zu HTML:
http://edition-w3.de/TR/1999/REC-html401-19991224/charset.html#h-5.2.2.

Zur Ermittlung der Zeichensatzcodierung wird dort folgende Reihenfolge angegeben:
1. HTTP-"charset"-Parameter in einem "Content-Type"-Feld.
2. ine META-Deklaration mit "http-equiv", gesetzt auf "Content-Type" und einem gesetzten Wert für "charset".

Folgende Fragen tun sich nun auf:
1. Wenn ein Dokument z.B. in UTF-16 mit Byte order Mark (BOM) kodiert ist, was bei HTML durchaus erlaubt ist, hat dann die BOM-Kodierung Vorrang vor der Meta-Angabe, oder sogar vor der Angabe des HTTP-Header (eher Unwahrscheinlich, wäre aber praktikabel)?
2. Die Spezifikation lässt einen im Unklaren, welche Zeichensatzkodierung zu benutzen ist wenn überhaupt keine diesbezüglichen Informationen geliefert werden (kein HTTP-Charset, kein BOM, kein Meta-Charset). Dort steht das in solchen Fällen RFC2616 zu ignorieren ist (welches für solche Fälle ISO-8859-1 vorsieht) und kein Standardwert angenommen werden soll. Wenn dem so ist, müsste dann ein Fehler gemeldet werden?! Der W3C-Validator führt in solchen Fällen einen Fallback zu US-ASCII durch, was sicherlich falsch sein dürfte (Validome momentan ISO-8859-1).
Wie geht man in solchen Fällen korrekt vor?

Und dann habe ich noch Klärungsbedarf bei XML/XHTMLhttp://edition-w3c.de/TR/2000/REC-xml-20001006/#sec-guessing:
1. Wie ist zu Verfahren wenn z.B. der Byte order Mark UTF-8 "sagt", aber das binäre Muster (automatische Erkennung) UTF-16?
2. Was muss passieren wenn in der XML-Deklaration ein anderer Zeichensatz steht als im BOM/automatische Erkennung/HTTP-Header?

Im Grunde reduzieren sich meine Fragen auf die Prioritätenreihenfolge der möglichen Zeichensatzkodierungen (HTTP/BOM/automatische Erkennung/XML-Deklaration/Meta-Tag) in Abhängigkeit zu HTML oder XML/XHTML, und die zu verwendende Zeichensatzkodierung wenn überhaupt keine Deklariert wurde.

Viele Grüße
Thomas Mell

  1. Hi,

    1. Die Spezifikation lässt einen im Unklaren, welche Zeichensatzkodierung zu benutzen ist wenn überhaupt keine diesbezüglichen Informationen geliefert werden (kein HTTP-Charset, kein BOM, kein Meta-Charset).

    Sie widerspricht sich offenbar auch teilweise (http://forum.de.selfhtml.org/archiv/2005/6/t110465/#m694488 ff).

    freundliche Grüße
    Ingo

  2. Hallo,

    Verzeihung übrigens, dass ich damals auf deine Mail nicht geantwortet hatte -- ich war erst einige Zeit offline und habe dann keine Muße gefunden. Du kannst mir den aktuell gebrauchten Algorithmus aber gerne noch einmal zuschicken, falls dich meine Meinung noch interessiert.

    1. Wenn ein Dokument z.B. in UTF-16 mit Byte order Mark (BOM) kodiert ist, was bei HTML durchaus erlaubt ist, hat dann die BOM-Kodierung Vorrang vor der Meta-Angabe, oder sogar vor der Angabe des HTTP-Header (eher Unwahrscheinlich, wäre aber praktikabel)?

    Da gibt es meines Wissens keine Vorschrift. Ich würde dem gesunden Menschenverstand nach urteilen: Manche Browser beachten die Meta-Angabe, für andere geht das BOM über alles. Sich widersprechende Kodierungsangaben sind also in der Praxis problematisch. Ich würde eine Fehlermeldung ausgeben oder UTF-16 benutzen, aber eine dicke Warnung ausgeben.

    1. Die Spezifikation lässt einen im Unklaren, welche Zeichensatzkodierung zu benutzen ist wenn überhaupt keine diesbezüglichen Informationen geliefert werden (kein HTTP-Charset, kein BOM, kein Meta-Charset). Dort steht das in solchen Fällen RFC2616 zu ignorieren ist (welches für solche Fälle ISO-8859-1 vorsieht) und kein Standardwert angenommen werden soll. Wenn dem so ist, müsste dann ein Fehler gemeldet werden?!

    Ja, das ist richtig.

    Ein HTML-Dokument, das weder eine eingebundene Kodierungsangabe hat, noch eine Kodierungsangabe durch das darüberliegende Protokoll (z.B. HTTP) übermittelt wurde, ist nicht standardkonform.
    Darüber hinaus ist die Regelung »eine Kodierungsangabe im Übertragungsprotokoll reicht« meiner Meinung nach wenig sinnvoll. Wenn der Anwender das Dokument lokal speichert oder weiterverschickt oder durch ein anderes Protokoll als vorgesehen bezieht, muss der Browser wieder raten. Denn nicht alle Browser sind so klug, die Kodierungsangabe aus dem HTTP-Header beim Speichern eines Dokuments in ein meta-Element zu schreiben. Sprich, ich schlage vor, bei einer im Dokument selbst fehlenden Kodierungsangabe einen Hinweis auszugeben.

    Der W3C-Validator führt in solchen Fällen einen Fallback zu US-ASCII durch, was sicherlich falsch sein dürfte (Validome momentan ISO-8859-1).
    Wie geht man in solchen Fällen korrekt vor?

    Korrekt zu den Standards eben: Wie du sagst, *kein* Fallback, sondern die Validierung abbrechen und eine Meldung ausgeben, dass eine Kodierungsangabe nicht nur in der Theorie, sondern auch in der Praxis unbedingt erforderlich bzw. ratsam ist.
    Oder eben ein Fallback zu Latin1 (dies kann man schwach über RFC 2616 rechtfertigen, auch wenn diese Regelung es für HTML außer Kraft gesetzt ist) mit einer dicken Warnung, wie es meines Wissens der W3C-Validator auch macht (im Sinne von: »ja, dieses Dokument entspricht zwar der DTD, aber hat trotzdem andere schwere Fehler, denn wir haben einfach einmal irgendeine Kodierung verwendet«).

    Und dann habe ich noch Klärungsbedarf bei XML/XHTMLhttp://edition-w3c.de/TR/2000/REC-xml-20001006/#sec-guessing:

    1. Wie ist zu Verfahren wenn z.B. der Byte order Mark UTF-8 "sagt", aber das binäre Muster (automatische Erkennung) UTF-16?

    a) F.1 des Anhangs empfiehlt, dass UTF-8 anzunehmen ist, sobald ein so kodiertes BOM auftritt.
    b) Wenn UTF-16 verwendet wird, muss ein entsprechendes BOM verwendet werden (das ist allerdings normativ). Wenn kein UTF-16-kodiertes BOM vorkommt, dann ist es definitionsgemäß kein UTF-16.
    c) Wenn trotzdem offenbar UTF-16-kodierte Zeichen in einer als UTF-8 ausgezeichneten XML-Datei vorkommen, so ist es keine gültige XML-Datei. Denn die ganzen Null-Bytes von UTF-16 verweisen in UTF-8 auf U+0000, das in einem XML-Dokument nicht erlaubt ist.
    d) Ein »ä« beispielsweise ist in UTF-16 11100100 00000000, das ist in UTF-8 meines Wissens notwendigerweise illegal, weil 1110xxxxx zwei Folgebytes nach sich zieht, die mit 10 beginnen müssen. Sprich: Wie kann man UTF-16 überhaupt als UTF-8 verarbeiten? Soweit ich es sehe gar nicht, also versteht es sich von selbst, dass der Parser abbrechen muss und einen Fatal Error zurückgeben muss.

    1. Was muss passieren wenn in der XML-Deklaration ein anderer Zeichensatz steht als im BOM/automatische Erkennung/HTTP-Header?

    Gute Frage, dazu finde ich auch keine ausdrückliche Aussage. Aber zum BOM:

    »In den (...) Fällen, [sinngemäß: in denen eine BOM für UCS-4, UTF-8 oder UTF-16 vorhanden ist], verlangt Abschnitt 4.3.3 (...), dass die Kodierungsdeklaration, falls vorhanden, gelesen wird und dass geprüft wird, dass der Kodierungsname mit der tatsächlichen Kodierung des Entity übereinstimmt.«

    Sprich: Wenn ein BOM gefunden wird, schaue nach einer Kodierungsdeklaration direkt dahinter. Überprüfe, ob die Kodierung, die das BOM anzeigt, mit der Kodierung, die die XML-Deklaration möglicherweise anzeigt, identisch ist. In Abschnitt 4.3.3 finde ich nun keine eindeutige Aussage: Wenn Sie nicht identisch sind, dann breche das Parsen ab. Dies halte ich aber für einzig sinnvoll, da das BOM den Ton angibt.

    Im Grunde reduzieren sich meine Fragen auf die Prioritätenreihenfolge der möglichen Zeichensatzkodierungen (HTTP/BOM/automatische Erkennung/XML-Deklaration/Meta-Tag) in Abhängigkeit zu HTML oder XML/XHTML, und die zu verwendende Zeichensatzkodierung wenn überhaupt keine Deklariert wurde.

    Ich sehe da ehrlich gesagt keine große Schwierigkeit, weil ich, sobald ein offensichtlicher Widerspruch festgestellt wird, sofort eine Fehlermeldung ausgeben würde. D.h. wenn z.B. der Content-Type eine Kodierung behauptet, die dem BOM widerspricht, liegt ein Fehler vor, wenngleich empfohlen wird, das BOM zu beachten. Oder wenn der Content-Type der Meta-Angabe widerspricht, dann ist der Server falsch konfiguriert, wenngleich feststeht, dass die Kodierungsangabe im der Content-Type ausschlaggebend ist.

    Mathias

    1. Hallo,

      Verzeihung übrigens, dass ich damals auf deine Mail nicht geantwortet hatte

      Kein Problem, bin eh noch nicht zum coden gekommen.

      Du kannst mir den aktuell gebrauchten Algorithmus aber gerne noch einmal zuschicken, falls dich meine Meinung noch interessiert.

      "Gebraucht" wird noch kein Algorithmus, es war nur ein Entwurf wie dieser mal arbeiten soll.
      Aber irgendwie komme ich nicht so richtig von der Stelle; um so tiefer ich mich in die Materie einarbeite, desto Widersprüchlicher, Unverständlicher und Sinnloser wird das ganze W3C-Sammelsurium.
      Da ich Validome nicht noch mal umcoden möchte, will ich es jetzt einmal richtig machen und dann Ruhe haben ;-))
      Deshalb muss ich erst mal feststellen was Vorschrift ist, was Empfehlungen sind und was man dem gesunden Menschenverstand überlässt; und dann den ganzen Plunder unter ein Dach zu bringen. Leider gibt es kaum Menschen die sich in der Materie halbwegs auskennen (Du bist da wohl ne Ausnahme ;-)), so das ich mir fast alles selber aneignen muss.
      Wenn ich mal alle Infos zusammenfasse komme ich zu diesem vorläufigen Ergebnis:
      Zunächst wird der HTTP-Header und der BOM ermittelt und anschließend wird versucht anhand des binären Musters von <?xml......> UTF-16 oder UTF-32 zu ermitteln und den Charset der XML-Deklaration festzustellen.
      Gibt es einen (oder mehrerer) Konflikt(e) zwischen BOM/auto/XML, gibt's einen Fatal Error.
      Ein Konflikt zwischen HTTP-Header und BOM/auto/XML (welche in sich nun Konfliktfrei sind) erzeugt nur eine Warnung, da in der Praxis wohl häufig anzutreffen ist.
      Sollte keiner dieser Angaben vorhanden sein, kann jedoch noch kein Fehler erzeugt werden (fehlende Zeichensatzkodierung), da es sich um ein HTML-Dokument mit Meta-Tag handeln könnte.
      Um das Meta-Tag überhaupt finden zu können, bräuchte ich aber den benutzten Zeichensatz des Dokumentes. Das dürfte z.B. bei UTF-16 ohne BOM schwierig werden (bei X[HT]ML ist dies anhand des Musters für <?xml....> einfach).
      Hier könnt man z.B. nach dem Muster von <html und <body suchen (einer von beiden muss vorhanden sein). Sollte auch diese Suche fruchtlos sein gibt's ne Fehlermeldung das keine Zeichensatzangabe gefunden wurde.
      Wurde ein Muster gefunden, wird zunächst nach der Dokumententypdeklaration gesucht (natürlich auch wenn der Zeichensatz zuvor ermittelt werden konnte) um festzustellen ob es sich um ein HTML oder XHTML-Dokument handelt.
      Bei HTML wird nun nach dem Meta-Tag gesucht. Einen Fatal Error gibt es bei Konflikten zwischen Meta und BOM/auto oder wenn zuvor eine XML-Deklaration gefunden wurde.
      Ein Konflikt zwischen Meta und HTTP-Header ergibt dagegen nur eine Warnung.
      Die Prioritätenreihenfolge der Zeichensatzangaben währen bei HTML wie folgt:
      1. HTTP-Header
      2. BOM/auto
      3. Automatische Erkennung anhand von <html und <body
      4. Meta-Tag
      Weiterhin wird prinzipiell eine Warnung (Hinweis?) ausgegeben wenn die Zeichensatzkodierung nur anhand des HTTP-Headers oder der Suche nach <html und <body ermittelt werden konnte.

      Bei XML und XHTML:
      1. HTTP-Header
      2. BOM/auto/XML

      Einen Fallback gibt es prinzipiell nicht.
      Was meinst Du, könnte man den Algorithmus so bauen?
      Ein Flussdiagramm werde ich jetzt noch anlegen, wenn Du möchtest schicke ich es Dir gerne zu.

      Grüße
      Thomas