Skip to content
Snippets Groups Projects
Commit 91275a65 authored by Andreas Gohr's avatar Andreas Gohr
Browse files

fix for quoted printable encoding

This patch replaces the old mail_quotedprintable_encode function with a
better one which makes sure to never split an encoded character. This also
makes sure mail headers aren't wrapped when quoting is needed.

darcs-hash:20060309182459-7ad00-0c442b5422e9727fc70d206f8e1bcd6281536573.gz
parent 21a15207
No related branches found
No related tags found
No related merge requests found
<?php
require_once DOKU_INC.'inc/mail.php';
class mail_quotedprintable_encode extends UnitTestCase {
function test_simple(){
$in = 'hello';
$out = 'hello';
$this->assertEqual(mail_quotedprintable_encode($in),$out);
}
function test_spaceend(){
$in = "hello \nhello";
$out = "hello=20\r\nhello";
$this->assertEqual(mail_quotedprintable_encode($in),$out);
}
function test_german_utf8(){
$in = 'hello überlänge';
$out = 'hello =C3=BCberl=C3=A4nge';
$this->assertEqual(mail_quotedprintable_encode($in),$out);
}
function test_wrap(){
$in = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
$out = "123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234=\r\n56789 123456789";
$this->assertEqual(mail_quotedprintable_encode($in,74),$out);
}
function test_nowrap(){
$in = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
$out = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
$this->assertEqual(mail_quotedprintable_encode($in,0),$out);
}
function test_russian_utf8(){
$in = 'Ваш пароль для системы Доку Вики';
$out = '=D0=92=D0=B0=D1=88 =D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D1=8C =D0=B4=D0=BB=D1=8F =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B =D0=94=D0=BE=D0=BA=D1=83 =D0=92=D0=B8=D0=BA=D0=B8';
$this->assertEqual(mail_quotedprintable_encode($in,0),$out);
}
}
//Setup VIM: ex: et ts=4 enc=utf-8 :
......@@ -38,7 +38,7 @@ function mail_send($to, $subject, $body, $from='', $cc='', $bcc='', $headers=nul
}
if(!utf8_isASCII($subject))
$subject = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject).'?=';
$subject = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject,0).'?=';
$header = '';
......@@ -119,7 +119,7 @@ function mail_encode_address($string,$header='',$names=true){
}
if(!utf8_isASCII($text)){
$text = '=?UTF-8?Q?'.mail_quotedprintable_encode($text).'?=';
$text = '=?UTF-8?Q?'.mail_quotedprintable_encode($text,0).'?=';
}
}else{
$text = '';
......@@ -155,52 +155,68 @@ function mail_isvalid($email){
/**
* Quoted printable encoding
*
* @author <pob@medienrecht.org>
* @author <tamas.tompa@kirowski.com>
* @link http://www.php.net/manual/en/function.quoted-printable-decode.php
* @author umu <umuAThrz.tu-chemnitz.de>
* @link http://www.php.net/manual/en/function.imap-8bit.php#61216
*/
function mail_quotedprintable_encode($input='',$line_max=74,$space_conv=false){
$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
$eol = "\n";
$escape = "=";
$output = "";
while( list(, $line) = each($lines) ) {
//$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
$linlen = strlen($line);
$newline = "";
for($i = 0; $i < $linlen; $i++) {
$c = substr( $line, $i, 1 );
$dec = ord( $c );
if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
$c = "=2E";
function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) {
// split text into lines
$aLines= preg_split("/(?:\r\n|\r|\n)/", $sText);
for ($i=0;$i<count($aLines);$i++) {
$sLine =& $aLines[$i];
if (strlen($sLine)===0) continue; // do nothing, if empty
$sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e';
// imap_8bit encodes x09 everywhere, not only at lineends,
// for EBCDIC safeness encode !"#$@[\]^`{|}~,
// for complete safeness encode every character :)
if ($bEmulate_imap_8bit)
$sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/e';
$sReplmt = 'sprintf( "=%02X", ord ( "$0" ) ) ;';
$sLine = preg_replace( $sRegExp, $sReplmt, $sLine );
// encode x09,x20 at lineends
{
$iLength = strlen($sLine);
$iLastChar = ord($sLine{$iLength-1});
// !!!!!!!!
// imap_8_bit does not encode x20 at the very end of a text,
// here is, where I don't agree with imap_8_bit,
// please correct me, if I'm wrong,
// or comment next line for RFC2045 conformance, if you like
if (!($bEmulate_imap_8bit && ($i==count($aLines)-1)))
if (($iLastChar==0x09)||($iLastChar==0x20)) {
$sLine{$iLength-1}='=';
$sLine .= ($iLastChar==0x09)?'09':'20';
}
if ( $dec == 32 ) {
if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
$c = "=20";
} else if ( $space_conv ) {
$c = "=20";
}
} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
$h2 = floor($dec/16);
$h1 = floor($dec%16);
$c = $escape.$hex["$h2"].$hex["$h1"];
}
if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
$newline = "";
// check if newline first character will be point or not
if ( $dec == 46 ) {
$c = "=2E";
}
}
$newline .= $c;
} // end of for
$output .= $newline.$eol;
} // end of while
return trim($output);
}
} // imap_8bit encodes x20 before chr(13), too
// although IMHO not requested by RFC2045, why not do it safer :)
// and why not encode any x20 around chr(10) or chr(13)
if ($bEmulate_imap_8bit) {
$sLine=str_replace(' =0D','=20=0D',$sLine);
//$sLine=str_replace(' =0A','=20=0A',$sLine);
//$sLine=str_replace('=0D ','=0D=20',$sLine);
//$sLine=str_replace('=0A ','=0A=20',$sLine);
}
// finally split into softlines no longer than $maxlen chars,
// for even more safeness one could encode x09,x20
// at the very first character of the line
// and after soft linebreaks, as well,
// but this wouldn't be caught by such an easy RegExp
if($maxlen){
preg_match_all( '/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch );
$sLine = implode( '=' . chr(13).chr(10), $aMatch[0] ); // add soft crlf's
}
}
// join lines into text
return implode(chr(13).chr(10),$aLines);
}
//Setup VIM: ex: et ts=2 enc=utf-8 :
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment