Zip und UTF-8-Erkennung

German support forum

Moderators: Hacker, Stefan2, white

Post Reply
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Zip und UTF-8-Erkennung

Post by *milo1012 »

Ich habe mal wieder ein Unicode-Problem gefunden, diesmal betrifft es aber Zip-Archive.
Ich weiß dass Unicode und Zip eigentlich keine Freunde sind, schlicht weil Winzip und Co. jeweils andere Erweiterungen zur Unicode-Fähigkeit benutzen.

Jedenfalls dachte ich dass TC mit UTF-8-Dateinamen in Zip klarkommt, tut er aber mit Archiven die mir Dropbox beim Download im Browser anbietet nicht.
Hier ein Beispielarchiv:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="test.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.zip"

UEsDBBQACAAIAGla1UQAAAAAAgAAAAAAAAALAAAAMjEgMDYgMjAxNC8DAFBLBwgAAAAAAgAAAAAA
AABQSwMEFAAIAAgATFrVRAAAAAACAAAAAAAAACwAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL0bD
vHJzdCBSZWdpc3RyaWVydW5nLwMAUEsHCAAAAAACAAAAAAAAAFBLAwQUAAgACAC9YNVEAAAAAAIA
AAAAAAAAIgAAADIxIDA2IDIwMTQvU2NyZWVuc2hvdHMvRXJuw6RocnVuZy8DAFBLBwgAAAAAAgAA
AAAAAABQSwMEFAAIAAgAZVrVRAAAAAACAAAAAAAAABcAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3Rz
LwMAUEsHCAAAAAACAAAAAAAAAFBLAQIUAxQACAAIAGla1UQAAAAAAgAAAAAAAAALAAAAAAAAAAAA
EADkAQAAAAAyMSAwNiAyMDE0L1BLAQIUAxQACAAIAExa1UQAAAAAAgAAAAAAAAAsAAAAAAAAAAAA
EADkATsAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL0bDvHJzdCBSZWdpc3RyaWVydW5nL1BLAQIU
AxQACAAIAL1g1UQAAAAAAgAAAAAAAAAiAAAAAAAAAAAAEADkAZcAAAAyMSAwNiAyMDE0L1NjcmVl
bnNob3RzL0VybsOkaHJ1bmcvUEsBAhQDFAAIAAgAZVrVRAAAAAACAAAAAAAAABcAAAAAAAAAAAAQ
AOQB6QAAADIxIDA2IDIwMTQvU2NyZWVuc2hvdHMvUEsFBgAAAAAEAAQAKAEAADABAAAAAA==
Die Verzeichnisse enthalten Umlaute die definitiv in UTF-8-Format abgespeichert sind (kann man mit jedem Hex-Editor sehen).
Andere nicht-ASCII-Zeichen werden genau so codiert.

WinRAR 4.x und 5 kommen problemlos damit klar und erkennen Unicode, 7-Zip in der neuesten Version aber zu meinem Erstaunen genau wie TC nicht!
Deswegen auch nicht als Bug-Report sondern erst einmal zum Verständnis zur Diskussion gestellt.

Erklärung: Die Dateien wurden von der Gegenseite mit Mac OS X hochgeladen. Ich habe keine Dropbox-Software installiert, möchte ich auch nicht.
Jedenfalls wird das Zip-Verzeichnis was mir Dropbox im Browser zum Download anbietet genau so codiert.
Ich vermute das es auch mit der Zip-Signatur zu tun hat. Besagtes Verzeichnis ist im Unix-Format, vermutlich wegen besagtem Mac auf der Gegenseite.
Sobald ich selbst im Browser Verzeichnisse mit Umlauten und sonstigen Sonderzeichen erstelle wird ein DOS-Zip-Format erstellt und alle Dateinamen bleiben stur in ANSI.
User avatar
Horst.Epp
Power Member
Power Member
Posts: 6983
Joined: 2003-02-06, 17:36 UTC
Location: Germany

Post by *Horst.Epp »

7-zip in der Version 9.32 Alpha kommt damit sehr wohl klar.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50567
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Das ist keine gültige ZIP-Datei: Der header enthält zwar Namen inUTF-8, aber bit 11 des "bit_flag" ist nicht auf 1 gesetzt (was UTF-8 bedeutet). Ich kann nur vermuten, dass die anderen Entpacker einfach "raten", dass dies UTF-8 sein soll, weil alle Zeichen sich als UTF-8 decodieren lassen.
Author of Total Commander
https://www.ghisler.com
User avatar
karlchen
Power Member
Power Member
Posts: 4605
Joined: 2003-02-06, 22:23 UTC
Location: Germany

Post by *karlchen »

Wenn man beim Einpacken die UTF-8 Kennung richtig mitgibt, dann klappt es auch mit dem Total Commander 8.51a. Will heißen, dann werden die Umlaute in den Namen beim Packen richtig kodiert und beim Auspacken wieder richtig dekodiert.

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="TEST2.ZIP"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="TEST2.ZIP"

