Re: email character decoding

From: Date: Thu, 26 Nov 2020 02:59:51 +0000
Subject: Re: email character decoding
References: 1 2 3 4 5 6 7 8 9 10 11  Groups: php.general 
Request: Send a blank email to php-general+get-327376@lists.php.net to get a copy of this message
FYI : if you want a nicer formatted version of this code that i've put together based on about a full day's worth of Googling, look no further than my https://github.com/nicerapp/nicerapp/tree/master/nicerapp/businessLogic/webmail/ with for now only functions.php fully LGPL opensourced (free for commercial use). i am seriously considering opensourcing (LGPL) the rest of the webmail module as well, with theme support, POP support (fortunately i got iRedMail installed on my https://nicer.app to test that with), and outgoing SMTP support. web coding is not the only job i do however, so putting the rest of it together is going to take me about 2 weeks to 2 months or so. follow the github releases for more information. this is the final post in this thread that *i* make for now, but feel free to put in suggestions and feature requests, while there is still time to do that. On Sun, Nov 22, 2020 at 1:15 PM Rene Veerman < rene.veerman.netherlands@gmail.com> wrote: > found another special case in my inbox.. a CR *or* LF for line endings. > > the following code will handle that case properly : > > function getPart($connection, $messageNumber, $partNumber, $encoding) { > setlocale(LC_CTYPE, 'nl_NL.utf8'); > $header = imap_fetchheader($connection, $messageNumber); > //return $header; > $data = imap_fetchbody($connection, $messageNumber, $partNumber); > if ($data == '') return $data; > //return $encoding; > switch($encoding) { > case 0: > //if (mb_detect_encoding($data, 'UTF-8', true)==='UTF-8') { > $d = quoted_printable_decode($data); > //return $d; > if ( > strpos($d, '<body')!==false > || strpos($d, '<table')!==false > ) { > $d = str_replace ("\r\n", "", $d); > $d = str_replace ("\r", "", $d); > $d = str_replace ("\n", "", $d); > } > > //return $d; > $f = fopen ('temp/data.bin', 'w'); > if ($f!==false) { > fwrite ($f, $d); > fclose ($f); > $xec = 'chardet > "'.dirname(__FILE__).'/temp/data.bin"'; > exec ($xec, $output, $result); > preg_match_all('/: (.*) with/',$output[0],$chardet); > //return json_encode($output); > $chardetResult = $chardet[1][0]; > if ($chardetResult=='utf-8') return $d; > $xec = 'iconv -f '.$chardetResult.' -t UTF-8 > "'.dirname(__FILE__).'/temp/data.bin" > > "'.dirname(__FILE__).'/temp/data.out"'; > exec ($xec, $output, $result); > return > file_get_contents(dirname(__FILE__).'/temp/data.out'); > } else { > echo 'Could not open temp/data.bin for detection and > conversion of character set encoding :(<br/>Please check directory > permissions on "'.dirname(__FILE__).'/temp"'; > }; > /* > } else { > return $data; // 7BIT > }*/ > case 1: return imap_8bit($data); // 8BIT > case 2: return $data; // BINARY > case 3: return imap_base64($data); // BASE64 > case 4: > if ( is_base64($data)){ > $d = base64_decode($data); > return $d; > } else { > return quoted_printable_decode($data); > }; > break; > case 5: return $data; // OTHER > } > } > > On Sun, Nov 22, 2020 at 9:50 AM Rene Veerman < > rene.veerman.netherlands@gmail.com> wrote: > >> found another special case; malformed HTML (CRLF *inside* html tags).. >> >> the following update to getPart() fixes it : >> >> function getPart($connection, $messageNumber, $partNumber, $encoding) { >> setlocale(LC_CTYPE, 'nl_NL.utf8'); >> $header = imap_fetchheader($connection, $messageNumber); >> //return $header; >> $data = imap_fetchbody($connection, $messageNumber, $partNumber); >> if ($data == '') return $data; >> //return $encoding; >> switch($encoding) { >> case 0: >> //if (mb_detect_encoding($data, 'UTF-8', true)==='UTF-8') { >> $d = quoted_printable_decode($data); >> if ( >> strpos($d, '<body')!==false >> || strpos($d, '<table')!==false >> ) $d = str_replace ("\r\n", "", $d); >> //return $d; >> $f = fopen ('temp/data.bin', 'w'); >> if ($f!==false) { >> fwrite ($f, $d); >> fclose ($f); >> $xec = 'chardet >> "'.dirname(__FILE__).'/temp/data.bin"'; >> exec ($xec, $output, $result); >> preg_match_all('/: (.*) with/',$output[0],$chardet); >> //return json_encode($output); >> $chardetResult = $chardet[1][0]; >> if ($chardetResult=='utf-8') return $d; >> $xec = 'iconv -f '.$chardetResult.' -t UTF-8 >> "'.dirname(__FILE__).'/temp/data.bin" > >> "'.dirname(__FILE__).'/temp/data.out"'; >> exec ($xec, $output, $result); >> return >> file_get_contents(dirname(__FILE__).'/temp/data.out'); >> } else { >> echo 'Could not open temp/data.bin for detection and >> conversion of character set encoding :(<br/>Please check directory >> permissions on "'.dirname(__FILE__).'/temp"'; >> }; >> /* >> } else { >> return $data; // 7BIT >> }*/ >> case 1: return imap_8bit($data); // 8BIT >> case 2: return $data; // BINARY >> case 3: return imap_base64($data); // BASE64 >> case 4: >> if ( is_base64($data)){ >> $d = base64_decode($data); >> return $d; >> } else { >> return quoted_printable_decode($data); >> }; >> break; >> case 5: return $data; // OTHER >> } >> } >> >> On Sun, Nov 22, 2020 at 8:45 AM Rene Veerman < >> rene.veerman.netherlands@gmail.com> wrote: >> >>> oh, i forgot to mention... and before i close the browser tabs to it.. i >>> found some really good explanations of what encodings actually are, and how >>> they got so complicated over time.. >>> >>> >>> >>> https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ >>> >>> https://kunststube.net/encoding/ >>> >>> https://kunststube.net/frontback/ >>> >>> On Sun, Nov 22, 2020 at 8:24 AM Rene Veerman < >>> rene.veerman.netherlands@gmail.com> wrote: >>> >>>> ok.. because it was googling and reading up on open source documents >>>> describing encodings and how to deal with them in general that led me to >>>> this solution, i thought it would be nice for me to share my code on how to >>>> parse email data.. >>>> this includes the complete fix for the problem which started this >>>> thread, in getPart(), switch($encoding) case 0: >>>> >>>> i'll let you all know if i run into any more special cases, and the >>>> (eventual) solutions to those.. >>>> this code will be part of my >>>> https://github.com/nicerapp/nicerapp >>>> opensource CMS, which is available to the public for 10% of the profits you >>>> make with it. >>>> >>>> i'll consider making the webmail part of it LGPL (true >>>> opensource available for commercial use without cost). >>>> >>>> bye for now, and thanks for being the mirror i needed to get this >>>> solved :) >>>> >>>> function webmail_get_mail_content ($serverConfig, $serverIdx, >>>> $mailboxes, $mailboxIdx, $mailIdx) { >>>> $c = $serverConfig; >>>> $connectString = >>>> >>>> '{'.$c['IMAP']['domain'].':'.$c['IMAP']['port'] >>>> >>>> .($c['IMAP']['requiresSSL']?'/imap/ssl':'') >>>> >>>> .($c['IMAP']['sslCertificateCheck']?'':'/novalidate-cert') >>>> .'}'.$mailboxes[$mailboxIdx]; >>>> $mbox = imap_open($connectString, $c['userID'], >>>> $c['userPassword']); >>>> if ($mbox===false) return 'FAIL - '.$connectString; >>>> >>>> /* >>>> $section = 2; >>>> $text = trim( utf8_encode( quoted_printable_decode( >>>> imap_fetchbody( $mbox, $mailIdx, $section ) ) ) >>>> ); >>>> $headers = imap_fetchheader($mbox, $mailIdx, >>>> */ >>>> $structure = imap_fetchstructure($mbox, 1); >>>> $flattenedParts = flattenParts($structure->parts); >>>> //return json_encode($flattenedParts, JSON_PRETTY_PRINT); >>>> foreach($flattenedParts as $partNumber => $part) { >>>> >>>> switch($part->type) { >>>> >>>> case 0: >>>> // the HTML or plain text part of the email >>>> $message = getPart($mbox, $mailIdx, $partNumber, >>>> $part->encoding); >>>> if ($message!=='') { >>>> if ($partNumber==1) { >>>> $msg = $message; >>>> $msg = >>>> str_replace("\r\n",'<br/>',$msg); >>>> $msg = >>>> str_replace("\r",'<br/>',$msg); >>>> $msg = >>>> str_replace("\n",'<br/>',$msg); >>>> } else { >>>> $msg = $message; >>>> } >>>> }; >>>> // now do something with the message, e.g. render it >>>> break; >>>> >>>> case 1: >>>> // multi-part headers, can ignore >>>> >>>> break; >>>> case 2: >>>> // attached message headers, can ignore >>>> break; >>>> >>>> case 3: // application >>>> case 4: // audio >>>> case 5: // image >>>> case 6: // video >>>> case 7: // other >>>> $filename = getFilenameFromPart($part); >>>> if($filename) { >>>> // it's an attachment >>>> $attachment = getPart($mbox, $mailIdx, $partNumber, >>>> $part->encoding); >>>> // now do something with the attachment, e.g. save >>>> it somewhere >>>> } >>>> else { >>>> // don't know what it is >>>> } >>>> break; >>>> >>>> } >>>> >>>> } >>>> >>>> return $msg;//json_encode($flattenedParts); >>>> } >>>> >>>> function flattenParts($messageParts, $flattenedParts = array(), $prefix >>>> = '', $index = 1, $fullPrefix = true) { >>>> >>>> foreach($messageParts as $part) { >>>> $flattenedParts[$prefix.$index] = $part; >>>> if(isset($part->parts)) { >>>> if($part->type == 2) { >>>> $flattenedParts = flattenParts($part->parts, $flattenedParts, >>>> $prefix.$index.'.', 0, false); >>>> } >>>> elseif($fullPrefix) { >>>> $flattenedParts = flattenParts($part->parts, $flattenedParts, >>>> $prefix.$index.'.'); >>>> } >>>> else { >>>> $flattenedParts = flattenParts($part->parts, $flattenedParts, $prefix); >>>> } >>>> unset($flattenedParts[$prefix.$index]->parts); >>>> } >>>> $index++; >>>> } >>>> >>>> return $flattenedParts; >>>> >>>> } >>>> >>>> >>>> function getPart($connection, $messageNumber, $partNumber, $encoding) { >>>> setlocale(LC_CTYPE, 'nl_NL.utf8'); >>>> $header = imap_fetchheader($connection, $messageNumber); >>>> //return $header; >>>> $data = imap_fetchbody($connection, $messageNumber, $partNumber); >>>> //return $encoding; >>>> switch($encoding) { >>>> case 0: >>>> if (mb_detect_encoding($data, 'UTF-8', >>>> true)==='UTF-8') { >>>> //$data = mb_convert_encoding($data, 'UTF-8', >>>> 'CP1250, >>>> Windows-1251, Windows-1252, Windows-1254');//." : >>>> ".$chr."<br>"; >>>> //$data = mb_convert_encoding($data, 'HTML-ENTITIES', >>>> 'UTF-8'); >>>> >>>> $d = quoted_printable_decode($data); >>>> $f = fopen ('temp/data.bin', 'w'); >>>> if ($f!==false) { >>>> fwrite ($f, quoted_printable_decode($data)); >>>> fclose ($f); >>>> $xec = 'chardet >>>> "'.dirname(__FILE__).'/temp/data.bin"'; >>>> exec ($xec, $output, $result); >>>> preg_match_all('/: (.*) with/',$output[0],$chardet); >>>> $chardetResult = >>>> $chardet[1][0];//json_encode($chardet); >>>> $xec = 'iconv -f '.$chardetResult.' -t UTF-8 >>>> "'.dirname(__FILE__).'/temp/data.bin" > >>>> "'.dirname(__FILE__).'/temp/data.out"'; >>>> exec ($xec, $output, $result); >>>> return >>>> file_get_contents(dirname(__FILE__).'/temp/data.out'); >>>> } else { >>>> echo 'Could not open temp/data.bin for detection >>>> and conversion of character set encoding :(<br/>Please check directory >>>> permissions on "'.dirname(__FILE__).'/temp"'; >>>> }; >>>> } else { >>>> return $data; // 7BIT >>>> } >>>> case 1: return imap_8bit($data); // 8BIT >>>> case 2: return $data; // BINARY >>>> case 3: return imap_base64($data); // BASE64 >>>> case 4: >>>> if ( is_base64($data)){ >>>> $d = base64_decode($data); >>>> return $d; >>>> } else { >>>> return quoted_printable_decode($data); >>>> }; >>>> break; >>>> case 5: return $data; // OTHER >>>> } >>>> } >>>> >>>> function is_base64($s) { >>>> if (($b = base64_decode($s, TRUE)) === FALSE) { >>>> return FALSE; >>>> } >>>> >>>> // now check whether the decoded data could be actual text >>>> $e = mb_detect_encoding($b); >>>> if (in_array($e, array('UTF-8', 'ASCII'))) { // YMMV >>>> return TRUE; >>>> } else { >>>> return FALSE; >>>> } >>>> } >>>> >>>> function getFilenameFromPart($part) { >>>> $filename = ''; >>>> >>>> if($part->ifdparameters) { >>>> foreach($part->dparameters as $object) { >>>> if(strtolower($object->attribute) == 'filename') { >>>> $filename = $object->value; >>>> } >>>> } >>>> } >>>> >>>> if(!$filename && $part->ifparameters) { >>>> foreach($part->parameters as $object) { >>>> if(strtolower($object->attribute) == 'name') { >>>> $filename = $object->value; >>>> } >>>> } >>>> } >>>> >>>> return $filename; >>>> } >>>> >>>> On Sun, Nov 22, 2020 at 8:05 AM Rene Veerman < >>>> rene.veerman.netherlands@gmail.com> wrote: >>>> >>>>> YES YES YES.. found it!! :) >>>>> >>>>> chardet FTW! :D >>>>> >>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>> chardet enca.bin >>>>> enca.bin: Windows-1252 with confidence 0.725876260928 >>>>> >>>>> >>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>> iconv -f windows-1252 -t UTF-8 enca.bin > enca.out >>>>> >>>>> which also means that i should be able to convert this data in PHP : >>>>> $d = quoted_printable_decode($data); >>>>> $d = mb_convert_encoding($d, 'Windows-1252', >>>>> 'UTF-8'); >>>>> return $d; >>>>> but alas, THIS DOES NOT WORK. >>>>> it replaces the special central european characters in the data with >>>>> '?'. >>>>> >>>>> so you'll have to write out the data to disk and convert it using the >>>>> commandline PHP exec() to Ubuntu's commandline iconv command, then read >>>>> back in the data using file_get_contents. >>>>> >>>>> i'll start now on the actual PHP code to do this, and post that when >>>>> i'm done.. it'll require some minor parsing of the chardet output, >>>>> but >>>>> shouldn't take me longer than an hour, maybe 2. >>>>> >>>>> On Sun, Nov 22, 2020 at 7:57 AM Rene Veerman < >>>>> rene.veerman.netherlands@gmail.com> wrote: >>>>> >>>>>> ok i hit a little bit of a breakthrough.. but still not there.. >>>>>> >>>>>> when i write out the file from PHP like this : >>>>>> fwrite ($f, quoted_printable_decode($data)); >>>>>> and then use the command line like this : >>>>>> >>>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>>> file enca.bin >>>>>> i get : >>>>>> enca.bin: HTML document, ISO-8859 text, with very long lines, with >>>>>> CRLF, NEL line terminators >>>>>> >>>>>> btw, using enca doesn't work: >>>>>> >>>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>>> enca enca.bin >>>>>> enca: Cannot determine (or understand) your language preferences. >>>>>> Please use -L language', or -L >>>>>> none' if your language is not >>>>>> supported >>>>>> (only a few multibyte encodings can be recognized then). >>>>>> Run `enca --list languages' to get a list of supported languages. >>>>>> >>>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>>> enca -L none enca.bin >>>>>> Unrecognized encoding >>>>>> >>>>>> And, using the following command line still fails miserably : >>>>>> >>>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>>> iconv -f ISO-8859 -t UTF-8 enca.bin > enca.out >>>>>> iconv: conversion from `ISO-8859' is not supported >>>>>> >>>>>> iconv -l >>>>>> gives me : >>>>>> >>>>>> root@crow:/home/rene/data1/htdocs/localhost/nicerapp/businessLogic/webmail/temp# >>>>>> iconv -l >>>>>> The following list contains all the coded character sets known. This >>>>>> does >>>>>> not necessarily mean that all combinations of these names can be used >>>>>> for >>>>>> the FROM and TO command line parameters. One coded character set can >>>>>> be >>>>>> listed with several different names (aliases). >>>>>> >>>>>> 437, 500, 500V1, 850, 851, 852, 855, 856, 857, 858, 860, 861, 862, >>>>>> 863, 864, >>>>>> 865, 866, 866NAV, 869, 874, 904, 1026, 1046, 1047, 8859_1, 8859_2, >>>>>> 8859_3, >>>>>> 8859_4, 8859_5, 8859_6, 8859_7, 8859_8, 8859_9, 10646-1:1993, >>>>>> 10646-1:1993/UCS4, ANSI_X3.4-1968, ANSI_X3.4-1986, ANSI_X3.4, >>>>>> ANSI_X3.110-1983, ANSI_X3.110, ARABIC, ARABIC7, ARMSCII-8, >>>>>> ARMSCII8, ASCII, >>>>>> ASMO-708, ASMO_449, BALTIC, BIG-5, BIG-FIVE, BIG5-HKSCS, BIG5, >>>>>> BIG5HKSCS, >>>>>> BIGFIVE, BRF, BS_4730, CA, CN-BIG5, CN-GB, CN, CP-AR, CP-GR, CP-HU, >>>>>> CP037, >>>>>> CP038, CP273, CP274, CP275, CP278, CP280, CP281, CP282, CP284, >>>>>> CP285, CP290, >>>>>> CP297, CP367, CP420, CP423, CP424, CP437, CP500, CP737, CP770, >>>>>> CP771, CP772, >>>>>> CP773, CP774, CP775, CP803, CP813, CP819, CP850, CP851, CP852, >>>>>> CP855, CP856, >>>>>> CP857, CP858, CP860, CP861, CP862, CP863, CP864, CP865, CP866, >>>>>> CP866NAV, >>>>>> CP868, CP869, CP870, CP871, CP874, CP875, CP880, CP891, CP901, >>>>>> CP902, CP903, >>>>>> CP904, CP905, CP912, CP915, CP916, CP918, CP920, CP921, CP922, >>>>>> CP930, CP932, >>>>>> CP933, CP935, CP936, CP937, CP939, CP949, CP950, CP1004, CP1008, >>>>>> CP1025, >>>>>> CP1026, CP1046, CP1047, CP1070, CP1079, CP1081, CP1084, CP1089, >>>>>> CP1097, >>>>>> CP1112, CP1122, CP1123, CP1124, CP1125, CP1129, CP1130, CP1132, >>>>>> CP1133, >>>>>> CP1137, CP1140, CP1141, CP1142, CP1143, CP1144, CP1145, CP1146, >>>>>> CP1147, >>>>>> CP1148, CP1149, CP1153, CP1154, CP1155, CP1156, CP1157, CP1158, >>>>>> CP1160, >>>>>> CP1161, CP1162, CP1163, CP1164, CP1166, CP1167, CP1250, CP1251, >>>>>> CP1252, >>>>>> CP1253, CP1254, CP1255, CP1256, CP1257, CP1258, CP1282, CP1361, >>>>>> CP1364, >>>>>> CP1371, CP1388, CP1390, CP1399, CP4517, CP4899, CP4909, CP4971, >>>>>> CP5347, >>>>>> CP9030, CP9066, CP9448, CP10007, CP12712, CP16804, CPIBM861, >>>>>> CSA7-1, CSA7-2, >>>>>> CSASCII, CSA_T500-1983, CSA_T500, CSA_Z243.4-1985-1, >>>>>> CSA_Z243.4-1985-2, >>>>>> CSA_Z243.419851, CSA_Z243.419852, CSDECMCS, CSEBCDICATDE, >>>>>> CSEBCDICATDEA, >>>>>> CSEBCDICCAFR, CSEBCDICDKNO, CSEBCDICDKNOA, CSEBCDICES, CSEBCDICESA, >>>>>> CSEBCDICESS, CSEBCDICFISE, CSEBCDICFISEA, CSEBCDICFR, CSEBCDICIT, >>>>>> CSEBCDICPT, >>>>>> CSEBCDICUK, CSEBCDICUS, CSEUCKR, CSEUCPKDFMTJAPANESE, CSGB2312, >>>>>> CSHPROMAN8, >>>>>> CSIBM037, CSIBM038, CSIBM273, CSIBM274, CSIBM275, CSIBM277, >>>>>> CSIBM278, >>>>>> CSIBM280, CSIBM281, CSIBM284, CSIBM285, CSIBM290, CSIBM297, >>>>>> CSIBM420, >>>>>> CSIBM423, CSIBM424, CSIBM500, CSIBM803, CSIBM851, CSIBM855, >>>>>> CSIBM856, >>>>>> CSIBM857, CSIBM860, CSIBM863, CSIBM864, CSIBM865, CSIBM866, >>>>>> CSIBM868, >>>>>> CSIBM869, CSIBM870, CSIBM871, CSIBM880, CSIBM891, CSIBM901, >>>>>> CSIBM902, >>>>>> CSIBM903, CSIBM904, CSIBM905, CSIBM918, CSIBM921, CSIBM922, >>>>>> CSIBM930, >>>>>> CSIBM932, CSIBM933, CSIBM935, CSIBM937, CSIBM939, CSIBM943, >>>>>> CSIBM1008, >>>>>> CSIBM1025, CSIBM1026, CSIBM1097, CSIBM1112, CSIBM1122, CSIBM1123, >>>>>> CSIBM1124, >>>>>> CSIBM1129, CSIBM1130, CSIBM1132, CSIBM1133, CSIBM1137, CSIBM1140, >>>>>> CSIBM1141, >>>>>> CSIBM1142, CSIBM1143, CSIBM1144, CSIBM1145, CSIBM1146, CSIBM1147, >>>>>> CSIBM1148, >>>>>> CSIBM1149, CSIBM1153, CSIBM1154, CSIBM1155, CSIBM1156, CSIBM1157, >>>>>> CSIBM1158, >>>>>> CSIBM1160, CSIBM1161, CSIBM1163, CSIBM1164, CSIBM1166, CSIBM1167, >>>>>> CSIBM1364, >>>>>> CSIBM1371, CSIBM1388, CSIBM1390, CSIBM1399, CSIBM4517, CSIBM4899, >>>>>> CSIBM4909, >>>>>> CSIBM4971, CSIBM5347, CSIBM9030, CSIBM9066, CSIBM9448, CSIBM12712, >>>>>> CSIBM16804, CSIBM11621162, CSISO4UNITEDKINGDOM, CSISO10SWEDISH, >>>>>> CSISO11SWEDISHFORNAMES, CSISO14JISC6220RO, CSISO15ITALIAN, >>>>>> CSISO16PORTUGESE, >>>>>> CSISO17SPANISH, CSISO18GREEK7OLD, CSISO19LATINGREEK, CSISO21GERMAN, >>>>>> CSISO25FRENCH, CSISO27LATINGREEK1, CSISO49INIS, CSISO50INIS8, >>>>>> CSISO51INISCYRILLIC, CSISO58GB1988, CSISO60DANISHNORWEGIAN, >>>>>> CSISO60NORWEGIAN1, CSISO61NORWEGIAN2, CSISO69FRENCH, >>>>>> CSISO84PORTUGUESE2, >>>>>> CSISO85SPANISH2, CSISO86HUNGARIAN, CSISO88GREEK7, CSISO89ASMO449, >>>>>> CSISO90, >>>>>> CSISO92JISC62991984B, CSISO99NAPLPS, CSISO103T618BIT, >>>>>> CSISO111ECMACYRILLIC, >>>>>> CSISO121CANADIAN1, CSISO122CANADIAN2, CSISO139CSN369103, >>>>>> CSISO141JUSIB1002, >>>>>> CSISO143IECP271, CSISO150, CSISO150GREEKCCITT, CSISO151CUBA, >>>>>> CSISO153GOST1976874, CSISO646DANISH, CSISO2022CN, CSISO2022JP, >>>>>> CSISO2022JP2, >>>>>> CSISO2022KR, CSISO2033, CSISO5427CYRILLIC, CSISO5427CYRILLIC1981, >>>>>> CSISO5428GREEK, CSISO10367BOX, CSISOLATIN1, CSISOLATIN2, >>>>>> CSISOLATIN3, >>>>>> CSISOLATIN4, CSISOLATIN5, CSISOLATIN6, CSISOLATINARABIC, >>>>>> CSISOLATINCYRILLIC, >>>>>> CSISOLATINGREEK, CSISOLATINHEBREW, CSKOI8R, CSKSC5636, CSMACINTOSH, >>>>>> CSNATSDANO, CSNATSSEFI, CSN_369103, CSPC8CODEPAGE437, CSPC775BALTIC, >>>>>> CSPC850MULTILINGUAL, CSPC858MULTILINGUAL, CSPC862LATINHEBREW, >>>>>> CSPCP852, >>>>>> CSSHIFTJIS, CSUCS4, CSUNICODE, CSWINDOWS31J, CUBA, CWI-2, CWI, >>>>>> CYRILLIC, DE, >>>>>> DEC-MCS, DEC, DECMCS, DIN_66003, DK, DS2089, DS_2089, E13B, >>>>>> EBCDIC-AT-DE-A, >>>>>> EBCDIC-AT-DE, EBCDIC-BE, EBCDIC-BR, EBCDIC-CA-FR, EBCDIC-CP-AR1, >>>>>> EBCDIC-CP-AR2, EBCDIC-CP-BE, EBCDIC-CP-CA, EBCDIC-CP-CH, >>>>>> EBCDIC-CP-DK, >>>>>> EBCDIC-CP-ES, EBCDIC-CP-FI, EBCDIC-CP-FR, EBCDIC-CP-GB, >>>>>> EBCDIC-CP-GR, >>>>>> EBCDIC-CP-HE, EBCDIC-CP-IS, EBCDIC-CP-IT, EBCDIC-CP-NL, >>>>>> EBCDIC-CP-NO, >>>>>> EBCDIC-CP-ROECE, EBCDIC-CP-SE, EBCDIC-CP-TR, EBCDIC-CP-US, >>>>>> EBCDIC-CP-WT, >>>>>> EBCDIC-CP-YU, EBCDIC-CYRILLIC, EBCDIC-DK-NO-A, EBCDIC-DK-NO, >>>>>> EBCDIC-ES-A, >>>>>> EBCDIC-ES-S, EBCDIC-ES, EBCDIC-FI-SE-A, EBCDIC-FI-SE, EBCDIC-FR, >>>>>> EBCDIC-GREEK, EBCDIC-INT, EBCDIC-INT1, EBCDIC-IS-FRISS, EBCDIC-IT, >>>>>> EBCDIC-JP-E, EBCDIC-JP-KANA, EBCDIC-PT, EBCDIC-UK, EBCDIC-US, >>>>>> EBCDICATDE, >>>>>> EBCDICATDEA, EBCDICCAFR, EBCDICDKNO, EBCDICDKNOA, EBCDICES, >>>>>> EBCDICESA, >>>>>> EBCDICESS, EBCDICFISE, EBCDICFISEA, EBCDICFR, EBCDICISFRISS, >>>>>> EBCDICIT, >>>>>> EBCDICPT, EBCDICUK, EBCDICUS, ECMA-114, ECMA-118, ECMA-128, >>>>>> ECMA-CYRILLIC, >>>>>> ECMACYRILLIC, ELOT_928, ES, ES2, EUC-CN, EUC-JISX0213, EUC-JP-MS, >>>>>> EUC-JP, >>>>>> EUC-KR, EUC-TW, EUCCN, EUCJP-MS, EUCJP-OPEN, EUCJP-WIN, EUCJP, >>>>>> EUCKR, EUCTW, >>>>>> FI, FR, GB, GB2312, GB13000, GB18030, GBK, GB_1988-80, GB_198880, >>>>>> GEORGIAN-ACADEMY, GEORGIAN-PS, GOST_19768-74, GOST_19768, >>>>>> GOST_1976874, >>>>>> GREEK-CCITT, GREEK, GREEK7-OLD, GREEK7, GREEK7OLD, GREEK8, >>>>>> GREEKCCITT, >>>>>> HEBREW, HP-GREEK8, HP-ROMAN8, HP-ROMAN9, HP-THAI8, HP-TURKISH8, >>>>>> HPGREEK8, >>>>>> HPROMAN8, HPROMAN9, HPTHAI8, HPTURKISH8, HU, IBM-803, IBM-856, >>>>>> IBM-901, >>>>>> IBM-902, IBM-921, IBM-922, IBM-930, IBM-932, IBM-933, IBM-935, >>>>>> IBM-937, >>>>>> IBM-939, IBM-943, IBM-1008, IBM-1025, IBM-1046, IBM-1047, IBM-1097, >>>>>> IBM-1112, >>>>>> IBM-1122, IBM-1123, IBM-1124, IBM-1129, IBM-1130, IBM-1132, >>>>>> IBM-1133, >>>>>> IBM-1137, IBM-1140, IBM-1141, IBM-1142, IBM-1143, IBM-1144, >>>>>> IBM-1145, >>>>>> IBM-1146, IBM-1147, IBM-1148, IBM-1149, IBM-1153, IBM-1154, >>>>>> IBM-1155, >>>>>> IBM-1156, IBM-1157, IBM-1158, IBM-1160, IBM-1161, IBM-1162, >>>>>> IBM-1163, >>>>>> IBM-1164, IBM-1166, IBM-1167, IBM-1364, IBM-1371, IBM-1388, >>>>>> IBM-1390, >>>>>> IBM-1399, IBM-4517, IBM-4899, IBM-4909, IBM-4971, IBM-5347, >>>>>> IBM-9030, >>>>>> IBM-9066, IBM-9448, IBM-12712, IBM-16804, IBM037, IBM038, IBM256, >>>>>> IBM273, >>>>>> IBM274, IBM275, IBM277, IBM278, IBM280, IBM281, IBM284, IBM285, >>>>>> IBM290, >>>>>> IBM297, IBM367, IBM420, IBM423, IBM424, IBM437, IBM500, IBM775, >>>>>> IBM803, >>>>>> IBM813, IBM819, IBM848, IBM850, IBM851, IBM852, IBM855, IBM856, >>>>>> IBM857, >>>>>> IBM858, IBM860, IBM861, IBM862, IBM863, IBM864, IBM865, IBM866, >>>>>> IBM866NAV, >>>>>> IBM868, IBM869, IBM870, IBM871, IBM874, IBM875, IBM880, IBM891, >>>>>> IBM901, >>>>>> IBM902, IBM903, IBM904, IBM905, IBM912, IBM915, IBM916, IBM918, >>>>>> IBM920, >>>>>> IBM921, IBM922, IBM930, IBM932, IBM933, IBM935, IBM937, IBM939, >>>>>> IBM943, >>>>>> IBM1004, IBM1008, IBM1025, IBM1026, IBM1046, IBM1047, IBM1089, >>>>>> IBM1097, >>>>>> IBM1112, IBM1122, IBM1123, IBM1124, IBM1129, IBM1130, IBM1132, >>>>>> IBM1133, >>>>>> IBM1137, IBM1140, IBM1141, IBM1142, IBM1143, IBM1144, IBM1145, >>>>>> IBM1146, >>>>>> IBM1147, IBM1148, IBM1149, IBM1153, IBM1154, IBM1155, IBM1156, >>>>>> IBM1157, >>>>>> IBM1158, IBM1160, IBM1161, IBM1162, IBM1163, IBM1164, IBM1166, >>>>>> IBM1167, >>>>>> IBM1364, IBM1371, IBM1388, IBM1390, IBM1399, IBM4517, IBM4899, >>>>>> IBM4909, >>>>>> IBM4971, IBM5347, IBM9030, IBM9066, IBM9448, IBM12712, IBM16804, >>>>>> IEC_P27-1, >>>>>> IEC_P271, INIS-8, INIS-CYRILLIC, INIS, INIS8, INISCYRILLIC, >>>>>> ISIRI-3342, >>>>>> ISIRI3342, ISO-2022-CN-EXT, ISO-2022-CN, ISO-2022-JP-2, >>>>>> ISO-2022-JP-3, >>>>>> ISO-2022-JP, ISO-2022-KR, ISO-8859-1, ISO-8859-2, ISO-8859-3, >>>>>> ISO-8859-4, >>>>>> ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, >>>>>> ISO-8859-9E, >>>>>> ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, >>>>>> ISO-8859-16, >>>>>> ISO-10646, ISO-10646/UCS2, ISO-10646/UCS4, ISO-10646/UTF-8, >>>>>> ISO-10646/UTF8, >>>>>> ISO-CELTIC, ISO-IR-4, ISO-IR-6, ISO-IR-8-1, ISO-IR-9-1, ISO-IR-10, >>>>>> ISO-IR-11, >>>>>> ISO-IR-14, ISO-IR-15, ISO-IR-16, ISO-IR-17, ISO-IR-18, ISO-IR-19, >>>>>> ISO-IR-21, >>>>>> ISO-IR-25, ISO-IR-27, ISO-IR-37, ISO-IR-49, ISO-IR-50, ISO-IR-51, >>>>>> ISO-IR-54, >>>>>> ISO-IR-55, ISO-IR-57, ISO-IR-60, ISO-IR-61, ISO-IR-69, ISO-IR-84, >>>>>> ISO-IR-85, >>>>>> ISO-IR-86, ISO-IR-88, ISO-IR-89, ISO-IR-90, ISO-IR-92, ISO-IR-98, >>>>>> ISO-IR-99, >>>>>> ISO-IR-100, ISO-IR-101, ISO-IR-103, ISO-IR-109, ISO-IR-110, >>>>>> ISO-IR-111, >>>>>> ISO-IR-121, ISO-IR-122, ISO-IR-126, ISO-IR-127, ISO-IR-138, >>>>>> ISO-IR-139, >>>>>> ISO-IR-141, ISO-IR-143, ISO-IR-144, ISO-IR-148, ISO-IR-150, >>>>>> ISO-IR-151, >>>>>> ISO-IR-153, ISO-IR-155, ISO-IR-156, ISO-IR-157, ISO-IR-166, >>>>>> ISO-IR-179, >>>>>> ISO-IR-193, ISO-IR-197, ISO-IR-199, ISO-IR-203, ISO-IR-209, >>>>>> ISO-IR-226, >>>>>> ISO/TR_11548-1, ISO646-CA, ISO646-CA2, ISO646-CN, ISO646-CU, >>>>>> ISO646-DE, >>>>>> ISO646-DK, ISO646-ES, ISO646-ES2, ISO646-FI, ISO646-FR, ISO646-FR1, >>>>>> ISO646-GB, ISO646-HU, ISO646-IT, ISO646-JP-OCR-B, ISO646-JP, >>>>>> ISO646-KR, >>>>>> ISO646-NO, ISO646-NO2, ISO646-PT, ISO646-PT2, ISO646-SE, ISO646-SE2, >>>>>> ISO646-US, ISO646-YU, ISO2022CN, ISO2022CNEXT, ISO2022JP, >>>>>> ISO2022JP2, >>>>>> ISO2022KR, ISO6937, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, >>>>>> ISO8859-5, >>>>>> ISO8859-6, ISO8859-7, ISO8859-8, ISO8859-9, ISO8859-9E, ISO8859-10, >>>>>> ISO8859-11, ISO8859-13, ISO8859-14, ISO8859-15, ISO8859-16, >>>>>> ISO11548-1, >>>>>> ISO88591, ISO88592, ISO88593, ISO88594, ISO88595, ISO88596, >>>>>> ISO88597, >>>>>> ISO88598, ISO88599, ISO88599E, ISO885910, ISO885911, ISO885913, >>>>>> ISO885914, >>>>>> ISO885915, ISO885916, ISO_646.IRV:1991, ISO_2033-1983, ISO_2033, >>>>>> ISO_5427-EXT, ISO_5427, ISO_5427:1981, ISO_5427EXT, ISO_5428, >>>>>> ISO_5428:1980, >>>>>> ISO_6937-2, ISO_6937-2:1983, ISO_6937, ISO_6937:1992, ISO_8859-1, >>>>>> ISO_8859-1:1987, ISO_8859-2, ISO_8859-2:1987, ISO_8859-3, >>>>>> ISO_8859-3:1988, >>>>>> ISO_8859-4, ISO_8859-4:1988, ISO_8859-5, ISO_8859-5:1988, >>>>>> ISO_8859-6, >>>>>> ISO_8859-6:1987, ISO_8859-7, ISO_8859-7:1987, ISO_8859-7:2003, >>>>>> ISO_8859-8, >>>>>> ISO_8859-8:1988, ISO_8859-9, ISO_8859-9:1989, ISO_8859-9E, >>>>>> ISO_8859-10, >>>>>> ISO_8859-10:1992, ISO_8859-14, ISO_8859-14:1998, ISO_8859-15, >>>>>> ISO_8859-15:1998, ISO_8859-16, ISO_8859-16:2001, ISO_9036, >>>>>> ISO_10367-BOX, >>>>>> ISO_10367BOX, ISO_11548-1, ISO_69372, IT, JIS_C6220-1969-RO, >>>>>> JIS_C6229-1984-B, JIS_C62201969RO, JIS_C62291984B, JOHAB, JP-OCR-B, >>>>>> JP, JS, >>>>>> JUS_I.B1.002, KOI-7, KOI-8, KOI8-R, KOI8-RU, KOI8-T, KOI8-U, KOI8, >>>>>> KOI8R, >>>>>> KOI8U, KSC5636, L1, L2, L3, L4, L5, L6, L7, L8, L10, LATIN-9, >>>>>> LATIN-GREEK-1, >>>>>> LATIN-GREEK, LATIN1, LATIN2, LATIN3, LATIN4, LATIN5, LATIN6, >>>>>> LATIN7, LATIN8, >>>>>> LATIN9, LATIN10, LATINGREEK, LATINGREEK1, MAC-CENTRALEUROPE, >>>>>> MAC-CYRILLIC, >>>>>> MAC-IS, MAC-SAMI, MAC-UK, MAC, MACCYRILLIC, MACINTOSH, MACIS, MACUK, >>>>>> MACUKRAINIAN, MIK, MS-ANSI, MS-ARAB, MS-CYRL, MS-EE, MS-GREEK, >>>>>> MS-HEBR, >>>>>> MS-MAC-CYRILLIC, MS-TURK, MS932, MS936, MSCP949, MSCP1361, >>>>>> MSMACCYRILLIC, >>>>>> MSZ_7795.3, MS_KANJI, NAPLPS, NATS-DANO, NATS-SEFI, NATSDANO, >>>>>> NATSSEFI, >>>>>> NC_NC0010, NC_NC00-10, NC_NC00-10:81, NF_Z_62-010, >>>>>> NF_Z_62-010_(1973), >>>>>> NF_Z_62-010_1973, NF_Z_62010, NF_Z_62010_1973, NO, NO2, NS_4551-1, >>>>>> NS_4551-2, >>>>>> NS_45511, NS_45512, OS2LATIN1, OSF00010001, OSF00010002, >>>>>> OSF00010003, >>>>>> OSF00010004, OSF00010005, OSF00010006, OSF00010007, OSF00010008, >>>>>> OSF00010009, >>>>>> OSF0001000A, OSF00010020, OSF00010100, OSF00010101, OSF00010102, >>>>>> OSF00010104, >>>>>> OSF00010105, OSF00010106, OSF00030010, OSF0004000A, OSF0005000A, >>>>>> OSF05010001, >>>>>> OSF100201A4, OSF100201A8, OSF100201B5, OSF100201F4, OSF100203B5, >>>>>> OSF1002011C, >>>>>> OSF1002011D, OSF1002035D, OSF1002035E, OSF1002035F, OSF1002036B, >>>>>> OSF1002037B, >>>>>> OSF10010001, OSF10010004, OSF10010006, OSF10020025, OSF10020111, >>>>>> OSF10020115, >>>>>> OSF10020116, OSF10020118, OSF10020122, OSF10020129, OSF10020352, >>>>>> OSF10020354, >>>>>> OSF10020357, OSF10020359, OSF10020360, OSF10020364, OSF10020365, >>>>>> OSF10020366, >>>>>> OSF10020367, OSF10020370, OSF10020387, OSF10020388, OSF10020396, >>>>>> OSF10020402, >>>>>> OSF10020417, PT, PT2, PT154, R8, R9, RK1048, ROMAN8, ROMAN9, >>>>>> RUSCII, SE, SE2, >>>>>> SEN_850200_B, SEN_850200_C, SHIFT-JIS, SHIFTJISX0213, SHIFT_JIS, >>>>>> SHIFT_JISX0213, SJIS-OPEN, SJIS-WIN, SJIS, SS636127, STRK1048-2002, >>>>>> ST_SEV_358-88, T.61-8BIT, T.61, T.618BIT, TCVN-5712, TCVN, >>>>>> TCVN5712-1, >>>>>> TCVN5712-1:1993, THAI8, TIS-620, TIS620-0, TIS620.2529-1, >>>>>> TIS620.2533-0, >>>>>> TIS620, TS-5881, TSCII, TURKISH8, UCS-2, UCS-2BE, UCS-2LE, UCS-4, >>>>>> UCS-4BE, >>>>>> UCS-4LE, UCS2, UCS4, UHC, UJIS, UK, UNICODE, UNICODEBIG, >>>>>> UNICODELITTLE, >>>>>> US-ASCII, US, UTF-7, UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, >>>>>> UTF-32BE, >>>>>> UTF-32LE, UTF7, UTF8, UTF16, UTF16BE, UTF16LE, UTF32, UTF32BE, >>>>>> UTF32LE, >>>>>> VISCII, WCHAR_T, WIN-SAMI-2, WINBALTRIM, WINDOWS-31J, WINDOWS-874, >>>>>> WINDOWS-936, WINDOWS-1250, WINDOWS-1251, WINDOWS-1252, WINDOWS-1253, >>>>>> WINDOWS-1254, WINDOWS-1255, WINDOWS-1256, WINDOWS-1257, >>>>>> WINDOWS-1258, >>>>>> WINSAMI2, WS2, YU >>>>>> >>>>>> >>>>>> On Sun, Nov 22, 2020 at 7:38 AM Rene Veerman < >>>>>> rene.veerman.netherlands@gmail.com> wrote: >>>>>> >>>>>>> i've also tried a commandline >>>>>>> iconv -f=Windows-1250 -t=UTF-8 enca.txt >>>>>>> but that returns the data unaltered :( >>>>>>> >>>>>>> On Sun, Nov 22, 2020 at 7:37 AM Rene Veerman < >>>>>>> rene.veerman.netherlands@gmail.com> wrote: >>>>>>> >>>>>>>> as additional and background info, i can tell you that this data >>>>>>>> came from a gmail server which upon 'show original', gave >>>>>>>> me extra headers >>>>>>>> (that are not in the data, nor in the headers as downloaded through >>>>>>>> PHP's imap functions), which told me that the charset is >>>>>>>> windows-1250. >>>>>>>> so this must come from Google's magical algorithms, which i >>>>>>>> find up >>>>>>>> to now impossible to reproduce :( >>>>>>>> >>>>>>>> On Sun, Nov 22, 2020 at 7:33 AM Rene Veerman < >>>>>>>> rene.veerman.netherlands@gmail.com> wrote: >>>>>>>> >>>>>>>>> no, it PHP iconv only supports nl_NL.utf8 and various en_*.utf8 >>>>>>>>> according to >>>>>>>>> locale -a >>>>>>>>> on the Ubuntu command prompt :( >>>>>>>>> >>>>>>>>> and using nl_NL.utf8 doesn't fix my problem either :( >>>>>>>>> >>>>>>>>> I've also tried saving the file to disk and then using >>>>>>>>> commandline >>>>>>>>> enca file.ext >>>>>>>>> and >>>>>>>>> file file.ext >>>>>>>>> and >>>>>>>>> chardet file.ext >>>>>>>>> and >>>>>>>>> uchar file.ext >>>>>>>>> but all these will give me is that the file is encoded in >>>>>>>>> ASCII. >>>>>>>>> >>>>>>>>> On the upside, Ubuntu commandline >>>>>>>>> iconv >>>>>>>>> will support the windows-1250 character set, >>>>>>>>> but i have no way to detect which character set my document is >>>>>>>>> encoded in, at this time :( >>>>>>>>> >>>>>>>>> For your convenience, i've included the file in question >>>>>>>>> as an >>>>>>>>> attachment to this email.. >>>>>>>>> >>>>>>>>> >>>>>>>>> On Sat, Nov 21, 2020 at 2:59 PM Christoph M. Becker < >>>>>>>>> cmbecker69@gmx.de> wrote: >>>>>>>>> >>>>>>>>>> On 21.11.2020 at 14:21, Rene Veerman wrote: >>>>>>>>>> >>>>>>>>>> > I'm having a bit of trouble decoding a message >>>>>>>>>> > that was written >>>>>>>>>> using the >>>>>>>>>> > Windows-1250 character set, on an Ubuntu PHP >>>>>>>>>> > installation that >>>>>>>>>> according to >>>>>>>>>> > mb_list_encodings only supports the Windows-1251, >>>>>>>>>> > Windows-1252 >>>>>>>>>> and >>>>>>>>>> > Windows-1254 character sets. >>>>>>>>>> > >>>>>>>>>> > Can someone here please point me in the direction of a >>>>>>>>>> > solution >>>>>>>>>> for this? >>>>>>>>>> >>>>>>>>>> Maybe Windows-1250 is supported by your iconv() >>>>>>>>>> >>>>>>>>>> (<https://www.php.net/manual/en/function.iconv.php>)? >>>>>>>>>> >>>>>>>>>> Christoph >>>>>>>>>> >>>>>>>>>

« previous php.general (#327376) next »