Skip to content

Commit

Permalink
Merge pull request #25 from danielabyan/feature/fold-header-properly
Browse files Browse the repository at this point in the history
Fold a header line with the correct length
  • Loading branch information
Ocramius authored Aug 30, 2022
2 parents 37802ff + 0ff5f9b commit 62a899a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 16 deletions.
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
"forum": "https://discourse.laminas.dev"
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"require": {
"php": "^7.3 || ~8.0.0 || ~8.1.0",
Expand All @@ -25,7 +28,7 @@
"require-dev": {
"laminas/laminas-coding-standard": "~2.2.1",
"laminas/laminas-mail": "^2.12",
"phpunit/phpunit": "^9.3"
"phpunit/phpunit": "^9.5"
},
"suggest": {
"laminas/laminas-mail": "Laminas\\Mail component"
Expand Down
10 changes: 5 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 18 additions & 6 deletions src/Mime.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,17 +491,22 @@ private static function _encodeQuotedPrintable($str)
* Mail headers depend on an extended quoted printable algorithm otherwise
* a range of bugs can occur.
*
* @param string $str
* @param string $charset
* @param int $lineLength Defaults to {@link LINELENGTH}
* @param string $lineEnd Defaults to {@link LINEEND}
* @param string $str
* @param string $charset
* @param int $lineLength Defaults to {@link LINELENGTH}
* @param string $lineEnd Defaults to {@link LINEEND}
* @param positive-int|0 $headerNameSize When folding a line, it is necessary to calculate
* the length of the entire line (together with the header name).
* Therefore, you can specify the header name and colon length
* in this argument to fold the string properly.
* @return string
*/
public static function encodeQuotedPrintableHeader(
$str,
$charset,
$lineLength = self::LINELENGTH,
$lineEnd = self::LINEEND
$lineEnd = self::LINEEND,
$headerNameSize = 0
) {
// Reduce line-length by the length of the required delimiter, charsets and encoding
$prefix = sprintf('=?%s?Q?', $charset);
Expand All @@ -527,7 +532,14 @@ public static function encodeQuotedPrintableHeader(
if ($token === '=20') {
// only if we have a single char token or space, we can append the
// tempstring it to the current line or start a new line if necessary.
$lineLimitReached = strlen($lines[$currentLine] . $tmp) > $lineLength;
if ($currentLine === 0) {
// The size of the first line should be calculated with the header name.
$currentLineLength = strlen($lines[$currentLine] . $tmp) + $headerNameSize;
} else {
$currentLineLength = strlen($lines[$currentLine] . $tmp);
}

$lineLimitReached = $currentLineLength > $lineLength;
$noCurrentLine = $lines[$currentLine] === '';
if ($noCurrentLine && $lineLimitReached) {
$lines[$currentLine] = $tmp;
Expand Down
51 changes: 48 additions & 3 deletions test/MimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,53 @@ public static function dataTestEncodeMailHeaderQuotedPrintable(): array
// phpcs:enable
}

/**
* @dataProvider dataTestEncodeMailHeaderQuotedPrintableWithHeaderName
*/
public function testEncodeMailHeaderQuotedPrintableWithHeaderName(
string $str,
string $charset,
string $expectedResult,
int $headerLength
): void {
$actualResult = Mime\Mime::encodeQuotedPrintableHeader($str, $charset, 78, Mime\Mime::LINEEND, $headerLength);
$this->assertEquals($expectedResult, $actualResult);
}

/** @psalm-return array<array-key, array{0: string, 1: string, 2: string, 3: int}> */
public static function dataTestEncodeMailHeaderQuotedPrintableWithHeaderName(): array
{
return [
'long string with header name size' => [
"xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx",
"UTF-8",
"=?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20?=" . Mime\Mime::LINEEND
. " =?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx?=",
9,
],
'long string without header name size' => [
"xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx",
"UTF-8",
"=?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20?=" . Mime\Mime::LINEEND
. " =?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx?=",
0,
],
'short string with header name size' => [
"xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx",
"UTF-8",
"=?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20?=" . Mime\Mime::LINEEND
. " =?UTF-8?Q?xxxxx=20xxxxx=20xxxxx?=",
11,
],
'short string without header name size' => [
"xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx",
"UTF-8",
"=?UTF-8?Q?xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx=20xxxxx?=",
11,
],
];
}

/**
* @group Laminas-1688
* @dataProvider dataTestEncodeMailHeaderBase64
Expand All @@ -170,9 +217,7 @@ public static function dataTestEncodeMailHeaderBase64(): array
[
"Alle meine Entchen schwimmen in dem See, schwimmen in dem See, Köpfchen in das Wasser, Schwänzchen in die Höh!",
"UTF-8",
"=?UTF-8?B?QWxsZSBtZWluZSBFbnRjaGVuIHNjaHdpbW1lbiBpbiBkZW0gU2VlLCBzY2h3?=
=?UTF-8?B?aW1tZW4gaW4gZGVtIFNlZSwgS8O2cGZjaGVuIGluIGRhcyBXYXNzZXIsIFNj?=
=?UTF-8?B?aHfDpG56Y2hlbiBpbiBkaWUgSMO2aCE=?=",
"=?UTF-8?B?QWxsZSBtZWluZSBFbnRjaGVuIHNjaHdpbW1lbiBpbiBkZW0gU2VlLCBzY2h3?=\n =?UTF-8?B?aW1tZW4gaW4gZGVtIFNlZSwgS8O2cGZjaGVuIGluIGRhcyBXYXNzZXIsIFNj?=\n =?UTF-8?B?aHfDpG56Y2hlbiBpbiBkaWUgSMO2aCE=?=",
],
];
// phpcs:enable
Expand Down

0 comments on commit 62a899a

Please sign in to comment.