Changeset 343 in subversion


Ignore:
Timestamp:
Sep 13, 2006 6:46:11 PM (7 years ago)
Author:
thomasb
Message:

Header encoding again. iconv_mime_encode does no good job

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/program/lib/Mail/mime.php

    r340 r343  
    788788    function _encodeHeaders($input) 
    789789    { 
     790        $maxlen = 73; 
    790791        foreach ($input as $hdr_name => $hdr_value) { 
    791             if (function_exists('iconv_mime_encode') && preg_match('#[\x80-\xFF]{1}#', $hdr_value)){ 
    792                 $imePref = array(); 
    793                 if ($this->_build_params['head_encoding'] == 'base64'){ 
    794                     $imePrefs['scheme'] = 'B'; 
    795                 }else{ 
    796                     $imePrefs['scheme'] = 'Q'; 
     792            // if header contains e-mail addresses 
     793            if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) 
     794                $chunks = $this->_explode_quoted_string(',', $hdr_value); 
     795            else 
     796               $chunks = array($hdr_value); 
     797 
     798            $hdr_value = ''; 
     799            $line_len = 0; 
     800 
     801            foreach ($chunks as $i => $value) { 
     802                $value = trim($value); 
     803 
     804                //This header contains non ASCII chars and should be encoded. 
     805                if (preg_match('#[\x80-\xFF]{1}#', $value)) { 
     806                    $suffix = ''; 
     807                    // Don't encode e-mail address 
     808                    if (preg_match('/(.+)\s(<.+@[a-z0-9\-\.]+\.[a-z]{2,5}>)$/Ui', $value, $matches)) { 
     809                        $value = $matches[1]; 
     810                        $suffix = ' '.$matches[2]; 
     811                    } 
     812 
     813                    switch ($this->_build_params['head_encoding']) { 
     814                    case 'base64': 
     815                        // Base64 encoding has been selected. 
     816                        $mode = 'B'; 
     817                        $encoded = base64_encode($value); 
     818                        break; 
     819 
     820                    case 'quoted-printable': 
     821                    default: 
     822                        // quoted-printable encoding has been selected 
     823                        $mode = 'Q'; 
     824                        $encoded = preg_replace('/([\x20-\x25\x2C\x80-\xFF])/e', "'='.sprintf('%02X', ord('\\1'))", $value); 
     825                        // replace spaces with _ 
     826                        $encoded = str_replace('=20', '_', $encoded); 
     827                    } 
     828 
     829                $value = '=?' . $this->_build_params['head_charset'] . '?' . $mode . '?' . $encoded . '?=' . $suffix; 
    797830                } 
    798                 $imePrefs['input-charset']  = $this->_build_params['head_charset']; 
    799                 $imePrefs['output-charset'] = $this->_build_params['head_charset']; 
    800                 $hdr_value = iconv_mime_encode($hdr_name, $hdr_value, $imePrefs); 
    801                 $hdr_value = preg_replace("#^{$hdr_name}\:\ #", "", $hdr_value); 
    802             }elseif (preg_match('#[\x80-\xFF]{1}#', $hdr_value)){ 
    803                 //This header contains non ASCII chars and should be encoded. 
    804                 switch ($this->_build_params['head_encoding']) { 
    805                 case 'base64': 
    806                     //Base64 encoding has been selected. 
    807                      
    808                     //Generate the header using the specified params and dynamicly  
    809                     //determine the maximum length of such strings. 
    810                     //75 is the value specified in the RFC. The -2 is there so  
    811                     //the later regexp doesn't break any of the translated chars. 
    812                     $prefix = '=?' . $this->_build_params['head_charset'] . '?B?'; 
    813                     $suffix = '?='; 
    814                     $maxLength = 75 - strlen($prefix . $suffix) - 2; 
    815                     $maxLength1stLine = $maxLength - strlen($hdr_name); 
    816                      
    817                     //Base64 encode the entire string 
    818                     $hdr_value = base64_encode($hdr_value); 
    819  
    820                     //This regexp will break base64-encoded text at every  
    821                     //$maxLength but will not break any encoded letters. 
    822                     $reg1st = "|.{0,$maxLength1stLine}[^\=][^\=]|"; 
    823                     $reg2nd = "|.{0,$maxLength}[^\=][^\=]|"; 
    824                     break; 
    825                 case 'quoted-printable': 
    826                 default: 
    827                     //quoted-printable encoding has been selected 
    828                      
    829                     preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $hdr_value, $matches);  
    830                     foreach ($matches[1] as $value) {  
    831                         $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);  
    832                         $hdr_value = str_replace($value, '=?' . $this->_build_params['head_charset'] . '?Q?' . $replacement . '?=', $hdr_value); 
    833                     } 
     831 
     832                // add chunk to output string by regarding the header maxlen 
     833                $len = strlen($value); 
     834                if ($line_len + $len < $maxlen) { 
     835                    $hdr_value .= ($i>0?', ':'') . $value; 
     836                    $line_len += $len + ($i>0?2:0); 
    834837                } 
     838                else { 
     839                    $hdr_value .= ($i>0?', ':'') . "\n " . $value; 
     840                    $line_len = $len; 
     841                } 
    835842            } 
    836843 
     
    840847        return $input; 
    841848    } 
     849 
     850 
     851  function _explode_quoted_string($delimiter, $string) 
     852    { 
     853    $quotes = explode("\"", $string); 
     854    foreach ($quotes as $key => $val) 
     855      if (($key % 2) == 1) 
     856        $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]); 
     857 
     858    $string = implode("\"", $quotes); 
     859 
     860    $result = explode($delimiter, $string); 
     861    foreach ($result as $key => $val)  
     862      $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]); 
     863 
     864    return $result; 
     865    } 
     866 
    842867 
    843868    /** 
Note: See TracChangeset for help on using the changeset viewer.