Chrome versus PDF & Latin2?

Próbáld már valaki megnyitni Chrome-al latin 2 fileneves PDF-et? Belefutottunk egy hibába, ami úgy tűnik a Chrome tökségére vezethető vissza... amennyiben latin2-es a file név, a chrome nem hajlandó megjeleníteni a PDF-et, csak egy szürke képernyőt kapunk. Ugyenez a file UTF8 filenév enkódolással megjelenik.

Hozzászólások

firefox desktopon megnyitja (beepitett pdf olvasoja)
firefox for android letolti, de mar az androidba (cyanogenmod 12) beepitett pdf olvasó megnyitni nem tudja.

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Röviden: miért akarna 2015-ben bárki is nem UTF-8-at használni?

Bővebben: Amikor megnyitja a latin2 fájlneves pdf-et, ezt a hibát dobja:


pdf.js:133 Uncaught (in promise) URIError: URI malformed
at decodeURIComponent (native)
at Object.PDFViewer (chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf.js:133:20)
at initViewer (chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/main.js:37:14)

Megnézve, hogy mi van a pdf.js-ben az említett helyen:


document.title = decodeURIComponent(getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl));

Ez pedig szabvány szerint:

The decodeURIComponent function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURIComponent function is replaced with the UTF-16 encoding of the code points that it represents.

Magyarán azért nem működik Chrome-ban a dolog, mert be akarná állítani fájlnevet az lap címének, de mivel az nem UTF-8-ban van kódolva, ezért hibával leáll.

tl;dr: használj UTF-8-at.

URI-t viszont encode-olni KELL a szabványok szerint, mondjuk percent-encoding a minimum. Az URL-ben nem lehet csak úgy Latin-2 karakter.
És bizony azt a karaktert, amit nem lehet URL-ben módosítás nélkül szerepeltetni, UTF-8-ban kell reprezentálni, majd az eredményt percent-encodeolni. Lásd RFC3986. 10 éve ez a szabvány. A Chrome nem tehet arról, hogy leszarod a szabványt.
"When a new URI scheme defines a component that represents textual
data consisting of characters from the Universal Character Set [UCS],
the data should first be encoded as octets according to the UTF-8
character encoding [STD63]; then only those octets that do not
correspond to characters in the unreserved set should be percent-
encoded."

Akkor a nagytiszteletű webszerver fejlesztői oldják meg - ott egyszerűbb, mint egy doksitárban mondjuk 123456 könyvtárban 23456789123 darab doksit átnevezni. Itt ugyanis a webszerver kap egy könyvtárat, amiben fájlok vannak, és odatolja a path egy részét útvonalként meg a fájl nevét úgy, ahogy van.

" és odatolja a path egy részét útvonalként meg a fájl nevét úgy, ahogy van."
Nem, ez egy nem jól működő webszerver.

A webszervernek úgy kell kiszolgálnia a dolgokat, hogy az URL helyes kódolású legyen: UTF-8 + percent-encoding.
Az, hogy a file neve micsoda a filerendszere, totál lényegtelen. A weben az URL az, amivel erőforrásokat azonosítunk. És az URL formájára és kódolására van előírás.

Amikor visszakövettem a hibát, próbáltam rá workaround-ot is keresni, sikertelenül. Egy .htaccess fájlba ugyanis meg lehet adni, hogy milyen kódolással listázza ki a könyvtárat az Apache, ezt latin2-re állítva jól szerepelt a fájlnév. Letölteni azonban már nem lehetett, access denied miatt. Itt feladtam.

23456789123 darab fájlnevet konkrétan egyetlen paranccsal át tudok konvertálni UTF-8-ra: convmv -r -f ISO-8859-2 -t UTF-8 /utvonal/a/konyvtarhoz

Alapvetően igazad van abban, hogy jó lenne mindenhol UTF-8-at használni már.

Viszont: van olyan weboldal, a kérdéses is, ahol már egy jó ideje latin 2 minden. Ha az ügyfél nem akarja az UTF-8-ra átállás költségét kifizetni, mert miért akarná, akkor marad is úgy. Technikai problémát, hátrányt nem okoz, kivétel ha egy böngésző fos. Mint jelen esetben.

A böngésző szabványkövető. Az ügyfélnek meg meg lehet mondani, hogy weboldala nem szabványos. Lásd kommentemet fentebb: az URI-nak UTF-8 és percent-encoding kell, már 10 éve. Én örülök, hogy a Chrome, mivel 2008-as browser, szart a legacy dolgokra. Latin-2-es URL sosem volt szabvány amúgysem. Percent-encoding kellene akkor is, csak a sok gyökér balfasz webfejlesztő miatt sok browser túl engedékeny.

A fenti oldal valóban UTF-8 kódolással jön le (Content-Type:text/html;charset=UTF-8), azaz a böngészőnek UTF-8-ként kellene értelmeznie, azonban a bytesorozat, amit tartalmaz, az nem UTF-8.
Maga az URL az percent-encoded, a link content azonban nem, és nem UTF-8.

Ezeket a byte-okat tartalmazza a file neve (a href-ben percent encode-olva): 0xE9 0xE1 0xF5 0xFA stb.
Nos, ezek így nem valid UTF-8 karakterek, így az egész URL valójában invalid.

Egy UTF-8 decoderen átfuttatva a 0xE9 0xE1 0xF5 0xFA karaktersorozatot:

