Ignore:
Timestamp:
Jul 29, 2010 2:50:19 AM (3 years ago)
Author:
alec
Message:
  • Mail-Mime-1.8.0
File:
1 edited

Legend:

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

    r3402 r3837  
    216216        } 
    217217 
     218        // Default content-type 
     219        if (empty($c_type['type'])) { 
     220            $c_type['type'] = 'text/plain'; 
     221        } 
     222 
    218223        // Content-Type 
    219         if (isset($c_type['type'])) { 
     224        if (!empty($c_type['type'])) { 
    220225            $headers['Content-Type'] = $c_type['type']; 
    221             if (isset($c_type['name'])) { 
     226            if (!empty($c_type['charset'])) { 
     227                $charset = "charset={$c_type['charset']}"; 
     228                // place charset parameter in the same line, if possible 
     229                if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) { 
     230                    $headers['Content-Type'] .= '; '; 
     231                } else { 
     232                    $headers['Content-Type'] .= ';' . $this->_eol . ' '; 
     233                } 
     234                $headers['Content-Type'] .= $charset; 
     235            } 
     236            if (!empty($c_type['name'])) { 
    222237                $headers['Content-Type'] .= ';' . $this->_eol; 
    223238                $headers['Content-Type'] .= $this->_buildHeaderParam( 
    224                     'name', $c_type['name'],  
    225                     isset($c_type['charset']) ? $c_type['charset'] : 'US-ASCII',  
     239                    'name', $c_type['name'], 
     240                    isset($c_type['charset']) ? $c_type['charset'] : 'US-ASCII', 
    226241                    isset($c_type['language']) ? $c_type['language'] : null, 
    227242                    isset($params['name_encoding']) ?  $params['name_encoding'] : null 
    228243                ); 
    229244            } 
    230             if (isset($c_type['charset'])) { 
    231                 $headers['Content-Type'] 
    232                     .= ';' . $this->_eol . " charset={$c_type['charset']}"; 
    233             } 
    234245        } 
    235246 
    236247        // Content-Disposition 
    237         if (isset($c_disp['disp'])) { 
     248        if (!empty($c_disp['disp'])) { 
    238249            $headers['Content-Disposition'] = $c_disp['disp']; 
    239             if (isset($c_disp['filename'])) { 
     250            if (!empty($c_disp['filename'])) { 
    240251                $headers['Content-Disposition'] .= ';' . $this->_eol; 
    241252                $headers['Content-Disposition'] .= $this->_buildHeaderParam( 
    242                     'filename', $c_disp['filename'],  
    243                     isset($c_disp['charset']) ? $c_disp['charset'] : 'US-ASCII',  
     253                    'filename', $c_disp['filename'], 
     254                    isset($c_disp['charset']) ? $c_disp['charset'] : 'US-ASCII', 
    244255                    isset($c_disp['language']) ? $c_disp['language'] : null, 
    245256                    isset($params['filename_encoding']) ?  $params['filename_encoding'] : null 
     
    255266                $this->_eol 
    256267            ); 
    257         } 
    258  
    259         // Default content-type 
    260         if (!isset($headers['Content-Type'])) { 
    261             $headers['Content-Type'] = 'text/plain'; 
    262268        } 
    263269 
     
    961967    function encodeHeaderValue($value, $charset, $encoding, $prefix_len=0, $eol="\r\n") 
    962968    { 
    963         if ($encoding == 'base64') { 
     969        // #17311: Use multibyte aware method (requires mbstring extension) 
     970        if ($result = Mail_mimePart::encodeMB($value, $charset, $encoding, $prefix_len, $eol)) { 
     971            return $result; 
     972        } 
     973 
     974        // Generate the header using the specified params and dynamicly 
     975        // determine the maximum length of such strings. 
     976        // 75 is the value specified in the RFC. 
     977        $encoding = $encoding == 'base64' ? 'B' : 'Q'; 
     978        $prefix = '=?' . $charset . '?' . $encoding .'?'; 
     979        $suffix = '?='; 
     980        $maxLength = 75 - strlen($prefix . $suffix); 
     981        $maxLength1stLine = $maxLength - $prefix_len; 
     982 
     983        if ($encoding == 'B') { 
    964984            // Base64 encode the entire string 
    965985            $value = base64_encode($value); 
    966986 
    967             // Generate the header using the specified params and dynamicly  
    968             // determine the maximum length of such strings. 
    969             // 75 is the value specified in the RFC. 
    970             $prefix = '=?' . $charset . '?B?'; 
    971             $suffix = '?='; 
    972             $maxLength = 75 - strlen($prefix . $suffix) - 2; 
    973             $maxLength1stLine = $maxLength - $prefix_len; 
    974  
    975             // We can cut base4 every 4 characters, so the real max 
     987            // We can cut base64 every 4 characters, so the real max 
    976988            // we can get must be rounded down. 
    977989            $maxLength = $maxLength - ($maxLength % 4); 
     
    979991 
    980992            $cutpoint = $maxLength1stLine; 
    981             $value_out = $value; 
    982993            $output = ''; 
    983             while ($value_out) { 
     994 
     995            while ($value) { 
    984996                // Split translated string at every $maxLength 
    985                 $part = substr($value_out, 0, $cutpoint); 
    986                 $value_out = substr($value_out, $cutpoint); 
     997                $part = substr($value, 0, $cutpoint); 
     998                $value = substr($value, $cutpoint); 
    987999                $cutpoint = $maxLength; 
    9881000                // RFC 2047 specifies that any split header should 
    989                 // be seperated by a CRLF SPACE.  
     1001                // be seperated by a CRLF SPACE. 
    9901002                if ($output) { 
    9911003                    $output .= $eol . ' '; 
     
    9981010            $value = Mail_mimePart::encodeQP($value); 
    9991011 
    1000             // Generate the header using the specified params and dynamicly  
    1001             // determine the maximum length of such strings. 
    1002             // 75 is the value specified in the RFC. 
    1003             $prefix = '=?' . $charset . '?Q?'; 
    1004             $suffix = '?='; 
    1005             $maxLength = 75 - strlen($prefix . $suffix) - 3; 
    1006             $maxLength1stLine = $maxLength - $prefix_len; 
    1007             $maxLength = $maxLength - 1; 
    1008  
    10091012            // This regexp will break QP-encoded text at every $maxLength 
    10101013            // but will not break any encoded letters. 
     
    10121015            $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; 
    10131016 
    1014             $value_out = $value; 
    1015             $realMax = $maxLength1stLine + strlen($prefix . $suffix); 
    1016             if (strlen($value_out) >= $realMax) { 
     1017            if (strlen($value) > $maxLength1stLine) { 
    10171018                // Begin with the regexp for the first line. 
    10181019                $reg = $reg1st; 
    10191020                $output = ''; 
    1020                 while ($value_out) { 
     1021                while ($value) { 
    10211022                    // Split translated string at every $maxLength 
    10221023                    // But make sure not to break any translated chars. 
    1023                     $found = preg_match($reg, $value_out, $matches); 
     1024                    $found = preg_match($reg, $value, $matches); 
    10241025 
    10251026                    // After this first line, we need to use a different 
     
    10331034                        $part = $matches[0]; 
    10341035                        $len = strlen($matches[0]); 
    1035                         $value_out = substr($value_out, $len); 
     1036                        $value = substr($value, $len); 
    10361037                    } else { 
    1037                         $part = $value_out; 
    1038                         $value_out = ""; 
     1038                        $part = $value; 
     1039                        $value = ''; 
    10391040                    } 
    10401041 
    1041                     // RFC 2047 specifies that any split header should  
     1042                    // RFC 2047 specifies that any split header should 
    10421043                    // be seperated by a CRLF SPACE 
    10431044                    if ($output) { 
     
    10461047                    $output .= $prefix . $part . $suffix; 
    10471048                } 
    1048                 $value_out = $output; 
     1049                $value = $output; 
    10491050            } else { 
    1050                 $value_out = $prefix . $value_out . $suffix; 
    1051             } 
    1052             $value = $value_out; 
     1051                $value = $prefix . $value . $suffix; 
     1052            } 
    10531053        } 
    10541054 
     
    10681068    { 
    10691069        // Bug #17226 RFC 2047 restricts some characters 
    1070         // if the word is inside a phrase, permit chars are only: 
     1070        // if the word is inside a phrase, permitted chars are only: 
    10711071        // ASCII letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" 
    10721072 
     
    10811081 
    10821082    /** 
     1083     * Encodes the given string using base64 or quoted-printable. 
     1084     * This method makes sure that encoded-word represents an integral 
     1085     * number of characters as per RFC2047. 
     1086     * 
     1087     * @param string $str        String to encode 
     1088     * @param string $charset    Character set name 
     1089     * @param string $encoding   Encoding name (base64 or quoted-printable) 
     1090     * @param int    $prefix_len Prefix length. Default: 0 
     1091     * @param string $eol        End-of-line sequence. Default: "\r\n" 
     1092     * 
     1093     * @return string     Encoded string 
     1094     * @access public 
     1095     * @since 1.8.0 
     1096     */ 
     1097    function encodeMB($str, $charset, $encoding, $prefix_len=0, $eol="\r\n") 
     1098    { 
     1099        if (!function_exists('mb_substr') || !function_exists('mb_strlen')) { 
     1100            return; 
     1101        } 
     1102 
     1103        $encoding = $encoding == 'base64' ? 'B' : 'Q'; 
     1104        // 75 is the value specified in the RFC 
     1105        $prefix = '=?' . $charset . '?'.$encoding.'?'; 
     1106        $suffix = '?='; 
     1107        $maxLength = 75 - strlen($prefix . $suffix); 
     1108 
     1109        // A multi-octet character may not be split across adjacent encoded-words 
     1110        // So, we'll loop over each character 
     1111        // mb_stlen() with wrong charset will generate a warning here and return null 
     1112        $length      = mb_strlen($str, $charset); 
     1113        $result      = ''; 
     1114        $line_length = $prefix_len; 
     1115 
     1116        if ($encoding == 'B') { 
     1117            // base64 
     1118            $start = 0; 
     1119            $prev  = ''; 
     1120 
     1121            for ($i=1; $i<=$length; $i++) { 
     1122                // See #17311 
     1123                $chunk = mb_substr($str, $start, $i-$start, $charset); 
     1124                $chunk = base64_encode($chunk); 
     1125                $chunk_len = strlen($chunk); 
     1126 
     1127                if ($line_length + $chunk_len == $maxLength || $i == $length) { 
     1128                    if ($result) { 
     1129                        $result .= "\n"; 
     1130                    } 
     1131                    $result .= $chunk; 
     1132                    $line_length = 0; 
     1133                    $start = $i; 
     1134                } else if ($line_length + $chunk_len > $maxLength) { 
     1135                    if ($result) { 
     1136                        $result .= "\n"; 
     1137                    } 
     1138                    if ($prev) { 
     1139                        $result .= $prev; 
     1140                    } 
     1141                    $line_length = 0; 
     1142                    $start = $i - 1; 
     1143                } else { 
     1144                    $prev = $chunk; 
     1145                } 
     1146            } 
     1147        } else { 
     1148            // quoted-printable 
     1149            // see encodeQP() 
     1150            $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; 
     1151 
     1152            for ($i=0; $i<=$length; $i++) { 
     1153                $char = mb_substr($str, $i, 1, $charset); 
     1154                // RFC recommends underline (instead of =20) in place of the space 
     1155                // that's one of the reasons why we're not using iconv_mime_encode() 
     1156                if ($char == ' ') { 
     1157                    $char = '_'; 
     1158                    $char_len = 1; 
     1159                } else { 
     1160                    $char = preg_replace_callback( 
     1161                        $regexp, array('Mail_mimePart', '_qpReplaceCallback'), $char 
     1162                    ); 
     1163                    $char_len = strlen($char); 
     1164                } 
     1165 
     1166                if ($line_length + $char_len > $maxLength) { 
     1167                    if ($result) { 
     1168                        $result .= "\n"; 
     1169                    } 
     1170                    $line_length = 0; 
     1171                } 
     1172 
     1173                $result      .= $char; 
     1174                $line_length += $char_len; 
     1175            } 
     1176        } 
     1177 
     1178        if ($result) { 
     1179            $result = $prefix 
     1180                .str_replace("\n", $suffix.$eol.' '.$prefix, $result).$suffix; 
     1181        } 
     1182 
     1183        return $result; 
     1184    } 
     1185 
     1186    /** 
    10831187     * Callback function to replace extended characters (\x80-xFF) with their 
    10841188     * ASCII values (RFC2047: quoted-printable) 
Note: See TracChangeset for help on using the changeset viewer.