Browse Source

Merge pull request #2565 from Howaner/mailpreview-fix

Updated php-mime-mail-parser library to 5.0 to fix webui html preview
André Peters 6 years ago
parent
commit
5cc6f68928

+ 1 - 1
data/web/inc/lib/composer.json

@@ -3,7 +3,7 @@
         "robthree/twofactorauth": "^1.6",
         "robthree/twofactorauth": "^1.6",
         "yubico/u2flib-server": "^1.0",
         "yubico/u2flib-server": "^1.0",
         "phpmailer/phpmailer": "^5.2",
         "phpmailer/phpmailer": "^5.2",
-        "php-mime-mail-parser/php-mime-mail-parser": "^2.9",
+        "php-mime-mail-parser/php-mime-mail-parser": "^5.0",
         "soundasleep/html2text": "^0.5.0",
         "soundasleep/html2text": "^0.5.0",
         "ddeboer/imap": "^1.5",
         "ddeboer/imap": "^1.5",
         "matthiasmullie/minify": "^1.3"
         "matthiasmullie/minify": "^1.3"

+ 149 - 63
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/README.md

@@ -1,6 +1,9 @@
 # php-mime-mail-parser
 # php-mime-mail-parser
 
 
-A fully tested mailparse extension wrapper for PHP 5.4+
+A fully tested email parser for PHP 7.1+ (mailparse extension wrapper).
+
+It's the most effective php email parser around in terms of performance, foreign character encoding, attachment handling, and ease of use.
+Internet Message Format RFC [822](https://tools.ietf.org/html/rfc822), [2822](https://tools.ietf.org/html/rfc2822), [5322](https://tools.ietf.org/html/rfc5322).
 
 
 [![Latest Version](https://img.shields.io/packagist/v/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://github.com/php-mime-mail-parser/php-mime-mail-parser/releases)
 [![Latest Version](https://img.shields.io/packagist/v/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://github.com/php-mime-mail-parser/php-mime-mail-parser/releases)
 [![Total Downloads](https://img.shields.io/packagist/dt/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://packagist.org/packages/php-mime-mail-parser/php-mime-mail-parser)
 [![Total Downloads](https://img.shields.io/packagist/dt/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://packagist.org/packages/php-mime-mail-parser/php-mime-mail-parser)
@@ -10,6 +13,7 @@ A fully tested mailparse extension wrapper for PHP 5.4+
 
 
 This extension can be used to...
 This extension can be used to...
  * Parse and read email from Postfix
  * Parse and read email from Postfix
+ * For reading messages (Filename extension: eml)
  * Create webmail 
  * Create webmail 
  * Store email information such a subject, HTML body, attachments, and etc. into a database
  * Store email information such a subject, HTML body, attachments, and etc. into a database
 
 
@@ -35,105 +39,185 @@ To install the latest version of PHP MIME Mail Parser, run the command below:
 
 
 The following versions of PHP are supported:
 The following versions of PHP are supported:
 
 
-* PHP 5.4
-* PHP 5.5
-* PHP 5.6
-* PHP 7
-* HHVM
+* PHP 7.1
+* PHP 7.2
+* PHP 7.3
+
+Previous Versions:
+
+| PHP Compatibility  | Version |
+| ------------- | ------------- |
+| HHVM  | php-mime-mail-parser 2.11.1  |
+| PHP 5.4  | php-mime-mail-parser 2.11.1  |
+| PHP 5.5  | php-mime-mail-parser 2.11.1  |
+| PHP 5.6  | php-mime-mail-parser 3.0.4  |
+| PHP 7.0  | php-mime-mail-parser 3.0.4  |
+
+Make sure you have the mailparse extension (http://php.net/manual/en/book.mailparse.php) properly installed. The command line `php -m | grep mailparse` need to return "mailparse".
 
 
+
+### Install mailparse extension
+
+#### Ubuntu, Debian & derivatives
 ```
 ```
-sudo apt install php-cli php-pear php-dev php-mbstring
+sudo apt install php-cli php-mailparse
 ```
 ```
 
 
-Make sure you have the mailparse extension (http://php.net/manual/en/book.mailparse.php) properly installed. The command line `php -m | grep mailparse` need to return "mailparse" else install it:
-* PHP version > 7.0: mailparse
-* PHP version < 7.0: mailparse 2.1.6
+#### Others platforms
+```
+sudo apt install php-cli php-pear php-dev php-mbstring
+pecl install mailparse
+```
 
 
-Follow this steps to install mailparse:
+#### From source
 
 
-* Compile in the temp folder the extension mailparse or mailparse-2.1.6 (workaround because pecl install doesn't work yet)
+AAAAMMDD should be `php-config --extension-dir`
 ```
 ```
-cd
-pecl download mailparse
-tar -xvf mailparse-3.0.2.tgz 
-cd mailparse-3.0.2/
+git clone https://github.com/php/pecl-mail-mailparse.git
+cd pecl-mail-mailparse
 phpize
 phpize
 ./configure
 ./configure
 sed -i 's/#if\s!HAVE_MBSTRING/#ifndef MBFL_MBFILTER_H/' ./mailparse.c
 sed -i 's/#if\s!HAVE_MBSTRING/#ifndef MBFL_MBFILTER_H/' ./mailparse.c
 make
 make
-sudo mv modules/mailparse.so /usr/lib/php/20160303/
-```
-* Add the extension mailparse and activate it
-```
+sudo mv modules/mailparse.so /usr/lib/php/AAAAMMDD/
 echo "extension=mailparse.so" | sudo tee /etc/php/7.1/mods-available/mailparse.ini
 echo "extension=mailparse.so" | sudo tee /etc/php/7.1/mods-available/mailparse.ini
 sudo phpenmod mailparse
 sudo phpenmod mailparse
 ```
 ```
 
 
-On Windows, you need to download mailparse DLL from http://pecl.php.net/package/mailparse and add the line "extension=php_mailparse.dll" to php.ini accordingly.
+#### Windows
+You need to download mailparse DLL from http://pecl.php.net/package/mailparse and add the line "extension=php_mailparse.dll" to php.ini accordingly.
 
 
 ## How do I use it?
 ## How do I use it?
 
 
+### Loading an email
+
+You can load an email with 4 differents ways. You only need to use one of the following four.
+
 ```php
 ```php
-<?php
-// Include the library first
 require_once __DIR__.'/vendor/autoload.php';
 require_once __DIR__.'/vendor/autoload.php';
 
 
-$path = 'path/to/mail.txt';
-$Parser = new PhpMimeMailParser\Parser();
+$path = 'path/to/email.eml';
+$parser = new PhpMimeMailParser\Parser();
+
+// 1. Specify a file path (string)
+$parser->setPath($path); 
+
+// 2. Specify the raw mime mail text (string)
+$parser->setText(file_get_contents($path));
 
 
-// There are four methods available to indicate which mime mail to parse.
-// You only need to use one of the following four:
+// 3. Specify a php file resource (stream)
+$parser->setStream(fopen($path, "r"));
 
 
-// 1. Specify a file path to the mime mail.
-$Parser->setPath($path); 
+// 4.  Specify a stream to work with mail server (stream)
+$parser->setStream(fopen("php://stdin", "r"));
+```
+
+### Get the metadata of the message
 
 
-// 2. Specify a php file resource (stream) to the mime mail.
-$Parser->setStream(fopen($path, "r"));
+Get the sender and the receiver:
 
 
-// 3. Specify the raw mime mail text.
-$Parser->setText(file_get_contents($path));
+```php
+$rawHeaderTo = $parser->getHeader('to');
+// return "test" <test@example.com>, "test2" <test2@example.com>
 
 
-// 4.  Specify a stream to work with mail server
-$Parser->setStream(fopen("php://stdin", "r"));
+$arrayHeaderTo = $parser->getAddresses('to');
+// return [["display"=>"test", "address"=>"test@example.com", false]]
 
 
-// Once we've indicated where to find the mail, we can parse out the data
-$to = $Parser->getHeader('to');             // "test" <test@example.com>, "test2" <test2@example.com>
-$addressesTo = $Parser->getAddresses('to'); //Return an array : [["display"=>"test", "address"=>"test@example.com", false],["display"=>"test2", "address"=>"test2@example.com", false]]
+$rawHeaderFrom = $parser->getHeader('from');
+// return "test" <test@example.com>
 
 
-$from = $Parser->getHeader('from');             // "test" <test@example.com>
-$addressesFrom = $Parser->getAddresses('from'); //Return an array : [["display"=>"test", "address"=>"test@example.com", "is_group"=>false]]
+$arrayHeaderFrom = $parser->getAddresses('from');
+// return [["display"=>"test", "address"=>"test@example.com", "is_group"=>false]]
+```
 
 
-$subject = $Parser->getHeader('subject');
+Get the subject:
 
 
-$text = $Parser->getMessageBody('text');
+```php
+$subject = $parser->getHeader('subject');
+```
 
 
-$html = $Parser->getMessageBody('html');
-$htmlEmbedded = $Parser->getMessageBody('htmlEmbedded'); //HTML Body included data
+Get other headers:
 
 
-$stringHeaders = $Parser->getHeadersRaw();	// Get all headers as a string, no charset conversion
-$arrayHeaders = $Parser->getHeaders();		// Get all headers as an array, with charset conversion
+```php
+$stringHeaders = $parser->getHeadersRaw();
+// return all headers as a string, no charset conversion
 
 
-// Pass in a writeable path to save attachments
-$attach_dir = '/path/to/save/attachments/'; 	// Be sure to include the trailing slash
-$include_inline = true;  			// Optional argument to include inline attachments (default: true)
-$Parser->saveAttachments($attach_dir [,$include_inline]);
+$arrayHeaders = $parser->getHeaders();
+// return all headers as an array, with charset conversion
+```
 
 
-// Get an array of Attachment items from $Parser
-$attachments = $Parser->getAttachments([$include_inline]);
+### Get the body of the message
 
 
-//  Loop through all the Attachments
-if (count($attachments) > 0) {
-	foreach ($attachments as $attachment) {
-		echo 'Filename : '.$attachment->getFilename().'<br />'; // logo.jpg
-		echo 'Filesize : '.filesize($attach_dir.$attachment->getFilename()).'<br />'; // 1000
-		echo 'Filetype : '.$attachment->getContentType().'<br />'; // image/jpeg
-		echo 'MIME part string : '.$attachment->getMimePartStr().'<br />'; // (the whole MIME part of the attachment)
-	}
-}
+```php
+$text = $parser->getMessageBody('text');
+// return the text version
+
+$html = $parser->getMessageBody('html');
+// return the html version
+
+$htmlEmbedded = $parser->getMessageBody('htmlEmbedded');
+// return the html version with the embedded contents like images
+
+```
+
+### Get attachments
+
+Save all attachments in a directory
+
+```php
+$parser->saveAttachments('/path/to/save/attachments/');
+// return all attachments saved in the directory (include inline attachments)
+
+$parser->saveAttachments('/path/to/save/attachments/', false);
+// return all attachments saved in the directory (exclude inline attachments)
+
+// Save all attachments with the strategy ATTACHMENT_DUPLICATE_SUFFIX (default)
+$parser->saveAttachments('/path/to/save/attachments/', false, Parser::ATTACHMENT_DUPLICATE_SUFFIX);
+// return all attachments saved in the directory: logo.jpg, logo_1.jpg, ..., logo_100.jpg, YY34UFHBJ.jpg
+
+// Save all attachments with the strategy ATTACHMENT_RANDOM_FILENAME
+$parser->saveAttachments('/path/to/save/attachments/', false, Parser::ATTACHMENT_RANDOM_FILENAME);
+// return all attachments saved in the directory: YY34UFHBJ.jpg and F98DBZ9FZF.jpg
+
+// Save all attachments with the strategy ATTACHMENT_DUPLICATE_THROW
+$parser->saveAttachments('/path/to/save/attachments/', false, Parser::ATTACHMENT_DUPLICATE_THROW);
+// return an exception when there is attachments duplicate.
 
 
-?>
 ```
 ```
 
 
+Get all attachments
+
+```php
+$attachments = $parser->getAttachments();
+// return an array of all attachments (include inline attachments)
+
+$attachments = $parser->getAttachments(false);
+// return an array of all attachments (exclude inline attachments)
+```
+
+
+Loop through all the Attachments
+```php
+foreach ($attachments as $attachment) {
+    echo 'Filename : '.$attachment->getFilename().'<br />';
+    // return logo.jpg
+    
+    echo 'Filesize : '.filesize($attach_dir.$attachment->getFilename()).'<br />';
+    // return 1000
+    
+    echo 'Filetype : '.$attachment->getContentType().'<br />';
+    // return image/jpeg
+    
+    echo 'MIME part string : '.$attachment->getMimePartStr().'<br />';
+    // return the whole MIME part of the attachment
+
+    $attachment->save('/path/to/save/myattachment/', Parser::ATTACHMENT_DUPLICATE_SUFFIX);
+    // return the path and the filename saved (same strategy available than saveAttachments)
+}
+```
+
+## Postfix configuration to manage email from a mail server
+
 Next you need to forward emails to this script above. For that I'm using [Postfix](http://www.postfix.org/) like a mail server, you need to configure /etc/postfix/master.cf
 Next you need to forward emails to this script above. For that I'm using [Postfix](http://www.postfix.org/) like a mail server, you need to configure /etc/postfix/master.cf
 
 
 Add this line at the end of the file (specify myhook to send all emails to the script test.php)
 Add this line at the end of the file (specify myhook to send all emails to the script test.php)
@@ -150,6 +234,8 @@ smtp      inet  n       -       -       -       -       smtpd
 
 
 The php script must use the fourth method to work with this configuration.
 The php script must use the fourth method to work with this configuration.
 
 
+And finally the easiest way is to use my SaaS https://mailcare.io
+
 
 
 ## Can I contribute?
 ## Can I contribute?
 
 
@@ -162,6 +248,6 @@ Feel free to contribute!
 
 
 If you report an issue, please provide the raw email that triggered it. This helps us reproduce the issue and fix it more quickly.
 If you report an issue, please provide the raw email that triggered it. This helps us reproduce the issue and fix it more quickly.
 
 
-### License
+## License
 
 
 The php-mime-mail-parser/php-mime-mail-parser is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
 The php-mime-mail-parser/php-mime-mail-parser is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

+ 10 - 0
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/compile_mailparse.sh

@@ -0,0 +1,10 @@
+#!/bin/sh
+
+git clone https://github.com/php/pecl-mail-mailparse.git
+cd pecl-mail-mailparse
+phpize
+./configure
+sed -i 's/#if\s!HAVE_MBSTRING/#ifndef MBFL_MBFILTER_H/' ./mailparse.c
+make
+sudo mv modules/mailparse.so /home/travis/.phpenv/versions/7.3.2/lib/php/extensions/no-debug-zts-20180731/
+echo 'extension=mailparse.so' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini

+ 7 - 7
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/composer.json

@@ -1,8 +1,8 @@
 {
 {
     "name": "php-mime-mail-parser/php-mime-mail-parser",
     "name": "php-mime-mail-parser/php-mime-mail-parser",
     "type": "library",
     "type": "library",
-    "description": "Fully Tested Mailparse Extension Wrapper for PHP 5.4+",
-    "keywords": ["mime", "mail", "mailparse", "MimeMailParser"],
+    "description": "A fully tested email parser for PHP 7.1+ (mailparse extension wrapper).",
+    "keywords": ["mime", "mail", "mailparse", "MimeMailParser", "parser", "php"],
     "homepage": "https://github.com/php-mime-mail-parser/php-mime-mail-parser",
     "homepage": "https://github.com/php-mime-mail-parser/php-mime-mail-parser",
     "license": "MIT",
     "license": "MIT",
     "authors": [      
     "authors": [      
@@ -42,14 +42,14 @@
         "url":"https://github.com/php-mime-mail-parser/php-mime-mail-parser.git"
         "url":"https://github.com/php-mime-mail-parser/php-mime-mail-parser.git"
     },
     },
     "require": {
     "require": {
-        "php":           "^5.4.0 || ^7.0",
+        "php":           "^7.1",
         "ext-mailparse": "*"
         "ext-mailparse": "*"
     },
     },
     "require-dev": {
     "require-dev": {
-        "phpunit/phpunit":              "^4.0 || ^5.0",
-        "phpunit/php-token-stream":     "^1.3.0",
-        "satooshi/php-coveralls":       "0.*",
-        "squizlabs/PHP_CodeSniffer":    "2.*"
+        "phpunit/phpunit":              "^7.0",
+        "phpunit/php-token-stream":     "^3.0",
+        "php-coveralls/php-coveralls":  "^2.1",
+        "squizlabs/php_codesniffer":    "^3.4"
     },
     },
     "replace": {
     "replace": {
         "exorus/php-mime-mail-parser":   "*",
         "exorus/php-mime-mail-parser":   "*",

+ 3 - 3
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/mailparse-stubs.php

@@ -135,7 +135,7 @@ function mailparse_msg_create()
  * @param resource $mimemail A valid MIME resource allocated by
  * @param resource $mimemail A valid MIME resource allocated by
  *                           mailparse_msg_create or mailparse_msg_parse_file
  *                           mailparse_msg_create or mailparse_msg_parse_file
  *
  *
- * @return bool
+ * @return boolean|null
  */
  */
 function mailparse_msg_free($mimemail)
 function mailparse_msg_free($mimemail)
 {
 {
@@ -149,7 +149,7 @@ function mailparse_msg_free($mimemail)
  * @param resource $mimemail A valid MIME resource
  * @param resource $mimemail A valid MIME resource
  * @param string   $data
  * @param string   $data
  *
  *
- * @return bool
+ * @return boolean|null
  */
  */
 function mailparse_msg_parse($mimemail, $data)
 function mailparse_msg_parse($mimemail, $data)
 {
 {
@@ -199,7 +199,7 @@ function mailparse_determine_best_xfer_encoding($fp)
  * @param string   $encoding One of the character encodings supported by the mbstring
  * @param string   $encoding One of the character encodings supported by the mbstring
  *                           module
  *                           module
  *
  *
- * @return bool
+ * @return boolean|null
  */
  */
 function mailparse_stream_encode($sourcefp, $destfp, $encoding)
 function mailparse_stream_encode($sourcefp, $destfp, $encoding)
 {
 {

+ 90 - 1
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Attachment.php

@@ -50,6 +50,11 @@ class Attachment
      */
      */
     protected $mimePartStr;
     protected $mimePartStr;
 
 
+    /**
+     * @var integer $maxDuplicateNumber
+     */
+    public $maxDuplicateNumber = 100;
+
     /**
     /**
      * Attachment constructor.
      * Attachment constructor.
      *
      *
@@ -133,13 +138,44 @@ class Attachment
     /**
     /**
      * Get a handle to the stream
      * Get a handle to the stream
      *
      *
-     * @return stream
+     * @return resource
      */
      */
     public function getStream()
     public function getStream()
     {
     {
         return $this->stream;
         return $this->stream;
     }
     }
 
 
+    /**
+     * Rename a file if it already exists at its destination.
+     * Renaming is done by adding a duplicate number to the file name. E.g. existingFileName_1.ext.
+     * After a max duplicate number, renaming the file will switch over to generating a random suffix.
+     *
+     * @param string $fileName  Complete path to the file.
+     * @return string           The suffixed file name.
+     */
+    protected function suffixFileName(string $fileName): string
+    {
+        $pathInfo = pathinfo($fileName);
+        $dirname = $pathInfo['dirname'].DIRECTORY_SEPARATOR;
+        $filename = $pathInfo['filename'];
+        $extension  = empty($pathInfo['extension']) ? '' : '.'.$pathInfo['extension'];
+
+        $i = 0;
+        do {
+            $i++;
+
+            if ($i > $this->maxDuplicateNumber) {
+                $duplicateExtension = uniqid();
+            } else {
+                $duplicateExtension = $i;
+            }
+
+            $resultName = $dirname.$filename."_$duplicateExtension".$extension;
+        } while (file_exists($resultName));
+
+        return $resultName;
+    }
+
     /**
     /**
      * Read the contents a few bytes at a time until completed
      * Read the contents a few bytes at a time until completed
      * Once read to completion, it always returns false
      * Once read to completion, it always returns false
@@ -180,4 +216,57 @@ class Attachment
     {
     {
         return $this->mimePartStr;
         return $this->mimePartStr;
     }
     }
+
+    /**
+     * Save the attachment individually
+     *
+     * @param string $attach_dir
+     * @param string $filenameStrategy
+     *
+     * @return string
+     */
+    public function save(
+        $attach_dir,
+        $filenameStrategy = Parser::ATTACHMENT_DUPLICATE_SUFFIX
+    ) {
+        $attach_dir = rtrim($attach_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+        if (!is_dir($attach_dir)) {
+            mkdir($attach_dir);
+        }
+
+        // Determine filename
+        switch ($filenameStrategy) {
+            case Parser::ATTACHMENT_RANDOM_FILENAME:
+                $attachment_path = tempnam($attach_dir, '');
+                break;
+            case Parser::ATTACHMENT_DUPLICATE_THROW:
+            case Parser::ATTACHMENT_DUPLICATE_SUFFIX:
+                $attachment_path = $attach_dir.$this->getFilename();
+                break;
+            default:
+                throw new Exception('Invalid filename strategy argument provided.');
+        }
+
+        // Handle duplicate filename
+        if (file_exists($attachment_path)) {
+            switch ($filenameStrategy) {
+                case Parser::ATTACHMENT_DUPLICATE_THROW:
+                    throw new Exception('Could not create file for attachment: duplicate filename.');
+                case Parser::ATTACHMENT_DUPLICATE_SUFFIX:
+                    $attachment_path = $this->suffixFileName($attachment_path);
+                    break;
+            }
+        }
+
+        /** @var resource $fp */
+        if ($fp = fopen($attachment_path, 'w')) {
+            while ($bytes = $this->read()) {
+                fwrite($fp, $bytes);
+            }
+            fclose($fp);
+            return realpath($attachment_path);
+        } else {
+            throw new Exception('Could not write attachments. Your directory may be unwritable by PHP.');
+        }
+    }
 }
 }

+ 31 - 19
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Charset.php

@@ -78,20 +78,20 @@ class Charset implements CharsetManager
         'cns11643'                 => 'x-euc-tw',
         'cns11643'                 => 'x-euc-tw',
         'x-imap4-modified-utf7'    => 'x-imap4-modified-utf7',
         'x-imap4-modified-utf7'    => 'x-imap4-modified-utf7',
         'x-euc-tw'                 => 'x-euc-tw',
         'x-euc-tw'                 => 'x-euc-tw',
-        'x-mac-ce'                 => 'x-mac-ce',
-        'x-mac-turkish'            => 'x-mac-turkish',
-        'x-mac-greek'              => 'x-mac-greek',
-        'x-mac-icelandic'          => 'x-mac-icelandic',
-        'x-mac-croatian'           => 'x-mac-croatian',
-        'x-mac-romanian'           => 'x-mac-romanian',
-        'x-mac-cyrillic'           => 'x-mac-cyrillic',
-        'x-mac-ukrainian'          => 'x-mac-cyrillic',
-        'x-mac-hebrew'             => 'x-mac-hebrew',
-        'x-mac-arabic'             => 'x-mac-arabic',
-        'x-mac-farsi'              => 'x-mac-farsi',
-        'x-mac-devanagari'         => 'x-mac-devanagari',
-        'x-mac-gujarati'           => 'x-mac-gujarati',
-        'x-mac-gurmukhi'           => 'x-mac-gurmukhi',
+        'x-mac-ce'                 => 'MACCE',
+        'x-mac-turkish'            => 'MACTURKISH',
+        'x-mac-greek'              => 'MACGREEK',
+        'x-mac-icelandic'          => 'MACICELANDIC',
+        'x-mac-croatian'           => 'MACCROATIAN',
+        'x-mac-romanian'           => 'MACROMANIAN',
+        'x-mac-cyrillic'           => 'MACCYRILLIC',
+        'x-mac-ukrainian'          => 'MACUKRAINIAN',
+        'x-mac-hebrew'             => 'MACHEBREW',
+        'x-mac-arabic'             => 'MACARABIC',
+        'x-mac-farsi'              => 'MACFARSI',
+        'x-mac-devanagari'         => 'MACDEVANAGARI',
+        'x-mac-gujarati'           => 'MACGUJARATI',
+        'x-mac-gurmukhi'           => 'MACGURMUKHI',
         'armscii-8'                => 'armscii-8',
         'armscii-8'                => 'armscii-8',
         'x-viet-tcvn5712'          => 'x-viet-tcvn5712',
         'x-viet-tcvn5712'          => 'x-viet-tcvn5712',
         'x-viet-vps'               => 'x-viet-vps',
         'x-viet-vps'               => 'x-viet-vps',
@@ -315,11 +315,23 @@ class Charset implements CharsetManager
      */
      */
     public function decodeCharset($encodedString, $charset)
     public function decodeCharset($encodedString, $charset)
     {
     {
-        if (strtolower($charset) == 'utf-8' || strtolower($charset) == 'us-ascii') {
+        $charset = $this->getCharsetAlias($charset);
+
+        if ($charset == 'utf-8' || $charset == 'us-ascii') {
             return $encodedString;
             return $encodedString;
-        } else {
-            return iconv($this->getCharsetAlias($charset), 'UTF-8//TRANSLIT//IGNORE', $encodedString);
         }
         }
+
+        if (function_exists('mb_convert_encoding')) {
+            if ($charset == 'ISO-2022-JP') {
+                return mb_convert_encoding($encodedString, 'UTF-8', 'ISO-2022-JP-MS');
+            }
+
+            if (array_search($charset, array_map('strtolower', mb_list_encodings()))) {
+                return mb_convert_encoding($encodedString, 'UTF-8', $charset);
+            }
+        }
+
+        return iconv($charset, 'UTF-8//TRANSLIT//IGNORE', $encodedString);
     }
     }
 
 
     /**
     /**
@@ -331,8 +343,8 @@ class Charset implements CharsetManager
 
 
         if (array_key_exists($charset, $this->charsetAlias)) {
         if (array_key_exists($charset, $this->charsetAlias)) {
             return $this->charsetAlias[$charset];
             return $this->charsetAlias[$charset];
-        } else {
-            return null;
         }
         }
+        
+        return 'us-ascii';
     }
     }
 }
 }

+ 2 - 0
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Middleware.php

@@ -7,6 +7,8 @@ namespace PhpMimeMailParser;
  */
  */
 class Middleware implements Contracts\Middleware
 class Middleware implements Contracts\Middleware
 {
 {
+    protected $parser;
+
     /**
     /**
      * Create a middleware using a callable $fn
      * Create a middleware using a callable $fn
      *
      *

+ 3 - 3
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MiddlewareStack.php

@@ -2,7 +2,7 @@
 
 
 namespace PhpMimeMailParser;
 namespace PhpMimeMailParser;
 
 
-use PhpMimeMailParser\Contracts\MiddleWare;
+use PhpMimeMailParser\Contracts\MiddleWare as MiddleWareContracts;
 
 
 /**
 /**
  * A stack of middleware chained together by (MiddlewareStack $next)
  * A stack of middleware chained together by (MiddlewareStack $next)
@@ -29,7 +29,7 @@ class MiddlewareStack
      *
      *
      * @param Middleware $middleware
      * @param Middleware $middleware
      */
      */
-    public function __construct(Middleware $middleware = null)
+    public function __construct(MiddleWareContracts $middleware = null)
     {
     {
         $this->middleware = $middleware;
         $this->middleware = $middleware;
     }
     }
@@ -40,7 +40,7 @@ class MiddlewareStack
      * @param Middleware $middleware
      * @param Middleware $middleware
      * @return MiddlewareStack Immutable MiddlewareStack
      * @return MiddlewareStack Immutable MiddlewareStack
      */
      */
-    public function add(Middleware $middleware)
+    public function add(MiddleWareContracts $middleware)
     {
     {
         $stack = new static($middleware);
         $stack = new static($middleware);
         $stack->next = $this;
         $stack->next = $this;

+ 24 - 45
data/web/inc/lib/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Parser.php

@@ -110,6 +110,15 @@ class Parser
      */
      */
     public function setPath($path)
     public function setPath($path)
     {
     {
+        if (is_writable($path)) {
+            $file = fopen($path, 'a+');
+            fseek($file, -1, SEEK_END);
+            if (fread($file, 1) != "\n") {
+                fwrite($file, PHP_EOL);
+            }
+            fclose($file);
+        }
+
         // should parse message incrementally from file
         // should parse message incrementally from file
         $this->resource = mailparse_msg_parse_file($path);
         $this->resource = mailparse_msg_parse_file($path);
         $this->stream = fopen($path, 'r');
         $this->stream = fopen($path, 'r');
@@ -142,6 +151,11 @@ class Parser
             while (!feof($stream)) {
             while (!feof($stream)) {
                 fwrite($tmp_fp, fread($stream, 2028));
                 fwrite($tmp_fp, fread($stream, 2028));
             }
             }
+
+            if (fread($tmp_fp, 1) != "\n") {
+                fwrite($tmp_fp, PHP_EOL);
+            }
+
             fseek($tmp_fp, 0);
             fseek($tmp_fp, 0);
             $this->stream = &$tmp_fp;
             $this->stream = &$tmp_fp;
         } else {
         } else {
@@ -170,9 +184,14 @@ class Parser
      */
      */
     public function setText($data)
     public function setText($data)
     {
     {
-        if (!$data) {
+        if (empty($data)) {
             throw new Exception('You must not call MimeMailParser::setText with an empty string parameter');
             throw new Exception('You must not call MimeMailParser::setText with an empty string parameter');
         }
         }
+
+        if (substr($data, -1) != "\n") {
+            $data = $data.PHP_EOL;
+        }
+
         $this->resource = mailparse_msg_create();
         $this->resource = mailparse_msg_create();
         // does not parse incrementally, fast memory hog might explode
         // does not parse incrementally, fast memory hog might explode
         mailparse_msg_parse($this->resource, $data);
         mailparse_msg_parse($this->resource, $data);
@@ -205,7 +224,7 @@ class Parser
      *
      *
      * @param string $name Header name (case-insensitive)
      * @param string $name Header name (case-insensitive)
      *
      *
-     * @return string
+     * @return string|bool
      * @throws Exception
      * @throws Exception
      */
      */
     public function getRawHeader($name)
     public function getRawHeader($name)
@@ -214,7 +233,7 @@ class Parser
         if (isset($this->parts[1])) {
         if (isset($this->parts[1])) {
             $headers = $this->getPart('headers', $this->parts[1]);
             $headers = $this->getPart('headers', $this->parts[1]);
 
 
-            return (isset($headers[$name])) ? $headers[$name] : false;
+            return isset($headers[$name]) ? $headers[$name] : false;
         } else {
         } else {
             throw new Exception(
             throw new Exception(
                 'setPath() or setText() or setStream() must be called before retrieving email headers.'
                 'setPath() or setText() or setStream() must be called before retrieving email headers.'
@@ -227,7 +246,7 @@ class Parser
      *
      *
      * @param string $name Header name (case-insensitive)
      * @param string $name Header name (case-insensitive)
      *
      *
-     * @return string
+     * @return string|bool
      */
      */
     public function getHeader($name)
     public function getHeader($name)
     {
     {
@@ -559,50 +578,10 @@ class Parser
         $filenameStrategy = self::ATTACHMENT_DUPLICATE_SUFFIX
         $filenameStrategy = self::ATTACHMENT_DUPLICATE_SUFFIX
     ) {
     ) {
         $attachments = $this->getAttachments($include_inline);
         $attachments = $this->getAttachments($include_inline);
-        if (empty($attachments)) {
-            return false;
-        }
-
-        if (!is_dir($attach_dir)) {
-            mkdir($attach_dir);
-        }
 
 
         $attachments_paths = [];
         $attachments_paths = [];
         foreach ($attachments as $attachment) {
         foreach ($attachments as $attachment) {
-            // Determine filename
-            switch ($filenameStrategy) {
-                case self::ATTACHMENT_RANDOM_FILENAME:
-                    $attachment_path = tempnam($attach_dir, '');
-                    break;
-                case self::ATTACHMENT_DUPLICATE_THROW:
-                case self::ATTACHMENT_DUPLICATE_SUFFIX:
-                    $attachment_path = $attach_dir.$attachment->getFilename();
-                    break;
-                default:
-                    throw new Exception('Invalid filename strategy argument provided.');
-            }
-
-            // Handle duplicate filename
-            if (file_exists($attachment_path)) {
-                switch ($filenameStrategy) {
-                    case self::ATTACHMENT_DUPLICATE_THROW:
-                        throw new Exception('Could not create file for attachment: duplicate filename.');
-                    case self::ATTACHMENT_DUPLICATE_SUFFIX:
-                        $attachment_path = tempnam($attach_dir, $attachment->getFilename());
-                        break;
-                }
-            }
-
-            /** @var resource $fp */
-            if ($fp = fopen($attachment_path, 'w')) {
-                while ($bytes = $attachment->read()) {
-                    fwrite($fp, $bytes);
-                }
-                fclose($fp);
-                $attachments_paths[] = realpath($attachment_path);
-            } else {
-                throw new Exception('Could not write attachments. Your directory may be unwritable by PHP.');
-            }
+            $attachments_paths[] = $attachment->save($attach_dir, $filenameStrategy);
         }
         }
 
 
         return $attachments_paths;
         return $attachments_paths;