UEsDBBQAAggAAGla1UQAAAAAAAAAAAAAAAALAAAAMjEgMDYgMjAxNC9QSwMEFAACCAAAG2DXRAAA
AAAAAAAAAAAAABcAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL1BLAwQUAAIIAABMWtVEAAAAAAAA
AAAAAAAALAAAADIxIDA2IDIwMTQvU2NyZWVuc2hvdHMvRsO8cnN0IFJlZ2lzdHJpZXJ1bmcvUEsD
BBQAAggAAL1g1UQAAAAAAAAAAAAAAAAiAAAAMjEgMDYgMjAxNC9TY3JlZW5zaG90cy9Fcm7DpGhy
dW5nL1BLAQIUCxQAAggAAGla1UQAAAAAAAAAAAAAAAALAAAAAAAAAAAAEAAAAAAAAAAyMSAwNiAy
MDE0L1BLAQIUCxQAAggAABtg10QAAAAAAAAAAAAAAAAXAAAAAAAAAAAAEAAAACkAAAAyMSAwNiAy
MDE0L1NjcmVlbnNob3RzL1BLAQIUCxQAAggAAExa1UQAAAAAAAAAAAAAAAAsAAAAAAAAAAAAEAAA
AF4AAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL0bDvHJzdCBSZWdpc3RyaWVydW5nL1BLAQIUCxQA
AggAAL1g1UQAAAAAAAAAAAAAAAAiAAAAAAAAAAAAEAAAAKgAAAAyMSAwNiAyMDE0L1NjcmVlbnNo
b3RzL0VybsOkaHJ1bmcvUEsFBgAAAAAEAAQAKAEAAOgAAAAAAA==
Welches Programm hat denn da nun Recht? Und warum? Und wer bestimmt, wann welche Spielregeln wie verändert werden und dass die anderen sich gefälligst danach zu richten haben?

--
Hinweis:
Der Ubuntu FileRoller 3.4.1 (Archivverwaltung, benutzt intern p7zip 9.20.1) kommt mit der 2. Fassung zurecht, mit der 1. ebenfalls nicht.
--
Nachtrag:
Wenn man mit dem oben genannten Fileroller die gleiche ZIP Datei erzeugt, dann kommt man zu diesem Ergebnis:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="test3.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test3.zip"

UEsDBBQDAAAAAItk10QAAAAAAAAAAAAAAAALAAAAMjEgMDYgMjAxNC9QSwMEFAMAAAAAG2DXRAAA
AAAAAAAAAAAAABcAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL1BLAwQUAwAIAAC9YNVEAAAAAAAA
AAAAAAAAIgAAADIxIDA2IDIwMTQvU2NyZWVuc2hvdHMvRXJuw6RocnVuZy9QSwMEFAMACAAATFrV
RAAAAAAAAAAAAAAAACwAAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL0bDvHJzdCBSZWdpc3RyaWVy
dW5nL1BLAQI/AxQDAAAAAItk10QAAAAAAAAAAAAAAAALAAAAAAAAAAAAEIDtQQAAAAAyMSAwNiAy
MDE0L1BLAQI/AxQDAAAAABtg10QAAAAAAAAAAAAAAAAXAAAAAAAAAAAAEIDtQSkAAAAyMSAwNiAy
MDE0L1NjcmVlbnNob3RzL1BLAQI/AxQDAAgAAL1g1UQAAAAAAAAAAAAAAAAiAAAAAAAAAAAAEIDt
QV4AAAAyMSAwNiAyMDE0L1NjcmVlbnNob3RzL0VybsOkaHJ1bmcvUEsBAj8DFAMACAAATFrVRAAA
AAAAAAAAAAAAACwAAAAAAAAAAAAQgO1BngAAADIxIDA2IDIwMTQvU2NyZWVuc2hvdHMvRsO8cnN0
IFJlZ2lzdHJpZXJ1bmcvUEsFBgAAAAAEAAQAKAEAAOgAAAAAAA==
Auch die packt der Total Commander 8.51a korrekt aus und stolpert nicht über die Umlaute.
MX Linux 21.3 64-bit xfce, Total Commander 11.50 64-bit
The people of Alderaan keep on bravely fighting back the clone warriors sent out by the unscrupulous Sith Lord Palpatine.
The Prophet's Song
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

