Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 44ce633

Browse files
committed
fix headers encoding and fix removed dot on smtp
1 parent 16ae197 commit 44ce633

File tree

2 files changed

+106
-32
lines changed

2 files changed

+106
-32
lines changed

‎src/Message.php‎

Lines changed: 101 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -939,44 +939,43 @@ private function encodeHeader($header, $value)
939939
{
940940
$max = 74;
941941
$offset = strlen($header) + 2;
942-
$symbols = str_split($value);
942+
$letters = mb_str_split($value);
943+
$hasOptions = preg_match('/;(\s+)?([a-z0-9\-]+)(\s+)?(=(\s+)?\"[^\"]+)?/ui', $value);
943944
unset($value);
944945
$result = $header . ': ';
945946
$coding = false;
946-
$all = count($symbols);
947+
$all = count($letters);
947948
$position = $offset;
948-
foreach ($symbols as $num => $symbol) {
949+
foreach ($letters as $num => $letter) {
949950
$line = '';
950-
$add = 0;
951-
$char = ord($symbol);
952-
$ascii = ($char >= 32 && $char <= 60) || ($char >= 62 && $char <= 126);
953-
if ($char === 32 && $num + 1 === $all) {
954-
$ascii = false;
955-
}
956-
if (!$coding && $char === 61 && preg_match('/;(\s+)?([a-z0-9\-]+)(\s+)?(=(\s+)?\"[^\"]+)?/ui', $result)) {
957-
$ascii = true;
958-
}
959-
if ($coding && $symbol === '') {
960-
$ascii = false;
961-
}
962-
if ($ascii) {
963-
if ($coding) {
964-
$coding = false;
965-
$line = '?=' . $symbol;
966-
$add = 3;
967-
} else {
968-
$line = $symbol;
969-
$add = 1;
970-
}
951+
/**
952+
* @var string $char
953+
* @var bool $encoded
954+
*/
955+
956+
if (!$coding && $letter === '=' && $hasOptions) {
957+
$char = '=';
958+
$encoded = false;
971959
} else {
960+
list($char, $encoded) = $this->encodeLetter($letter, $num, $all, $coding);
961+
}
962+
963+
if ($encoded) {
972964
if (!$coding) {
973965
$coding = true;
974966
$line = '=?utf-8?Q?';
975-
$add = 10;
976967
}
977-
$line .= $this->map[$char];
978-
$add += 3;
968+
$line .= $char;
969+
} else {
970+
if ($coding) {
971+
$coding = false;
972+
$line = '?=' . $char;
973+
} else {
974+
$line = $char;
975+
}
979976
}
977+
$add = strlen($line);
978+
980979
if ($position + $add >= $max) {
981980
if ($coding) {
982981
$line = "?=\r\n =?utf-8?Q?$line";
@@ -996,16 +995,87 @@ private function encodeHeader($header, $value)
996995
}
997996
$result .= $line;
998997
}
999-
return $result;
998+
return str_replace(
999+
array("\t\r\n", "\r\n"),
1000+
array("=09\r\n", "=20\r\n"),
1001+
$result
1002+
);
1003+
}
1004+
1005+
/**
1006+
* @param string $letter
1007+
* @param int $position
1008+
* @param int $length
1009+
* @return array
1010+
*/
1011+
private function encodeLetter($letter, $position, $length, $coding)
1012+
{
1013+
$result = '';
1014+
if ($letter === '' && $coding) {
1015+
return array($this->encodeSymbol($letter, true), true);
1016+
}
1017+
$isNeedEncode = (strlen($letter) > 1);
1018+
$symbols = str_split($letter);
1019+
foreach ($symbols as $symbol) {
1020+
if ($this->isNeedEncode($symbol, $position, $length)) {
1021+
$isNeedEncode = true;
1022+
}
1023+
}
1024+
foreach ($symbols as $symbol) {
1025+
$result .= $this->encodeSymbol($symbol, $isNeedEncode);
1026+
}
1027+
return array($result, $isNeedEncode);
1028+
}
1029+
1030+
/**
1031+
* @param string$symbol
1032+
* @param int $position
1033+
* @param int $length
1034+
* @return bool
1035+
*/
1036+
private function isNeedEncode($symbol, $position, $length)
1037+
{
1038+
$char = ord($symbol);
1039+
$isNeedEncode = !($char === 9 || ($char >= 32 && $char <= 60) || ($char >= 62 && $char <= 126));
1040+
if ((in_array($char, array(9, 20, 32)) && $position + 1 === $length)) {
1041+
$isNeedEncode = true;
1042+
}
1043+
return $isNeedEncode;
10001044
}
10011045

10021046
/**
1003-
* @param string $data
1047+
* @param string $symbol
1048+
* @param bool $isNeedEncode
10041049
* @return string
10051050
*/
1006-
private function encodeBody($data)
1051+
private function encodeSymbol($symbol, $isNeedEncode)
10071052
{
1008-
return quoted_printable_encode($data);
1053+
$char = ord($symbol);
1054+
1055+
if ($isNeedEncode) {
1056+
return $this->map[$char];
1057+
}
1058+
return $symbol;
1059+
}
1060+
1061+
/**
1062+
* @param string $string
1063+
* @return string
1064+
*/
1065+
private function encodeBody($string)
1066+
{
1067+
$string = quoted_printable_encode($string);
1068+
$string = str_replace(
1069+
array("\t\r\n", "\r\n"),
1070+
array("=09\r\n", "=20\r\n"),
1071+
$string
1072+
);
1073+
$last = ord(substr($string, -1));
1074+
if (in_array($last, array(9, 20))) {
1075+
$string = substr_replace($string, sprintf('=%\'.02d', $last), -1);
1076+
}
1077+
1078+
return $string;
10091079
}
10101080

10111081
/**

‎src/Transport/SmtpTransport.php‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,11 @@ public function send(Message $message)
174174
$this->smtpCommand('RCPT TO: <' . $address . '>');
175175
}
176176
$this->smtpCommand('DATA');
177-
$data = $message->getHeadersRaw() . "\r\n\r\n" . $message->getBodyRaw() . "\r\n.\r\n";
177+
$data = $message->getHeadersRaw()
178+
. "\r\n\r\n"
179+
. str_replace("\r\n.", "\r\n..", $message->getBodyRaw())
180+
. "\r\n.\r\n"
181+
;
178182
$this->smtpCommand($data);
179183
return true;
180184
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /