php-imap icon indicating copy to clipboard operation
php-imap copied to clipboard

Support for cyrillic Windows-1251

Open alaevka opened this issue 4 years ago • 8 comments
trafficstars

Hi! As described at #76 we need support for subject that decoded in cyrilic Windows-1251

Subject: =?Windows-1251?B?z+7k8uLl8Obk5e3o5SDk7vHy4OLq6CDx7u7h+eXt6P8g7eAg4OTw5fEgb3BAbnBwc2Vuc29yLnJ1?=

For example you may send any mail to [email protected] and wait for response message that contains this subject

alaevka avatar Feb 10 '21 14:02 alaevka

Added in Webklex\PHPIMAP\Header -> decode method if (strpos(strtolower($value), '=?windows-1251?') !== false) { $decoder = 'iconv'; } works fine for me

alaevka avatar Feb 10 '21 15:02 alaevka

Full working example!

private function decode($value) {
        if (is_array($value)) {
            return $this->decodeArray($value);
        }
        $original_value = $value;
        $decoder = $this->config['decoder']['message'];

        if(strpos(strtolower($value), '=?windows-1251?') !== false) {
            $decoder = 'iconv';
        }

        if ($value !== null) {
            $is_utf8_base = $this->is_uft8($value);

            if($decoder === 'utf-8' && extension_loaded('imap')) {
                $value = \imap_utf8($value);
                $is_utf8_base = $this->is_uft8($value);
                if ($is_utf8_base) {
                    $value = mb_decode_mimeheader($value);
                }
                if ($this->notDecoded($original_value, $value)) {
                    $decoded_value = $this->mime_header_decode($value);
                    if (count($decoded_value) > 0) {
                        if(property_exists($decoded_value[0], "text")) {
                            $value = $decoded_value[0]->text;
                        }
                    }
                }
            }elseif($decoder === 'iconv' && $is_utf8_base) {
                $value = iconv_mime_decode($value);
            }elseif($decoder === 'iconv') {
                $value = iconv_mime_decode($value);
            }elseif($is_utf8_base){
                $value = mb_decode_mimeheader($value);
            }

            if ($this->is_uft8($value)) {
                $value = mb_decode_mimeheader($value);
            }

            if ($this->notDecoded($original_value, $value)) {
                $value = $this->convertEncoding($original_value, $this->getEncoding($original_value));
            }
        }

        return $value;
    }

alaevka avatar Feb 10 '21 15:02 alaevka

Hi @alaevka , many thanks for the followup! Would you like to create a pull request?

Otherwise i'll patch it during the next weekend :)

Best regards,

Webklex avatar Feb 17 '21 15:02 Webklex

Hi @alaevka , as you might noticed, I havn't found a patch jet. It turns out to be a a bit more complicated than just "fixing" the regex :)

Best regards,

Webklex avatar Jun 17 '21 16:06 Webklex

Hi @Webklex

For me part of the problem comes from divided attributes

Here are some raw attributes that should be managed (in rfc822_parse_headers() of Header.php ??) :

Content-Type: application/pdf;
 name="=?UTF-8?Q?PPT_support_CS_SYDED_du_19_05_2021_VF_avec_r=c3=a9sultat_d?=
 =?UTF-8?Q?es_votes=2epdf?="
Content-Type: application/pdf;
 name*0*=UTF-8''Un%20mail%20%C3%A0v%C3%A9c%20un%20s%C3%B9jet%20tr%C3%A8s;
 name*1*=%20long%20pour%20voir%20ce%20qu%27ca%20donne%20quand%20n%20met%20;
 name*2*=boucoup%20de%20la%20donn%C3%A9e%20de%20la%20mort%20dans%20un%20en;
 name*3*=droit%20qu%27on%20devrait%20p%C3%A0s.pdf

We'll continue to drill in your code because we got another mail that is not working (no attachment found while exists in rawData)

Thanks Best regards

nicohell avatar Jun 17 '21 17:06 nicohell

Good Morning

rc2231 explains "Parameter continuations"

nicohell avatar Jun 18 '21 07:06 nicohell

for those who use laravel and have problems with encoding Russian headers, you can use:

private function decode($value) {//dump($value);
        if (is_array($value)) {
            return $this->decodeArray($value);
        }
        $original_value = $value;
        $decoder = $this->config['decoder']['message'];

        if(strpos(strtolower($value), '=?windows-1251?') !== false || strpos(strtolower($value), '=?koi8-r') !== false) {
            $value = Str::replace(['=?KOI8-R?B?', '?='], '', $value);
            $value = base64_decode($value); // decode base64 data
            $value = iconv('koi8-r', 'UTF-8', $value); // convert source data to UTF-8
        }

        if ($value !== null) {
            $is_utf8_base = $this->is_uft8($value);

            if($decoder === 'utf-8' && extension_loaded('imap')) {
                $value = \imap_utf8($value);
                $is_utf8_base = $this->is_uft8($value);
                if ($is_utf8_base) {
                    $value = mb_decode_mimeheader($value);
                }
                if ($this->notDecoded($original_value, $value)) {
                    $decoded_value = $this->mime_header_decode($value);
                    if (count($decoded_value) > 0) {
                        if(property_exists($decoded_value[0], "text")) {
                            $value = $decoded_value[0]->text;
                        }
                    }
                }
            }elseif($decoder === 'iconv' && $is_utf8_base) {
                $value = iconv_mime_decode($value);
            }elseif($decoder === 'iconv') {
                $value = iconv_mime_decode($value);
            }elseif($is_utf8_base){
                $value = mb_decode_mimeheader($value);
            }

            if ($this->is_uft8($value)) {
                $value = mb_decode_mimeheader($value);
            }

            if ($this->notDecoded($original_value, $value)) {
                $value = $this->convertEncoding($original_value, $this->getEncoding($original_value));
            }
        }

        return $value;
    }

or rewrite one line in pure php and a regular expression

AntistressStore avatar Jul 17 '21 02:07 AntistressStore

Same problem with getting attachment name or filename in UTF-8.

Sample attachment header:

Content-Type: application/pdf;
 name="=?UTF-8?B?0J/RgNC40LvQvtC20LXQvdC40LUgNyAtINCh0L7Qs9C70LDRgdC40LUg?=
 =?UTF-8?B?0YEg0KLQly5wZGY=?="
Content-Disposition: attachment;
 filename*0*=UTF-8''%D0%9F%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8;
 filename*1*=%D0%B5%20%37%20%2D%20%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%81;
 filename*2*=%D0%B8%D0%B5%20%D1%81%20%D0%A2%D0%97%2E%70%64%66
Content-Transfer-Encoding: base64

Result name in attachment name: undefined

AndrusX-Git avatar Apr 20 '22 14:04 AndrusX-Git

Please update to v5.1 and give it another try. If you are currently using an older version below v5.0, please read the breaking changes leading up to v5.1 before upgrading.

Best regards,

Webklex avatar Mar 16 '23 00:03 Webklex