Fix Q-encoding for strings containing '=', fixes #91

This commit is contained in:
Synchro 2013-08-01 09:55:26 +02:00
parent 812985886e
commit 331d24bc82
2 changed files with 26 additions and 14 deletions

View File

@ -1687,7 +1687,7 @@ class PHPMailer
/**
* Returns the whole MIME message.
* Includes complete headers and body.
* Only valid post preSend().
* Only valid post PreSend().
* @see PHPMailer::PreSend()
* @access public
* @return string
@ -2353,22 +2353,31 @@ class PHPMailer
$encoded = str_replace(array("\r", "\n"), '', $str);
switch (strtolower($position)) {
case 'phrase':
//RFC 2047 section 5.3
$pattern = '^A-Za-z0-9!*+\/ -';
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 'comment':
//RFC 2047 section 5.2
$pattern = '\(\)"';
//intentional fall-through
//for this reason we build the $pattern without including delimiters and []
case 'text':
default:
//Replace every high ascii, control =, ? and _ characters
//We put \075 (=) as first value to make sure it's the first one
//in being converted, preventing double encode
$pattern = '\075\000-\011\013\014\016-\037\077\137\177-\377' . $pattern;
//RFC 2047 section 5.1
//Replace every high ascii, control, =, ? and _ characters
$pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
break;
}
$matches = array();
if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
//If the string contains an '=', make sure it's the first thing we replace
//so as to avoid double-encoding
$s = array_search('=', $matches[0]);
if ($s !== false) {
unset($matches[0][$s]);
array_unshift($matches[0], '=');
}
foreach (array_unique($matches[0]) as $char) {
$encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
}

View File

@ -27,33 +27,34 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
/**
* Holds the default phpmailer instance.
* @private
* @var PHPMailer
* @type PHPMailer
*/
public $Mail;
/**
* Holds the SMTP mail host.
* @public
* @var string
* @type string
*/
public $Host = '';
/**
* Holds the change log.
* @private
* @var string[]
* @type string[]
*/
public $ChangeLog = array();
/**
* Holds the note log.
* @private
* @var string[]
* @type string[]
*/
public $NoteLog = array();
/**
* @var string Default include path
* Default include path
* @type string
*/
public $INCLUDE_DIR = '../';
@ -65,9 +66,7 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
if (file_exists('./testbootstrap.php')) {
include './testbootstrap.php'; //Overrides go in here
}
//require_once $this->INCLUDE_DIR . 'class.phpmailer.php';
$this->Mail = new PHPMailer;
$this->Mail->Priority = 3;
$this->Mail->Encoding = '8bit';
$this->Mail->CharSet = 'iso-8859-1';
@ -99,14 +98,12 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
$this->Mail->PluginDir = $this->INCLUDE_DIR;
$this->Mail->addReplyTo('no_reply@phpmailer.example.com', 'Reply Guy');
$this->Mail->Sender = 'unit_test@phpmailer.example.com';
if (strlen($this->Mail->Host) > 0) {
$this->Mail->Mailer = 'smtp';
} else {
$this->Mail->Mailer = 'mail';
$this->Mail->Sender = 'unit_test@phpmailer.example.com';
}
if (array_key_exists('mail_to', $_REQUEST)) {
$this->setAddress($_REQUEST['mail_to'], 'Test User', 'to');
}
@ -1165,6 +1162,12 @@ EOT;
$this->Mail->encodeQ("\xc2\xa1Hola! Se\xc3\xb1or!", 'text'),
'Q Encoding (text) failed'
);
//Strings containing '=' are a special case
$this->assertEquals(
'Nov=C3=A1=3D',
$this->Mail->encodeQ("Nov\xc3\xa1=", 'text'),
'Q Encoding (text) failed 2'
);
}
/**