From 51f688bd46ab796a5a817d5806e880b3147c61da Mon Sep 17 00:00:00 2001 From: Martin Raenker Date: Wed, 14 Dec 2022 08:47:51 +0100 Subject: [PATCH 1/8] =?UTF-8?q?=20N=C2=B04281=20-=20"Content=20Type"=20and?= =?UTF-8?q?=20"Content=20Disposition"=20RFC=202045-compliant=20for=20"name?= =?UTF-8?q?"=20and=20"filename"=20attributes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- classes/rawemailmessage.class.inc.php | 33 ++++--- ..._without_quotes_around_attachment_name.eml | 97 +++++++++++++++++++ 2 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 test/emailsSample/email_with_and_without_quotes_around_attachment_name.eml diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 9fa5a1f..41c6eb1 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -172,6 +172,21 @@ public function GetMessageId() */ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1) { + // This Regex complies with RFC 2045 regarding the Grammar of Content Type Headers Filenames: + // (1) Allow all chars for the filename, if the filename is quoted with double quotes + // (2) Allow all chars for the filename, if the filename is quoted with single quotes + // (3) If the filename is not quoted, allow only ASCII chars and exclude the following + // chars from the set, referenced as "tspecials" in the RFC: + // + // + // ()<>@,;:\"/[]?= + // To keep the regex as simple as possible, the _allowed_ chars are whitelisted + // with their corresponding hexval. + $sFileNameRegex = <<GetHeader('content-disposition', $aPart['headers']); - if (($sContentDisposition != '') && (preg_match('/filename="([^"]+)"/', $sContentDisposition, $aMatches))) + if (($sContentDisposition != '') && (preg_match('/filename='.$sFileNameRegex.'/', $sContentDisposition, $aMatches))) { - $sFileName = $aMatches[1]; - } - else - { - if (($sContentDisposition != '') && (preg_match('/filename=([^"]+)/', $sContentDisposition, $aMatches))) // same but without quotes - { - $sFileName = $aMatches[1]; - } + $sFileName = end($aMatches); } $bInline = true; @@ -223,10 +231,13 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 { $sType = $aMatches[1]; } - if (empty($sFileName) && preg_match('/name="([^"]+)"/', $sContentType, $aMatches)) + if (empty($sFileName) && preg_match('/name='.$sFileNameRegex.'/', $sContentType, $aMatches)) { - $sFileName = $aMatches[1]; + $sFileName = end($aMatches); } + + $sFileName = trim($sFileName, '"\''); + if (empty($sFileName)) { // generate a name based on the type of the file... diff --git a/test/emailsSample/email_with_and_without_quotes_around_attachment_name.eml b/test/emailsSample/email_with_and_without_quotes_around_attachment_name.eml new file mode 100644 index 0000000..6dd4f06 --- /dev/null +++ b/test/emailsSample/email_with_and_without_quotes_around_attachment_name.eml @@ -0,0 +1,97 @@ +Return-Path: +Received: from www192.your-server.de + by www192.your-server.de with LMTP + id cANPJDAmYmNaVQEAUXDXKw + (envelope-from ); Wed, 02 Nov 2022 09:11:28 +0100 +Envelope-to: martin.raenker@itomig.de +Delivery-date: Wed, 02 Nov 2022 09:11:28 +0100 +Authentication-Results: www192.your-server.de; + iprev=pass (localhost) smtp.remote-ip=127.0.0.1; + spf=pass smtp.mailfrom=itomig.de; + dkim=pass header.d=itomig.de header.s=default2012 header.a=rsa-sha256; + dmarc=skipped +Received: from localhost ([127.0.0.1] helo=www192.your-server.de) + by www192.your-server.de with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 + (Exim 4.94.2) + (envelope-from ) + id 1oq8qO-000NG0-7r + for martin.raenker@itomig.de; Wed, 02 Nov 2022 09:11:28 +0100 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=itomig.de; + s=default2012; h=Subject:From:To:MIME-Version:Date:Message-ID:Content-Type: + Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + In-Reply-To:References; bh=qfsa/c5xPqZ3d+6wNfzUExTW0ZNkPkALI3o0hp2R85A=; b=r5 + zbg+7XSo/HBfaFAqqdBD0gDiOIa8ujhqmikWoXps5jf9oMJVJ6af5ynLdfZPbxkpWss5t6os7LhO/ + w/ZdvjR8sOpvIX5nkR3DJxnG76Z28p0aFtpBz1OSIXpWe7LmSj8mBwsXBuh6jTLLH2xRGY3gBEIU9 + fkOlRbJQ6lU3qhS9Xa9cgSGECPfhIvZzdM/Rb0vdvvERCmrpvr9TylqFb+3RA05pQJBOvG3i/ih7O + 5a9RytEsd5rpN1IabPoMV6UJFhKaxPY4hMG4qdgzI2GQZAcoK5kNm/IrUxeHQ8KLy5HigJ1I11e9e + kzqzy6hT0ZKrELFcqh6Y8L6EzgtC+aOg==; +Received: from [95.90.147.54] (helo=[192.168.0.103]) + by www192.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 + (Exim 4.94.2) + (envelope-from ) + id 1oq8qO-000NFs-3t + for martin.raenker@itomig.de; Wed, 02 Nov 2022 09:11:28 +0100 +Content-Type: multipart/mixed; boundary="------------8PrwbWLJ6Ep94lElB18RfVAR" +Message-ID: <2525d616-c82b-fa1e-05c6-065e9f91f46d@itomig.de> +Date: Wed, 2 Nov 2022 09:11:25 +0100 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.2.2 +Content-Language: en-US +To: martin.raenker@itomig.de +From: Martin Raenker +Subject: test for attachments with unquoted name +X-Authenticated-Sender: martin.raenker@itomig.de +X-Virus-Scanned: Clear (ClamAV 0.103.7/26707/Tue Nov 1 21:23:26 2022) +X-local-sign: yes +X-DKIM-Status: pass [(itomig.de) - 127.0.0.1] +Delivered-To: itomig-martin.raenker@itomig.de + +This is a multi-part message in MIME format. +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: 7bit + +testbody +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; name="example_attachment_mail.csv" +Content-Disposition: attachment; +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= + +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; name='example_attachment_mail.csv' +Content-Disposition: attachment; +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= + +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; name=example_attachment_mail.csv +Content-Disposition: attachment; +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= + +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; +Content-Disposition: attachment; filename="example_attachment_mail.csv" +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= + +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; +Content-Disposition: attachment; filename='example_attachment_mail.csv' +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= + +--------------8PrwbWLJ6Ep94lElB18RfVAR +Content-Type: application/octet-stream; charset=UTF-8; +Content-Disposition: attachment; filename=example_attachment_mail.csv +Content-Transfer-Encoding: base64 + +InRlc3QiLCJ0b3N0Igo= From ed5577fbde03256345dbc8b6699156ef76c32c23 Mon Sep 17 00:00:00 2001 From: mraenker Date: Wed, 14 Dec 2022 09:14:13 +0100 Subject: [PATCH 2/8] Remove trim() before the final results, as it is not necessary anymore. Co-authored-by: Thomas Casteleyn --- classes/rawemailmessage.class.inc.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 41c6eb1..7b10110 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -236,8 +236,6 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 $sFileName = end($aMatches); } - $sFileName = trim($sFileName, '"\''); - if (empty($sFileName)) { // generate a name based on the type of the file... From 81bd7fe297f8b78ad2633d494fc4f2cb4e2dd853 Mon Sep 17 00:00:00 2001 From: mraenker Date: Thu, 15 Dec 2022 08:41:47 +0100 Subject: [PATCH 3/8] Remove redundant part of comment Co-authored-by: Molkobain --- classes/rawemailmessage.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 7b10110..3f20b36 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -180,7 +180,7 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 // // // ()<>@,;:\"/[]?= - // To keep the regex as simple as possible, the _allowed_ chars are whitelisted + // To keep the regex as simple as possible, the _allowed_ chars are listed // with their corresponding hexval. $sFileNameRegex = << Date: Wed, 11 Jan 2023 18:53:39 +0100 Subject: [PATCH 4/8] Moved the Regex into a class var + Testcases Please note the comment in TestRegexAttachmentNames.php:55. Could you please have a look, if you've got any idea, why this is happening? --- classes/rawemailmessage.class.inc.php | 37 ++++++------ test/TestRegexAttachmentNames.php | 86 +++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 test/TestRegexAttachmentNames.php diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 3f20b36..19d960a 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -66,6 +66,23 @@ class RawEmailMessage */ protected $iNextId; + /** + * @var string This Regex complies with RFC 2045 regarding the Grammar of + * Content Type Headers Filenames: + * (1) Allow all chars for the filename, if the filename is quoted with double quotes + * (2) Allow all chars for the filename, if the filename is quoted with single quotes + * (3) If the filename is not quoted, allow only ASCII chars and exclude the following + * chars from the set, referenced as "tspecials" in the RFC: + * + * + * ()<>@,;:\"/[]?= + * To keep the regex as simple as possible, the _allowed_ chars are listed + * with their corresponding hexval. + */ + public static $sFileNameRegex = << - // - // ()<>@,;:\"/[]?= - // To keep the regex as simple as possible, the _allowed_ chars are listed - // with their corresponding hexval. - $sFileNameRegex = <<GetHeader('content-disposition', $aPart['headers']); - if (($sContentDisposition != '') && (preg_match('/filename='.$sFileNameRegex.'/', $sContentDisposition, $aMatches))) + if (($sContentDisposition != '') && (preg_match('/filename='.self::$sFileNameRegex.'/', $sContentDisposition, $aMatches))) { $sFileName = end($aMatches); } @@ -214,7 +216,6 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 $bInline = false; } - $sType = ''; $sContentId = $this->GetHeader('content-id', $aPart['headers']); if (($sContentId != '') && (preg_match('/^<(.+)>$/', $sContentId, $aMatches))) @@ -231,7 +232,7 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 { $sType = $aMatches[1]; } - if (empty($sFileName) && preg_match('/name='.$sFileNameRegex.'/', $sContentType, $aMatches)) + if (empty($sFileName) && preg_match('/name='.self::$sFileNameRegex.'/', $sContentType, $aMatches)) { $sFileName = end($aMatches); } diff --git a/test/TestRegexAttachmentNames.php b/test/TestRegexAttachmentNames.php new file mode 100644 index 0000000..3212ba1 --- /dev/null +++ b/test/TestRegexAttachmentNames.php @@ -0,0 +1,86 @@ +assertEquals($sExpectedAttachmentName, $sNormalizedAttachmentName, "Attachmentname for '".bin2hex($sInput)."' doesn't match. Got'".bin2hex($sNormalizedAttachmentName)."', expected '$sExpectedAttachmentName'."); + } + else + { + $this->AssertNull($sNormalizedAttachmentName); + } + } + + public function AttachmentFilenameProvider() + { + return [ + 'All allowed Chars' => [ + "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~", + "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~", + ], + // Something is odd here: x2C (comma) is not in the list of allowed + // chars in RawEmailMessage::$sFileNameRegex, but nevertheless is + // not filtered by the Regex, resulting in this test case is failing. + // I have no clue, as to why this is happening. + 'All not allowed Chars (from the ASCII Table)' => [ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x17\x18\x19\x1A\x1B\x1C\x1E\x1F\x20\x22\x28\x29\x2C\x2F\x3A\x3B\x3C\x3D\x3E\x3F\x40\x5B\x5C\x5D\x7F", + "", + ], + 'Single Quotes delimit filename' => [ + "'End 'before'", + "End ", + ], + 'Double Quotes delimit filename' => [ + '"End "before"', + 'End ', + ], + 'Empty String' => [ + '', + '', + ], + 'Name with a Space' => [ + 'OQL Queries', + 'OQL', + ], + // Same problem as in test for not allowed chars: The comma somehow slips through. + 'Name with a Comma' => [ + 'OQL,Queries', + 'OQL', + ], + ]; + } +} From 610c2f379d57725f2cdbed2406d54c04759e6b16 Mon Sep 17 00:00:00 2001 From: mraenker Date: Thu, 12 Jan 2023 10:47:06 +0100 Subject: [PATCH 5/8] Change Namespace in test/TestRegexAttachmentNames.php Co-authored-by: Molkobain --- test/TestRegexAttachmentNames.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestRegexAttachmentNames.php b/test/TestRegexAttachmentNames.php index 3212ba1..d74ce10 100644 --- a/test/TestRegexAttachmentNames.php +++ b/test/TestRegexAttachmentNames.php @@ -5,7 +5,7 @@ */ -namespace Combodo\iTop\Test\UnitTest\CombodoEmailSynchro; +namespace Combodo\iTop\Test\UnitTest\Module\CombodoEmailSynchro; use Combodo\iTop\Test\UnitTest\ItopTestCase; use RawEmailMessage; From f0521eb71b4c9ec2f7c39a182a4afeafa209fc57 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Fri, 3 Feb 2023 18:17:05 +0100 Subject: [PATCH 6/8] Regex is now a const, and its uses are factorized in a dedicated method --- classes/rawemailmessage.class.inc.php | 110 ++++++++++++++------------ test/TestRegexAttachmentNames.php | 9 +-- 2 files changed, 62 insertions(+), 57 deletions(-) diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 19d960a..bddfc7d 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -67,19 +67,21 @@ class RawEmailMessage protected $iNextId; /** - * @var string This Regex complies with RFC 2045 regarding the Grammar of + * @var string This Regex complies with RFC 2045 regarding the Grammar of * Content Type Headers Filenames: - * (1) Allow all chars for the filename, if the filename is quoted with double quotes - * (2) Allow all chars for the filename, if the filename is quoted with single quotes - * (3) If the filename is not quoted, allow only ASCII chars and exclude the following - * chars from the set, referenced as "tspecials" in the RFC: - * - * - * ()<>@,;:\"/[]?= - * To keep the regex as simple as possible, the _allowed_ chars are listed - * with their corresponding hexval. - */ - public static $sFileNameRegex = << + * + * ()<>@,;:\"/[]?= + * To keep the regex as simple as possible, the _allowed_ chars are listed + * with their corresponding hexval. + * + * @since 3.7.1 N°4281 + */ + public const FILENAME_REGEX = <<aParts; } //Init for recursion - if ($aPart['type'] == 'simple') - { - if ($this->IsAttachment($aPart['headers'])) - { - $sFileName = ''; + if ($aPart['type'] == 'simple') { + if ($this->IsAttachment($aPart['headers'])) { + $sFileName = ''; $sContentDisposition = $this->GetHeader('content-disposition', $aPart['headers']); - if (($sContentDisposition != '') && (preg_match('/filename='.self::$sFileNameRegex.'/', $sContentDisposition, $aMatches))) - { - $sFileName = end($aMatches); + if ($sContentDisposition != '') { + $sFileName = static::GetAttachmentFilename($sContentDisposition); } $bInline = true; - if (stripos($sContentDisposition, 'attachment;') !== false) - { + if (stripos($sContentDisposition, 'attachment;') !== false) { $bInline = false; } - $sType = ''; + $sType = ''; $sContentId = $this->GetHeader('content-id', $aPart['headers']); - if (($sContentId != '') && (preg_match('/^<(.+)>$/', $sContentId, $aMatches))) - { + if (($sContentId != '') && (preg_match('/^<(.+)>$/', $sContentId, $aMatches))) { $sContentId = $aMatches[1]; - } - else - { + } else { $sContentId = 'itop_'.$iAttachmentCount; $iAttachmentCount++; } $sContentType = $this->GetHeader('content-type', $aPart['headers']); - if (($sContentType != '') && (preg_match('/^([^;]+)/', $sContentType, $aMatches))) - { + if (($sContentType != '') && (preg_match('/^([^;]+)/', $sContentType, $aMatches))) { $sType = $aMatches[1]; } - if (empty($sFileName) && preg_match('/name='.self::$sFileNameRegex.'/', $sContentType, $aMatches)) - { - $sFileName = end($aMatches); + if (empty($sFileName)) { + $sContentTypeFilename = static::GetAttachmentFilename($sContentType); + if ($sContentTypeFilename !== '') { + $sFileName = $sContentTypeFilename; + } } - if (empty($sFileName)) - { + if (empty($sFileName)) { // generate a name based on the type of the file... - $aTypes = explode('/', $sType); + $aTypes = explode('/', $sType); $sFileExtension = $aTypes[1]; // map the type to a useful extension if needed - switch ($aTypes[1]) - { + switch ($aTypes[1]) { case 'rfc822': // Special case for messages: use the .eml extension $sFileExtension = 'eml'; @@ -253,18 +245,15 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 $sFileName = sprintf('%s%03d.%s', $aTypes[0], $index, $sFileExtension); // i.e. image001.jpg } $aAttachments['part_'.$aPart['part_id']] = array( - 'filename' => $sFileName, - 'mimeType' => $sType, + 'filename' => $sFileName, + 'mimeType' => $sType, 'content-id' => $sContentId, - 'content' => $this->DecodePart($aPart['headers'], $aPart['body']), - 'inline' => $bInline, + 'content' => $this->DecodePart($aPart['headers'], $aPart['body']), + 'inline' => $bInline, ); } - } - else - { - foreach ($aPart['parts'] as $aSubPart) - { + } else { + foreach ($aPart['parts'] as $aSubPart) { $aAttachments = array_merge($aAttachments, $this->GetAttachments($aAttachments, $aSubPart, $index)); } } @@ -272,6 +261,25 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 return $aAttachments; } + /** + * Allow to handle RFC 2045 filename syntax in attachments + * + * @param string $sHeaderValue + * + * @return string empty string if none found + * @uses static::FILENAME_REGEX + * + * @since 3.7.1 N°4281 + */ + public static function GetAttachmentFilename($sHeaderValue) + { + if (preg_match('/name='.static::FILENAME_REGEX.'/', $sHeaderValue, $aMatches)) { + return end($aMatches); + } + + return ''; + } + /** * Create a new RawEmailMessage object by reading the content of the given file * diff --git a/test/TestRegexAttachmentNames.php b/test/TestRegexAttachmentNames.php index d74ce10..198c2a9 100644 --- a/test/TestRegexAttachmentNames.php +++ b/test/TestRegexAttachmentNames.php @@ -34,13 +34,10 @@ public function testNormalizeAttachmentName(string $sInput, string $sExpectedAtt { $aMatches = array(); $sNormalizedAttachmentName = null; - if (preg_match(RawEmailMessage::$sFileNameRegex, $sInput, $aMatches)) - { + if (preg_match(RawEmailMessage::FILENAME_REGEX, $sInput, $aMatches)) { $sNormalizedAttachmentName = end($aMatches); $this->assertEquals($sExpectedAttachmentName, $sNormalizedAttachmentName, "Attachmentname for '".bin2hex($sInput)."' doesn't match. Got'".bin2hex($sNormalizedAttachmentName)."', expected '$sExpectedAttachmentName'."); - } - else - { + } else { $this->AssertNull($sNormalizedAttachmentName); } } @@ -53,7 +50,7 @@ public function AttachmentFilenameProvider() "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~", ], // Something is odd here: x2C (comma) is not in the list of allowed - // chars in RawEmailMessage::$sFileNameRegex, but nevertheless is + // chars in {@see RawEmailMessage::FILENAME_REGEX}, but nevertheless is // not filtered by the Regex, resulting in this test case is failing. // I have no clue, as to why this is happening. 'All not allowed Chars (from the ASCII Table)' => [ From 541bf573560ec63843ff8f92f893b3a37a390440 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 6 Feb 2023 16:35:47 +0100 Subject: [PATCH 7/8] :art: Fix formatting --- classes/rawemailmessage.class.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index 858ad22..bdc9bfd 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -201,7 +201,7 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 if ($aPart['type'] == 'simple') { if ($this->IsAttachment($aPart['headers'])) { - $sFileName = ''; + $sFileName = ''; $sContentDisposition = $this->GetHeader('content-disposition', $aPart['headers']); if ($sContentDisposition != '') { $sFileName = static::GetAttachmentFilename($sContentDisposition); @@ -212,7 +212,7 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 $bInline = false; } - $sType = ''; + $sType = ''; $sContentId = $this->GetHeader('content-id', $aPart['headers']); if (($sContentId != '') && (preg_match('/^<(.+)>$/', $sContentId, $aMatches))) { $sContentId = $aMatches[1]; From 3158cf5797673274e8c61f4162424046f5257c25 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 7 Feb 2023 09:56:09 +0100 Subject: [PATCH 8/8] :art: Fix formatting again --- classes/rawemailmessage.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/rawemailmessage.class.inc.php b/classes/rawemailmessage.class.inc.php index bdc9bfd..b4ff3e5 100644 --- a/classes/rawemailmessage.class.inc.php +++ b/classes/rawemailmessage.class.inc.php @@ -233,7 +233,7 @@ public function GetAttachments(&$aAttachments = null, $aPart = null, &$index = 1 if (empty($sFileName)) { // generate a name based on the type of the file... - $aTypes = explode('/', $sType); + $aTypes = explode('/', $sType); $sFileExtension = $aTypes[1]; // map the type to a useful extension if needed switch ($aTypes[1]) {