Byte number 1 is decimal 233, hex 0xE9, octal \351, binary 11101001
This is the first byte of a 3 byte sequence.

Byte number 2 is decimal 225, hex 0xE1, octal \341, binary 11100001
Previous UTF-8 multibyte sequence incomplete, earlier bytes dropped.
This is the first byte of a 3 byte sequence.

Byte number 3 is decimal 245, hex 0xF5, octal \365, binary 11110101
Previous UTF-8 multibyte sequence incomplete, earlier bytes dropped.
This is the first byte of a 4 byte sequence.

Byte number 4 is decimal 250, hex 0xFA, octal \372, binary 11111010
Previous UTF-8 multibyte sequence incomplete, earlier bytes dropped.
This is the first byte of a 5 byte sequence.
End of file during multibyte sequence, some bytes dropped

Szépen látszik, hogy ez egy totálisan invalid bytesorozat, amit nem lehet UTF-8-ként értelmezni.

Nem véletlen, hogy a Chrome 6 darab "Unicode replacement mark" karaktert (Unicode U+FFFD karakter) jelenít meg. Nem tudja értelmezni (helyesen), hogy mit akar az a bytesorozat ott jelenteni. Invalid UTF-8.

Update: ha elmentem a file-t wget-tel, akkor letöltődik, de a Gnome alatt invalid encodingot jelez a file nevének, 6 db replacement mark karakterrel. És igen, a GLib UTF-8-ként értelmezi a fileneveket.
Itt bizony el van rontva a filenév encoding-od.
Ugyanis nem minden karaktersorozat Latin2-es bytesorozata értelmezhető UTF-8 bytesorozatként. A hiba igazából nem a Chrome-ban van, csak a többi browser a fejlesztő trehányságát megpróbálja orvosolni.

Ha nem lehet utf-8 karaktersorozatként értelmezni, akkor tessen má' megpróbálni 8 bites karakterként, ugyanis attól, hogy a gugli azt hiszi, ők sz@rják az internetet, még ez nincs így, és bizony vannak korábbi szabványoknak megfelelő tartalmak, amik nem igazán lesznek recode-dal átrágva (tartalom és fájlnév egyaránt!), még a naccságos gugli kedvéért sem. Ez van...

Nana. Ha keresztbeszarjuk a szabványokat, az rossz dolog. HA egyszer a weboldal azt mondja magáról, hogy UTF-8, akkor legyen a tartalma UTF-8.
Az URL encode-olásnak meg eleve annak KELL lennie: UTF-8 + percent-encoding.
A tartalmak, ha jó Content-type headerrel jelennek meg, a Chrome helyesen fogja megjeleníteni. Azért akar UTF-8-at értelmezni, mert a weboldal azt mondja magáról, hogy UTF-8. Miért kéne a Chrome-nak heurisztikákat alkalmazni csak azért, mert a fejlesztő balfasz?
A legacy tartalommal semmi gond nincs: A Content-Type megfelelő beállítása után jól fog értelmeződni.
Itt a gond abból adódik, hogy UTF-8-as Content-Type mellett a tartalom nem értelmezhető. A fejlesztő balfaszsága és trehánysága miatt nem a Chrome tehető felelőssé.

Olyan ez, mintha azt mondanád, hogy egy tartalmad application/xml, miközben valójában application/pdf. Aztán csodálkozol, hogy az XML parser nem eszi meg.

A webszervered azt mondja a Content-type headerben, hogy a tartalom, amit a böngésző kapni fog, az HTML, és UTF-8 kódolással kell értelmezni a tartalmát:
Content-Type:text/html;charset=UTF-8

Miközben a tartalom az nem értelmezhető UTF-8-ként, pont a kérdéses rész bytesorozata invalid UTF-8 bytesorozat.

Lehetne ez Content-Type:text/html;charset=iso-8859-2 is, de akkor sem lenne jó a file URL-je, mert invalid UTF-8 bytesorozat van benne percent-encode-olva.

Lásd a szabványt: https://tools.ietf.org/html/rfc2046#page-7
Ez leírja, hogy a Text MIME-típusnak hogyan lehet megadni a charset paramétert, és a default az US-ASCII.
Mondjuk az eléggé zavaró, hogy keverik a karakterkészlet és karakterkódolás fogalmakat ebben a szabványban (meg sok máshol), hiszen UTF-8 esetén a karakterkészlet az Unicode, a karakterkódolás az UTF-8. Bár eleve sokszor baj, hogy sokan nem tudják, mi a különbség karakterkészlet és karakterkódolás között.

Nomostan ha a directory megnyitásakor a fájlnevet szépen latin2-ben kapja meg a webszerver (mert olyan bájtsorozat van a fájlnév helyén), akkor abból neki kell röptében utf-8 nevet alkotni, ha pl. autoindex-szel odatolja a kliensnek a könyvtárlistát: a href= után utf-8 kell ugyanis.

Lehet latin 2 az oldal/adatbázis, de a fájlnevek legyenek UTF-8-ban, hogy ne okozzanak ilyen problémát.

Az ügyfél nem akar fizetni a javításért meg összetett téma. Ha az ügyfélnek is vannak ügyfelei, akkor nem zavarja az a tény, hogy MO-on a Chrome a legelterjedtebb böngésző? Ha emiatt piacot veszít, akkor lehet mégiscsak megérné a fejlesztés.