Horst.Epp wrote:7-zip in der Version 9.32 Alpha kommt damit sehr wohl klar.
Mit der neuesten Version meine ich die offizielle 9.20er.
Alpha-, Beta- und sonstige Testversionen zählen bei mir nicht.
9.20 ist auch weiterhin die Erste die auf der offz. Download-Seite angeboten wird.
Kein Grund zu schreien ;)
ghisler(Author) wrote:Das ist keine gültige ZIP-Datei...
Das sollte den Verantwortlichen bei Dropbox gesagt werden.
Aber für mein Verständnis ist die Datei gültig, da CRC und Verzeichnisstruktur in Ordnung sind.
karlchen wrote:Welches Programm hat denn da nun Recht? Und warum? Und wer bestimmt, wann welche Spielregeln wie verändert werden und dass die anderen sich gefälligst danach zu richten haben?
Keiner und irgendwie doch alle.
Auch wenn PKWARE einen vermeintlichen "Standard" festlegt kommen Programme wie WinZip gerne mal mit Nicht-Standard-Methoden daher,
weswegen das Zip-Format IMO sowieso ein Ausläufer ist wenn es ums Archivieren geht. Das reinste Flickwerk eines Uralt-Formats.
RAR z.B. unterstützt mittlerweile so gut wie alles was das Dateisystem hergibt, 7z ist auch um Längen moderner.
Nur leider bietet mir Dropbox eben nur Zip zum Download an.

Ich würde ja gerne den Quellcode der neuen 7-Zip-Alpha-Version anschauen um zu sehen was sie verändert haben um es jetzt zu unterstützen, nur leider ist dieser nicht freigegeben.

Unabhängig davon wäre es natürlich begrüßenswert wenn TC die Dateinamen auf Unicode-Gültigkeit prüft
wenn die Bytes 0x7F überschreiten und unabhängig von den Archiv-Flags UTF-8 dann trotzdem korrekt dekodiert.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50567
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Das Problem dabei ist, dass es dann bei 2-Byte-Sprachen wie Chinesisch, Japanisch etc. zu vielen Fehlerkennungen kommen kann, weil diese auch Codes brauchen, die es als UTF-8 gibt. Es wäre also ein sehr unschöner "Hack".
Author of Total Commander
https://www.ghisler.com
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

ghisler(Author) wrote:Das Problem dabei ist, dass es dann bei 2-Byte-Sprachen wie Chinesisch, Japanisch etc. zu vielen Fehlerkennungen kommen kann
Ich verstehe die Bedenken, aber die Wahrscheinlichkeit für Fehlerkennungen ist nur bei einem einzigen Zeichen relevant.
Sobald an mehr als einer Stelle Bytes > 0x7F irgendwo in einem Dateinamen vorkommt tendiert die Wahrscheinlichkeit zunehmend gegen Null,
schlicht weil UTF-8 nach einem festen Schema arbeitet, welches in diesem Fall bestimmte (die meisten!) Byte-Kombinationen ausschließt.

Fast jeder moderne Parser, incl. der Scintilla-basierten Editoren macht das so, und meiner Erfahrung nach recht zuverlässig.
In meinem Plugins mache ich das ebenfalls so, und selbst kleinste Dateien im z.B. Big-5-DBCS werden korrekt als ANSI erkannt.
Das jetzt schon vorhandene CBC-Tool im TC muss es ja auch schon in ähnlicher Weise machen, auch wenn ich die Zuverlässigkeit noch nicht im Detail geprüft habe.

Man könnte das Ganze bei verbleibenden Restbedenken immer noch als optionale Erkennung einbauen und standardmäßig ausschalten.
Dann wäre es auch kein Hack, sondern eine "Maßnahme" wegen solcher vermeintlichen Nicht-Standard-Dateien.
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

Da jetzt endlich mal die aktuelle 7-Zip-Source zur Verfügung steht, möchte ich das Thema wieder aufwärmen.
Scheint so als wenn 7-Zip wirklich blind UTF-8 versucht wenn Unix als Host-OS im Header steht:

\CPP\7zip\Archive\Zip\ZipItem.h:

Code: Select all

bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; }

...

  void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const
  {
    bool isUtf8 = IsUtf8();

    #ifdef _WIN32
    if (!isUtf8)
    {
      if (useSpecifiedCodePage)
        isUtf8 = (codePage == CP_UTF8);
      else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
      {
        /* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
           We try to get name as UTF-8.
          Do we need to do it in POSIX version also? */
        isUtf8 = true;
      }
    }
    #endif

    if (isUtf8)
      if (ConvertUTF8ToUnicode(s, res))
        return;
    MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
  }
Definitiv ein Unterschied zur alten 9.20er, dort wird noch strikt nach dem Bit-Flag verfahren:

Code: Select all

  UString GetUnicodeString(const AString &s) const
  {
    UString res;
    if (IsUtf8())
      if (!ConvertUTF8ToUnicode(s, res))
        res.Empty();
    if (res.IsEmpty())
      res = MultiByteToUnicodeString(s, GetCodePage());
    return res;
  }
TC plugins: PCREsearch and RegXtract
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50567
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Hmm, nicht schön. Ich habe es inzwischen anders gelöst: TC testet, ob der String nur korrekte UTF8-Sequenzen enthält. Falls ja, wird es als UTF-8 interpretiert.
Author of Total Commander
https://www.ghisler.com
Post Reply