From 3b0a679524474211ad91775dc69cc7051a449c6a Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Wed, 27 May 2020 12:45:33 -0500 Subject: [PATCH] Updated third-party PHP libraries * phpmailer/phpmailer has been updated to fix an attachment filename escaping issue. * hybridauth/hybridauth has been updated to add Patreon as a social login provider. * ifsnop/mysqldump-php has been updated just 'cause. --- composer.lock | 45 +++-- .../vendor/composer/autoload_real.php | 3 + e107_handlers/vendor/composer/installed.json | 44 +++-- .../vendor/hybridauth/hybridauth/README.md | 2 +- .../hybridauth/src/Provider/Facebook.php | 2 +- .../hybridauth/src/Provider/Instagram.php | 131 +++++++++++--- .../hybridauth/src/Provider/Odnoklassniki.php | 8 + .../hybridauth/src/Provider/Patreon.php | 85 +++++++++ .../hybridauth/src/Provider/Vkontakte.php | 73 +++++--- .../vendor/ifsnop/mysqldump-php/README.md | 31 +++- .../src/Ifsnop/Mysqldump/Mysqldump.php | 100 +++++++---- .../vendor/phpmailer/phpmailer/README.md | 6 +- .../vendor/phpmailer/phpmailer/SECURITY.md | 2 + .../vendor/phpmailer/phpmailer/VERSION | 2 +- .../vendor/phpmailer/phpmailer/composer.json | 6 + .../phpmailer/language/phpmailer.lang-da.php | 32 ++-- ...iler.lang-am.php => phpmailer.lang-hy.php} | 0 .../phpmailer/phpmailer/src/PHPMailer.php | 170 ++++++++++++------ .../vendor/phpmailer/phpmailer/src/POP3.php | 4 +- .../vendor/phpmailer/phpmailer/src/SMTP.php | 7 +- e107_tests/tests/unit/e_user_providerTest.php | 2 +- 21 files changed, 536 insertions(+), 219 deletions(-) create mode 100644 e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Patreon.php rename e107_handlers/vendor/phpmailer/phpmailer/language/{phpmailer.lang-am.php => phpmailer.lang-hy.php} (100%) diff --git a/composer.lock b/composer.lock index 3b854383a..321b5e9c0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "33e332186d73935e44e71e72a52ae532", + "content-hash": "1c075824f15ab5d3b2b7f32dcf933e8a", "packages": [ { "name": "hybridauth/hybridauth", - "version": "3.2.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/hybridauth/hybridauth.git", - "reference": "2edf92f07b94fcc9e17ea14e2a1644b83981af7d" + "reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/2edf92f07b94fcc9e17ea14e2a1644b83981af7d", - "reference": "2edf92f07b94fcc9e17ea14e2a1644b83981af7d", + "url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/51cb2ad2f04d175d298b51e919868dec1d4d8b04", + "reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04", "shasum": "" }, "require": { @@ -56,20 +56,20 @@ "social", "twitter" ], - "time": "2020-03-04T14:32:04+00:00" + "time": "2020-04-16T08:04:26+00:00" }, { "name": "ifsnop/mysqldump-php", - "version": "v2.8", + "version": "v2.9", "source": { "type": "git", "url": "https://github.com/ifsnop/mysqldump-php.git", - "reference": "b6919eff87c36b18fe0d4b3a53635df03c8a3b38" + "reference": "fc9c119fe5d70af9a685cad6a8ac612fd7589e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/b6919eff87c36b18fe0d4b3a53635df03c8a3b38", - "reference": "b6919eff87c36b18fe0d4b3a53635df03c8a3b38", + "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/fc9c119fe5d70af9a685cad6a8ac612fd7589e25", + "reference": "fc9c119fe5d70af9a685cad6a8ac612fd7589e25", "shasum": "" }, "require": { @@ -111,20 +111,20 @@ "php5", "sql" ], - "time": "2019-10-29T23:13:43+00:00" + "time": "2020-04-03T14:40:40+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v6.1.4", + "version": "v6.1.6", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683" + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c5e61d0729507049cec9673aa1a679f9adefd683", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", "shasum": "" }, "require": { @@ -173,7 +173,13 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "time": "2019-12-10T11:17:38+00:00" + "funding": [ + { + "url": "https://github.com/synchro", + "type": "github" + } + ], + "time": "2020-05-27T12:24:03+00:00" }, { "name": "tedivm/jshrink", @@ -229,10 +235,13 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.6" + "php": ">=5.6", + "ext-json": "*", + "ext-pdo": "*" }, "platform-dev": [], "platform-overrides": { "php": "5.6" - } + }, + "plugin-api-version": "1.1.0" } diff --git a/e107_handlers/vendor/composer/autoload_real.php b/e107_handlers/vendor/composer/autoload_real.php index d604ee2df..04632fea0 100644 --- a/e107_handlers/vendor/composer/autoload_real.php +++ b/e107_handlers/vendor/composer/autoload_real.php @@ -13,6 +13,9 @@ class ComposerAutoloaderInit1da798ad8058bf7b615c0a3d8f41e314 } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { diff --git a/e107_handlers/vendor/composer/installed.json b/e107_handlers/vendor/composer/installed.json index 4900fb761..1ac5f7696 100644 --- a/e107_handlers/vendor/composer/installed.json +++ b/e107_handlers/vendor/composer/installed.json @@ -1,17 +1,17 @@ [ { "name": "hybridauth/hybridauth", - "version": "3.2.0", - "version_normalized": "3.2.0.0", + "version": "3.3.0", + "version_normalized": "3.3.0.0", "source": { "type": "git", "url": "https://github.com/hybridauth/hybridauth.git", - "reference": "2edf92f07b94fcc9e17ea14e2a1644b83981af7d" + "reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/2edf92f07b94fcc9e17ea14e2a1644b83981af7d", - "reference": "2edf92f07b94fcc9e17ea14e2a1644b83981af7d", + "url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/51cb2ad2f04d175d298b51e919868dec1d4d8b04", + "reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04", "shasum": "" }, "require": { @@ -21,7 +21,7 @@ "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^6.5 || ^8" }, - "time": "2020-03-04T14:32:04+00:00", + "time": "2020-04-16T08:04:26+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -55,17 +55,17 @@ }, { "name": "ifsnop/mysqldump-php", - "version": "v2.8", - "version_normalized": "2.8.0.0", + "version": "v2.9", + "version_normalized": "2.9.0.0", "source": { "type": "git", "url": "https://github.com/ifsnop/mysqldump-php.git", - "reference": "b6919eff87c36b18fe0d4b3a53635df03c8a3b38" + "reference": "fc9c119fe5d70af9a685cad6a8ac612fd7589e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/b6919eff87c36b18fe0d4b3a53635df03c8a3b38", - "reference": "b6919eff87c36b18fe0d4b3a53635df03c8a3b38", + "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/fc9c119fe5d70af9a685cad6a8ac612fd7589e25", + "reference": "fc9c119fe5d70af9a685cad6a8ac612fd7589e25", "shasum": "" }, "require": { @@ -75,7 +75,7 @@ "phpunit/phpunit": "4.8.36", "squizlabs/php_codesniffer": "1.*" }, - "time": "2019-10-29T23:13:43+00:00", + "time": "2020-04-03T14:40:40+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -112,17 +112,17 @@ }, { "name": "phpmailer/phpmailer", - "version": "v6.1.4", - "version_normalized": "6.1.4.0", + "version": "v6.1.6", + "version_normalized": "6.1.6.0", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683" + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c5e61d0729507049cec9673aa1a679f9adefd683", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", "shasum": "" }, "require": { @@ -143,7 +143,7 @@ "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" }, - "time": "2019-12-10T11:17:38+00:00", + "time": "2020-05-27T12:24:03+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -172,7 +172,13 @@ "name": "Brent R. Matzelle" } ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP" + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "funding": [ + { + "url": "https://github.com/synchro", + "type": "github" + } + ] }, { "name": "tedivm/jshrink", diff --git a/e107_handlers/vendor/hybridauth/hybridauth/README.md b/e107_handlers/vendor/hybridauth/hybridauth/README.md index 6a2142bc1..1d88c707d 100644 --- a/e107_handlers/vendor/hybridauth/hybridauth/README.md +++ b/e107_handlers/vendor/hybridauth/hybridauth/README.md @@ -1,4 +1,4 @@ -## [Hybridauth](https://hybridauth.github.io/) 3.1 +## [Hybridauth](https://hybridauth.github.io/) 3.3 [![Build Status](https://travis-ci.org/hybridauth/hybridauth.svg?branch=master)](https://travis-ci.org/hybridauth/hybridauth) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/hybridauth/hybridauth/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/hybridauth/hybridauth/?branch=master) [![Latest Stable Version](https://poser.pugx.org/hybridauth/hybridauth/v/stable.png)](https://packagist.org/packages/hybridauth/hybridauth) [![Join the chat at https://gitter.im/hybridauth/hybridauth](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hybridauth/hybridauth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php index 159ffedf0..f0fbf2add 100644 --- a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php @@ -47,7 +47,7 @@ class Facebook extends OAuth2 /** * {@inheritdoc} */ - protected $apiBaseUrl = 'https://graph.facebook.com/v2.12/'; + protected $apiBaseUrl = 'https://graph.facebook.com/v6.0/'; /** * {@inheritdoc} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php index bc5d01475..6c0cf691c 100644 --- a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php @@ -2,35 +2,35 @@ /*! * Hybridauth * https://hybridauth.github.io | https://github.com/hybridauth/hybridauth -* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html +* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html */ namespace Hybridauth\Provider; use Hybridauth\Adapter\OAuth2; +use Hybridauth\Data\Collection; use Hybridauth\Exception\UnexpectedApiResponseException; -use Hybridauth\Data; use Hybridauth\User; /** - * Instagram OAuth2 provider adapter. + * Instagram OAuth2 provider adapter via Instagram Basic Display API. */ class Instagram extends OAuth2 { /** * {@inheritdoc} */ - protected $scope = 'basic'; + protected $scope = 'user_profile,user_media'; /** * {@inheritdoc} */ - protected $apiBaseUrl = 'https://api.instagram.com/v1/'; + protected $apiBaseUrl = 'https://graph.instagram.com'; /** * {@inheritdoc} */ - protected $authorizeUrl = 'https://api.instagram.com/oauth/authorize/'; + protected $authorizeUrl = 'https://api.instagram.com/oauth/authorize'; /** * {@inheritdoc} @@ -40,7 +40,7 @@ class Instagram extends OAuth2 /** * {@inheritdoc} */ - protected $apiDocumentation = 'https://www.instagram.com/developer/authentication/'; + protected $apiDocumentation = 'https://developers.facebook.com/docs/instagram-basic-display-api'; /** * {@inheritdoc} @@ -50,7 +50,7 @@ class Instagram extends OAuth2 parent::initialize(); // The Instagram API requires an access_token from authenticated users - // for each endpoint, see https://www.instagram.com/developer/endpoints. + // for each endpoint. $accessToken = $this->getStoredData($this->accessTokenName); $this->apiRequestParameters[$this->accessTokenName] = $accessToken; } @@ -60,28 +60,111 @@ class Instagram extends OAuth2 */ public function getUserProfile() { - $response = $this->apiRequest('users/self/'); + $response = $this->apiRequest('me', 'GET', [ + 'fields' => 'id,username,account_type,media_count', + ]); - $data = new Data\Collection($response); - - if (! $data->exists('data')) { + $data = new Collection($response); + if (!$data->exists('id')) { throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); } $userProfile = new User\Profile(); - - $data = $data->filter('data'); - - $userProfile->identifier = $data->get('id'); - $userProfile->description = $data->get('bio'); - $userProfile->photoURL = $data->get('profile_picture'); - $userProfile->webSiteURL = $data->get('website'); - $userProfile->displayName = $data->get('full_name'); - $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); - $userProfile->profileURL = "https://instagram.com/{$data->get('username')}"; - - $userProfile->data = (array) $data->get('counts'); + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('username'); + $userProfile->profileURL = "https://instagram.com/{$userProfile->displayName}"; + $userProfile->data = [ + 'account_type' => $data->get('account_type'), + 'media_count' => $data->get('media_count'), + ]; return $userProfile; } + + /** + * Fetch user medias. + * + * @param int $limit Number of elements per page. + * @param string $pageId Current pager ID. + * @param array|null $fields Fields to fetch per media. + * + * @return \Hybridauth\Data\Collection + * + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws \Hybridauth\Exception\InvalidAccessTokenException + * @throws \Hybridauth\Exception\UnexpectedApiResponseException + */ + public function getUserMedia($limit = 12, $pageId = null, array $fields = null) + { + if (empty($fields)) { + $fields = [ + 'id', + 'caption', + 'media_type', + 'media_url', + 'thumbnail_url', + 'permalink', + 'timestamp', + 'username', + ]; + } + + $params = [ + 'fields' => implode(',', $fields), + 'limit' => $limit, + ]; + if ($pageId !== null) { + $params['after'] = $pageId; + } + + $response = $this->apiRequest('me/media', 'GET', $params); + + $data = new Collection($response); + if (!$data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + return $data; + } + + /** + * Fetches a single user's media. + * + * @param string $mediaId Media ID. + * @param array|null $fields Fields to fetch per media. + * + * @return \Hybridauth\Data\Collection + * + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws \Hybridauth\Exception\InvalidAccessTokenException + * @throws \Hybridauth\Exception\UnexpectedApiResponseException + */ + public function getMedia($mediaId, array $fields = null) + { + if (empty($fields)) { + $fields = [ + 'id', + 'caption', + 'media_type', + 'media_url', + 'thumbnail_url', + 'permalink', + 'timestamp', + 'username', + ]; + } + + $response = $this->apiRequest($mediaId, 'GET', [ + 'fields' => implode(',', $fields), + ]); + + $data = new Collection($response); + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + return $data; + } } diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php index 9597b4e7a..cc97dc6e3 100644 --- a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php @@ -109,6 +109,14 @@ class Odnoklassniki extends OAuth2 $userProfile->displayName = $data->get('name'); $userProfile->photoURL = $data->get('pic1024x768'); $userProfile->profileURL = 'http://ok.ru/profile/' . $data->get('uid'); + + // Handle birthday. + if ($data->get('birthday')) { + $bday = explode('-', $data->get('birthday')); + $userProfile->birthDay = (int)$bday[0]; + $userProfile->birthMonth = (int)$bday[1]; + $userProfile->birthYear = (int)$bday[2]; + } return $userProfile; } diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Patreon.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Patreon.php new file mode 100644 index 000000000..d68006ead --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Patreon.php @@ -0,0 +1,85 @@ +tokenRefreshParameters += [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + ]; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('oauth2/v2/identity', 'GET', [ + 'fields[user]' => 'created,first_name,last_name,email,full_name,is_email_verified,thumb_url,url', + ]); + + $collection = new Collection($response); + if (!$collection->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new Profile(); + + $data = $collection->filter('data'); + $attributes = $data->filter('attributes'); + + $userProfile->identifier = $data->get('id'); + $userProfile->email = $attributes->get('email'); + $userProfile->firstName = $attributes->get('first_name'); + $userProfile->lastName = $attributes->get('last_name'); + $userProfile->displayName = $attributes->get('full_name') ?: $data->get('id'); + $userProfile->photoURL = $attributes->get('thumb_url'); + $userProfile->profileURL = $attributes->get('url'); + + $userProfile->emailVerified = $attributes->get('is_email_verified') ? $userProfile->email : ''; + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php index cfc31bd4e..b58203ea0 100644 --- a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php @@ -64,6 +64,31 @@ class Vkontakte extends OAuth2 */ protected $scope = 'email,offline'; + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + // The VK API requires version and access_token from authenticated users + // for each endpoint. + $accessToken = $this->getStoredData($this->accessTokenName); + $this->apiRequestParameters[$this->accessTokenName] = $accessToken; + $this->apiRequestParameters['v'] = static::API_VERSION; + } + + /** + * {@inheritdoc} + */ + protected function validateAccessTokenExchange($response) + { + $data = parent::validateAccessTokenExchange($response); + + // Need to store email for later use. + $this->storeData('email', $data->get('email')); + } + /** * {@inheritdoc} */ @@ -80,30 +105,13 @@ class Vkontakte extends OAuth2 /** * {@inheritdoc} */ - protected function validateAccessTokenExchange($response) - { - $data = parent::validateAccessTokenExchange($response); - - // Need to store user_id as token for later use. - $this->storeData('user_id', $data->get('user_id')); - $this->storeData('email', $data->get('email')); - } - - /** - * {@inheritdoc} - */ public function getUserProfile() { $photoField = 'photo_' . ($this->config->get('photo_size') ?: 'max_orig'); - $parameters = [ - 'user_ids' => $this->getStoredData('user_id'), - // Required fields: id,first_name,last_name - 'fields' => 'screen_name,sex,has_photo,' . $photoField, - 'v' => static::API_VERSION, - $this->accessTokenName => $this->getStoredData($this->accessTokenName), - ]; - $response = $this->apiRequest('users.get', 'GET', $parameters); + $response = $this->apiRequest('users.get', 'GET', [ + 'fields' => 'screen_name,sex,education,bdate,has_photo,' . $photoField, + ]); if (property_exists($response, 'error')) { throw new UnexpectedApiResponseException($response->error->error_msg); @@ -124,6 +132,18 @@ class Vkontakte extends OAuth2 $userProfile->displayName = $data->get('screen_name'); $userProfile->photoURL = $data->get('has_photo') === 1 ? $data->get($photoField) : ''; + // Handle b-date. + if ($data->get('bdate')) { + $bday = explode('.', $data->get('bdate')); + $userProfile->birthDay = (int) $bday[0]; + $userProfile->birthMonth = (int) $bday[1]; + $userProfile->birthYear = (int) $bday[2]; + } + + $userProfile->data = [ + 'education' => $data->get('education'), + ]; + $screen_name = static::URL . ($data->get('screen_name') ?: 'id' . $data->get('id')); $userProfile->profileURL = $screen_name; @@ -145,21 +165,16 @@ class Vkontakte extends OAuth2 */ public function getUserContacts() { - $contacts = []; - - $parameters = [ - 'user_id' => $this->getStoredData('user_id'), + $response = $this->apiRequest('friends.get', 'GET', [ 'fields' => 'uid,name,photo_200_orig', - 'v' => static::API_VERSION, - $this->accessTokenName => $this->getStoredData($this->accessTokenName), - ]; - - $response = $this->apiRequest('friends.get', 'GET', $parameters); + ]); $data = new Data\Collection($response); if (!$data->exists('response')) { throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); } + + $contacts = []; if (!$data->filter('response')->filter('items')->isEmpty()) { foreach ($data->filter('response')->filter('items')->toArray() as $item) { $contacts[] = $this->fetchUserContact($item); diff --git a/e107_handlers/vendor/ifsnop/mysqldump-php/README.md b/e107_handlers/vendor/ifsnop/mysqldump-php/README.md index 5982e4d87..ca2c8da67 100644 --- a/e107_handlers/vendor/ifsnop/mysqldump-php/README.md +++ b/e107_handlers/vendor/ifsnop/mysqldump-php/README.md @@ -25,7 +25,7 @@ Out of the box, MySQLDump-PHP supports backing up table structures, the data its MySQLDump-PHP is the only library that supports: * output binary blobs as hex. * resolves view dependencies (using Stand-In tables). -* output compared against original mysqldump. Linked to travis-ci testing system (testing from php 5.3 to 7.1 & hhvm) +* output compared against original mysqldump. Linked to travis-ci testing system (testing from php 5.3 to 7.3 & hhvm) * dumps stored routines (functions and procedures). * dumps events. * does extended-insert and/or complete-insert. @@ -89,23 +89,36 @@ Plain old PHP: Refer to the [wiki](https://github.com/ifsnop/mysqldump-php/wiki/Full-usage-example) for some examples and a comparision between mysqldump and mysqldump-php dumps. ## Changing values when exporting + You can register a callable that will be used to transform values during the export. An example use-case for this is removing sensitive data from database dumps: ```php $dumper = new IMysqldump\Mysqldump('mysql:host=localhost;dbname=testdb', 'username', 'password'); -$dumper->setTransformColumnValueHook(function ($tableName, $colName, $colValue) { - if ($colName === 'social_security_number') { - return (string) rand(1000000, 9999999); +$dumper->setTransformTableRowHook(function ($tableName, array $row) { + if ($tableName === 'customers') { + $row['social_security_number'] = (string) rand(1000000, 9999999); } - return $colValue; + return $row; }); $dumper->start('storage/work/dump.sql'); ``` +## Getting information about the dump + +You can register a callable that will be used to report on the progress of the dump + +```php +$dumper->setInfoHook(function($object, $info) { + if ($object === 'table') { + echo $info['name'], $info['rowCount']; + }); +``` + ## Table specific export conditions + You can register table specific 'where' clauses to limit data on a per table basis. These override the default `where` dump setting: ```php @@ -119,6 +132,7 @@ $dumper->setTableWheres(array( ``` ## Table specific export limits + You can register table specific 'limits' to limit the returned rows on a per table basis: ```php @@ -132,6 +146,7 @@ $dumper->setTableLimits(array( ``` ## Constructor and default parameters + ```php /** * Constructor of Mysqldump. Note that in the case of an SQLite database @@ -200,9 +215,11 @@ $this->_dumpSettings = self::array_replace_recursive($dumpSettingsDefault, $dump ## Dump Settings - **include-tables** - - Only include these tables (array of table names), include all if empty + - Only include these tables (array of table names), include all if empty. - **exclude-tables** - - Exclude these tables (array of table names), include all if empty, supports regexps + - Exclude these tables (array of table names), include all if empty, supports regexps. +- **include-views** + - Only include these views (array of view names), include all if empty. By default, all views named as the include-tables array are included. - **compress** - Gzip, Bzip2, None. - Could be specified using the declared consts: IMysqldump\Mysqldump::GZIP, IMysqldump\Mysqldump::BZIP2 or IMysqldump\Mysqldump::NONE diff --git a/e107_handlers/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php b/e107_handlers/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php index 06d3ff71d..bd870ca21 100644 --- a/e107_handlers/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php +++ b/e107_handlers/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php @@ -83,7 +83,9 @@ class Mysqldump private $pdoSettings = array(); private $version; private $tableColumnTypes = array(); + private $transformTableRowCallable; private $transformColumnValueCallable; + private $infoCallable; /** * Database name, parsed from dsn. @@ -112,6 +114,7 @@ class Mysqldump private $tableWheres = array(); private $tableLimits = array(); + /** * Constructor of Mysqldump. Note that in the case of an SQLite database * connection, the filename must be in the $db parameter. @@ -132,6 +135,7 @@ class Mysqldump $dumpSettingsDefault = array( 'include-tables' => array(), 'exclude-tables' => array(), + 'include-views' => array(), 'compress' => Mysqldump::NONE, 'init_commands' => array(), 'no-data' => array(), @@ -196,8 +200,10 @@ class Mysqldump throw new Exception("Include-tables and exclude-tables should be arrays"); } - // Dump the same views as tables, mimic mysqldump behaviour - $this->dumpSettings['include-views'] = $this->dumpSettings['include-tables']; + // If no include-views is passed in, dump the same views as tables, mimic mysqldump behaviour. + if (!isset($dumpSettings['include-views'])) { + $this->dumpSettings['include-views'] = $this->dumpSettings['include-tables']; + } // Create a new compressManager to manage compressed output $this->compressManager = CompressManagerFactory::create($this->dumpSettings['compress']); @@ -723,6 +729,7 @@ class Mysqldump foreach ($this->triggers as $trigger) { $this->getTriggerStructure($trigger); } + } /** @@ -1011,12 +1018,20 @@ class Mysqldump * * @return array */ - private function prepareColumnValues($tableName, $row) + private function prepareColumnValues($tableName, array $row) { $ret = array(); $columnTypes = $this->tableColumnTypes[$tableName]; + + if ($this->transformTableRowCallable) { + $row = call_user_func($this->transformTableRowCallable, $tableName, $row); + } + foreach ($row as $colName => $colValue) { - $colValue = $this->hookTransformColumnValue($tableName, $colName, $colValue, $row); + if ($this->transformColumnValueCallable) { + $colValue = call_user_func($this->transformColumnValueCallable, $tableName, $colName, $colValue, $row); + } + $ret[] = $this->escape($colValue, $columnTypes[$colName]); } @@ -1049,38 +1064,41 @@ class Mysqldump } /** - * Set a callable that will will be used to transform column values. + * Set a callable that will be used to transform table rows * * @param callable $callable * * @return void */ + public function setTransformTableRowHook($callable) + { + $this->transformTableRowCallable = $callable; + } + + /** + * Set a callable that will be used to transform column values + * + * @param callable $callable + * + * @return void + * + * @deprecated Use setTransformTableRowHook instead for better performance + */ public function setTransformColumnValueHook($callable) { $this->transformColumnValueCallable = $callable; } /** - * Give extending classes an opportunity to transform column values + * Set a callable that will be used to report dump information * - * @param string $tableName Name of table which contains rows - * @param string $colName Name of the column in question - * @param string $colValue Value of the column in question + * @param callable $callable * - * @return string + * @return void */ - protected function hookTransformColumnValue($tableName, $colName, $colValue, $row) + public function setInfoHook($callable) { - if (!$this->transformColumnValueCallable) { - return $colValue; - } - - return call_user_func_array($this->transformColumnValueCallable, array( - $tableName, - $colName, - $colValue, - $row - )); + $this->infoCallable = $callable; } /** @@ -1157,6 +1175,10 @@ class Mysqldump } $this->endListValues($tableName, $count); + + if ($this->infoCallable) { + call_user_func($this->infoCallable, 'table', array('name' => $tableName, 'rowCount' => $count)); + } } /** @@ -1458,39 +1480,39 @@ class CompressNone extends CompressManagerFactory class CompressGzipstream extends CompressManagerFactory { - private $fileHandler = null; + private $fileHandler = null; - private $compressContext; + private $compressContext; - /** - * @param string $filename - */ - public function open($filename) - { + /** + * @param string $filename + */ + public function open($filename) + { $this->fileHandler = fopen($filename, "wb"); if (false === $this->fileHandler) { - throw new Exception("Output file is not writable"); + throw new Exception("Output file is not writable"); } $this->compressContext = deflate_init(ZLIB_ENCODING_GZIP, array('level' => 9)); return true; - } + } - public function write($str) - { + public function write($str) + { $bytesWritten = fwrite($this->fileHandler, deflate_add($this->compressContext, $str, ZLIB_NO_FLUSH)); if (false === $bytesWritten) { - throw new Exception("Writting to file failed! Probably, there is no more free space left?"); + throw new Exception("Writting to file failed! Probably, there is no more free space left?"); } return $bytesWritten; - } + } - public function close() - { + public function close() + { fwrite($this->fileHandler, deflate_add($this->compressContext, '', ZLIB_FINISH)); return fclose($this->fileHandler); - } + } } /** @@ -1942,7 +1964,7 @@ class TypeAdapterMysql extends TypeAdapterFactory "Please check 'https://bugs.mysql.com/bug.php?id=14564'"); } $procedureStmt = $row['Create Procedure']; - if ( $this->dumpSettings['skip-definer'] ) { + if ($this->dumpSettings['skip-definer']) { if ($procedureStmtReplaced = preg_replace( '/^(CREATE)\s+('.self::DEFINER_RE.')?\s+(PROCEDURE\s.*)$/s', '\1 \3', @@ -2132,7 +2154,7 @@ class TypeAdapterMysql extends TypeAdapterFactory public function start_transaction() { - return "START TRANSACTION " . + return "START TRANSACTION ". "/*!40100 WITH CONSISTENT SNAPSHOT */"; } diff --git a/e107_handlers/vendor/phpmailer/phpmailer/README.md b/e107_handlers/vendor/phpmailer/phpmailer/README.md index d8a0f4e3b..c287e307a 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/README.md +++ b/e107_handlers/vendor/phpmailer/phpmailer/README.md @@ -102,8 +102,8 @@ try { $mail->SMTPAuth = true; // Enable SMTP authentication $mail->Username = 'user@example.com'; // SMTP username $mail->Password = 'secret'; // SMTP password - $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted - $mail->Port = 587; // TCP port to connect to + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged + $mail->Port = 587; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above //Recipients $mail->setFrom('from@example.com', 'Mailer'); @@ -155,7 +155,7 @@ Note that in order to reduce PHPMailer's deployed code footprint, the examples a Complete generated API documentation is [available online](http://phpmailer.github.io/PHPMailer/). -You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/phpmailerTest.php) a good source of how to do various operations such as encryption. +You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good source of how to do various operations such as encryption. If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting). diff --git a/e107_handlers/vendor/phpmailer/phpmailer/SECURITY.md b/e107_handlers/vendor/phpmailer/phpmailer/SECURITY.md index 5e917cd04..fc3e61c20 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/SECURITY.md +++ b/e107_handlers/vendor/phpmailer/phpmailer/SECURITY.md @@ -2,6 +2,8 @@ Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. +PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs in `Content-Type` and `Content-Disposition` when filenames passed into `addAttachment` and other methods that accept attachment names contain double quote characters, in contravention of RFC822 3.4.1. No specific vulnerability has been found relating to this, but it could allow file attachments to bypass attachment filters that are based on matching filename extensions. Recorded as [CVE-2020-13625](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-13625). Reported by Elar Lang of Clarified Security. + PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr. PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. diff --git a/e107_handlers/vendor/phpmailer/phpmailer/VERSION b/e107_handlers/vendor/phpmailer/phpmailer/VERSION index 1879c1be0..3af67b5cb 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/VERSION +++ b/e107_handlers/vendor/phpmailer/phpmailer/VERSION @@ -1 +1 @@ -6.1.4 \ No newline at end of file +6.1.6 \ No newline at end of file diff --git a/e107_handlers/vendor/phpmailer/phpmailer/composer.json b/e107_handlers/vendor/phpmailer/phpmailer/composer.json index fd0695c8a..90d2576f5 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/composer.json +++ b/e107_handlers/vendor/phpmailer/phpmailer/composer.json @@ -19,6 +19,12 @@ "name": "Brent R. Matzelle" } ], + "funding": [ + { + "url": "https://github.com/synchro", + "type": "github" + } + ], "require": { "php": ">=5.5.0", "ext-ctype": "*", diff --git a/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php b/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php index e725f4b47..5febb516e 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php +++ b/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php @@ -2,25 +2,27 @@ /** * Danish PHPMailer language file: refer to English translation for definitive list * @package PHPMailer - * @author Mikael Stokkebro + * @author John Sebastian + * Rewrite and extension of the work by Mikael Stokkebro + * */ -$PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Kunne ikke logge på.'; -$PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; -$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data kunne ikke accepteres.'; -//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Login mislykkedes.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Forbindelse til SMTP serveren kunne ikke oprettes.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.'; +$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold'; $PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; -$PHPMAILER_LANG['execute'] = 'Kunne ikke køre: '; -$PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; +$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: '; +$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: '; $PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: '; $PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; -$PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.'; -//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; +$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.'; +$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; -$PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; +$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; -//$PHPMAILER_LANG['signing'] = 'Signing Error: '; -//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; -//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; -//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; +$PHPMAILER_LANG['signing'] = 'Signeringsfejl: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: '; +$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: '; +$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: '; diff --git a/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-am.php b/e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-hy.php similarity index 100% rename from e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-am.php rename to e107_handlers/vendor/phpmailer/phpmailer/language/phpmailer.lang-hy.php diff --git a/e107_handlers/vendor/phpmailer/phpmailer/src/PHPMailer.php b/e107_handlers/vendor/phpmailer/phpmailer/src/PHPMailer.php index 127f2b79b..ed14d7c7a 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/src/PHPMailer.php +++ b/e107_handlers/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -64,7 +64,7 @@ class PHPMailer * Options: null (default), 1 = High, 3 = Normal, 5 = low. * When null, the header is not set at all. * - * @var int + * @var int|null */ public $Priority; @@ -745,7 +745,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.1.4'; + const VERSION = '6.1.6'; /** * Error severity: message only, continue processing. @@ -769,11 +769,22 @@ class PHPMailer const STOP_CRITICAL = 2; /** - * SMTP RFC standard line ending. + * The SMTP standard CRLF line break. + * If you want to change line break format, change static::$LE, not this. + */ + const CRLF = "\r\n"; + + /** + * "Folding White Space" a white space string used for line folding. + */ + const FWS = ' '; + + /** + * SMTP RFC standard line ending; Carriage Return, Line Feed. * * @var string */ - protected static $LE = "\r\n"; + protected static $LE = self::CRLF; /** * The maximum line length supported by mail(). @@ -1446,7 +1457,7 @@ class PHPMailer ) { //SMTP mandates RFC-compliant line endings //and it's also used with mail() on Windows - static::setLE("\r\n"); + static::setLE(self::CRLF); } else { //Maintain backward compatibility with legacy Linux command line mailers static::setLE(PHP_EOL); @@ -1553,7 +1564,7 @@ class PHPMailer $this->encodeHeader($this->secureHeader($this->Subject)), $this->MIMEBody ); - $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . static::$LE . + $this->MIMEHeader = static::stripTrailingWSP($this->MIMEHeader) . static::$LE . static::normalizeBreaks($header_dkim) . static::$LE; } @@ -1620,7 +1631,7 @@ class PHPMailer */ protected function sendmailSend($header, $body) { - $header = rtrim($header, "\r\n ") . static::$LE . static::$LE; + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. if (!empty($this->Sender) && self::isShellSafe($this->Sender)) { @@ -1750,7 +1761,7 @@ class PHPMailer */ protected function mailSend($header, $body) { - $header = rtrim($header, "\r\n ") . static::$LE . static::$LE; + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; $toArr = []; foreach ($this->to as $toaddr) { @@ -1839,7 +1850,7 @@ class PHPMailer */ protected function smtpSend($header, $body) { - $header = rtrim($header, "\r\n ") . static::$LE . static::$LE; + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; $bad_rcpt = []; if (!$this->smtpConnect($this->SMTPOptions)) { throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); @@ -2075,6 +2086,7 @@ class PHPMailer 'se' => 'sv', 'rs' => 'sr', 'tg' => 'tl', + 'am' => 'hy', ]; if (isset($renamed_langcodes[$langcode])) { @@ -2511,7 +2523,8 @@ class PHPMailer */ public function getSentMIMEMessage() { - return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . static::$LE . static::$LE . $this->MIMEBody; + return static::stripTrailingWSP($this->MIMEHeader . $this->mailHeader) . + static::$LE . static::$LE . $this->MIMEBody; } /** @@ -2594,7 +2607,7 @@ class PHPMailer $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE; } //Use this as a preamble in all multipart message types - $mimepre = 'This is a multi-part message in MIME format.' . static::$LE; + $mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE; switch ($this->message_type) { case 'inline': $body .= $mimepre; @@ -2949,7 +2962,7 @@ class PHPMailer $disposition = 'attachment' ) { try { - if (!static::isPermittedPath($path) || !@is_file($path)) { + if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); } @@ -3051,9 +3064,9 @@ class PHPMailer //Only include a filename property if we have one if (!empty($name)) { $mime[] = sprintf( - 'Content-Type: %s; name="%s"%s', + 'Content-Type: %s; name=%s%s', $type, - $this->encodeHeader($this->secureHeader($name)), + static::quotedString($this->encodeHeader($this->secureHeader($name))), static::$LE ); } else { @@ -3073,24 +3086,14 @@ class PHPMailer $mime[] = 'Content-ID: <' . $this->encodeHeader($this->secureHeader($cid)) . '>' . static::$LE; } - // If a filename contains any of these chars, it should be quoted, - // but not otherwise: RFC2183 & RFC2045 5.1 - // Fixes a warning in IETF's msglint MIME checker - // Allow for bypassing the Content-Disposition header totally + // Allow for bypassing the Content-Disposition header if (!empty($disposition)) { $encoded_name = $this->encodeHeader($this->secureHeader($name)); - if (preg_match('/[ ()<>@,;:"\/\[\]?=]/', $encoded_name)) { - $mime[] = sprintf( - 'Content-Disposition: %s; filename="%s"%s', - $disposition, - $encoded_name, - static::$LE . static::$LE - ); - } elseif (!empty($encoded_name)) { + if (!empty($encoded_name)) { $mime[] = sprintf( 'Content-Disposition: %s; filename=%s%s', $disposition, - $encoded_name, + static::quotedString($encoded_name), static::$LE . static::$LE ); } else { @@ -3134,7 +3137,7 @@ class PHPMailer protected function encodeFile($path, $encoding = self::ENCODING_BASE64) { try { - if (!static::isPermittedPath($path) || !file_exists($path)) { + if (!static::isPermittedPath($path) || !file_exists($path) || !is_readable($path)) { throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE); } $file_buffer = file_get_contents($path); @@ -3146,6 +3149,10 @@ class PHPMailer return $file_buffer; } catch (Exception $exc) { $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } return ''; } @@ -3516,7 +3523,7 @@ class PHPMailer $disposition = 'inline' ) { try { - if (!static::isPermittedPath($path) || !@is_file($path)) { + if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); } @@ -3935,15 +3942,28 @@ class PHPMailer * * @param string $name Custom header name * @param string|null $value Header value + * + * @throws Exception */ public function addCustomHeader($name, $value = null) { - if (null === $value) { + if (null === $value && strpos($name, ':') !== false) { // Value passed in as name:value - $this->CustomHeader[] = explode(':', $name, 2); - } else { - $this->CustomHeader[] = [$name, $value]; + list($name, $value) = explode(':', $name, 2); } + $name = trim($name); + $value = trim($value); + //Ensure name is not empty, and that neither name nor value contain line breaks + if (empty($name) || strpbrk($name . $value, "\r\n") !== false) { + if ($this->exceptions) { + throw new Exception('Invalid header name or value'); + } + + return false; + } + $this->CustomHeader[] = [$name, $value]; + + return true; } /** @@ -3987,6 +4007,7 @@ class PHPMailer foreach ($images[2] as $imgindex => $url) { // Convert data URIs into embedded images //e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" + $match = []; if (preg_match('#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match)) { if (count($match) === 4 && static::ENCODING_BASE64 === $match[2]) { $data = base64_decode($match[3]); @@ -4355,7 +4376,7 @@ class PHPMailer $breaktype = static::$LE; } // Normalise to \n - $text = str_replace(["\r\n", "\r"], "\n", $text); + $text = str_replace([self::CRLF, "\r"], "\n", $text); // Now convert LE as needed if ("\n" !== $breaktype) { $text = str_replace("\n", $breaktype, $text); @@ -4364,6 +4385,18 @@ class PHPMailer return $text; } + /** + * Remove trailing breaks from a string. + * + * @param string $text + * + * @return string The text to remove breaks from + */ + public static function stripTrailingWSP($text) + { + return rtrim($text, " \r\n\t"); + } + /** * Return the current line break format string. * @@ -4472,13 +4505,15 @@ class PHPMailer */ public function DKIM_HeaderC($signHeader) { + //Normalize breaks to CRLF (regardless of the mailer) + $signHeader = static::normalizeBreaks($signHeader, self::CRLF); + //Unfold header lines //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` //@see https://tools.ietf.org/html/rfc5322#section-2.2 //That means this may break if you do something daft like put vertical tabs in your headers. - //Unfold header lines $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); //Break headers out into an array - $lines = explode("\r\n", $signHeader); + $lines = explode(self::CRLF, $signHeader); foreach ($lines as $key => $line) { //If the header is missing a :, skip it as it's invalid //This is likely to happen because the explode() above will also split @@ -4498,7 +4533,7 @@ class PHPMailer $lines[$key] = trim($heading, " \t") . ':' . trim($value, " \t"); } - return implode("\r\n", $lines); + return implode(self::CRLF, $lines); } /** @@ -4515,13 +4550,13 @@ class PHPMailer public function DKIM_BodyC($body) { if (empty($body)) { - return "\r\n"; + return self::CRLF; } // Normalize line endings to CRLF - $body = static::normalizeBreaks($body, "\r\n"); + $body = static::normalizeBreaks($body, self::CRLF); //Reduce multiple trailing line breaks to a single one - return rtrim($body, "\r\n") . "\r\n"; + return static::stripTrailingWSP($body) . self::CRLF; } /** @@ -4542,17 +4577,18 @@ class PHPMailer $DKIMquery = 'dns/txt'; // Query method $DKIMtime = time(); //Always sign these headers without being asked + //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 $autoSignHeaders = [ - 'From', - 'To', - 'CC', - 'Date', - 'Subject', - 'Reply-To', - 'Message-ID', - 'Content-Type', - 'Mime-Version', - 'X-Mailer', + 'from', + 'to', + 'cc', + 'date', + 'subject', + 'reply-to', + 'message-id', + 'content-type', + 'mime-version', + 'x-mailer', ]; if (stripos($headers_line, 'Subject') === false) { $headers_line .= 'Subject: ' . $subject . static::$LE; @@ -4587,7 +4623,7 @@ class PHPMailer $headersToSign = []; foreach ($parsedHeaders as $header) { //Is this header one that must be included in the DKIM signature? - if (in_array($header['label'], $autoSignHeaders, true)) { + if (in_array(strtolower($header['label']), $autoSignHeaders, true)) { $headersToSignKeys[] = $header['label']; $headersToSign[] = $header['label'] . ': ' . $header['value']; if ($this->DKIM_copyHeaderFields) { @@ -4625,9 +4661,9 @@ class PHPMailer //Fold long values if (strlen($copiedHeader) > self::STD_LINE_LENGTH - 3) { $copiedHeaderFields .= substr( - chunk_split($copiedHeader, self::STD_LINE_LENGTH - 3, static::$LE . ' '), + chunk_split($copiedHeader, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS), 0, - -strlen(static::$LE . ' ') + -strlen(static::$LE . self::FWS) ); } else { $copiedHeaderFields .= $copiedHeader; @@ -4639,7 +4675,6 @@ class PHPMailer $headerKeys = ' h=' . implode(':', $headersToSignKeys) . ';' . static::$LE; $headerValues = implode(static::$LE, $headersToSign); $body = $this->DKIM_BodyC($body); - $DKIMlen = strlen($body); // Length of body $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body $ident = ''; if ('' !== $this->DKIM_identity) { @@ -4653,7 +4688,6 @@ class PHPMailer ' s=' . $this->DKIM_selector . ';' . static::$LE . ' a=' . $DKIMsignatureType . ';' . ' q=' . $DKIMquery . ';' . - ' l=' . $DKIMlen . ';' . ' t=' . $DKIMtime . ';' . ' c=' . $DKIMcanonicalization . ';' . static::$LE . $headerKeys . @@ -4666,9 +4700,9 @@ class PHPMailer $headerValues . static::$LE . $dkimSignatureHeader ); $signature = $this->DKIM_Sign($canonicalizedHeaders); - $signature = trim(chunk_split($signature, self::STD_LINE_LENGTH - 3, static::$LE . ' ')); + $signature = trim(chunk_split($signature, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS)); - return static::normalizeBreaks($dkimSignatureHeader . $signature) . static::$LE; + return static::normalizeBreaks($dkimSignatureHeader . $signature); } /** @@ -4684,6 +4718,28 @@ class PHPMailer return (bool) preg_match('/^(.{' . (self::MAX_LINE_LENGTH + strlen(static::$LE)) . ',})/m', $str); } + /** + * If a string contains any "special" characters, double-quote the name, + * and escape any double quotes with a backslash. + * + * @param string $str + * + * @return string + * + * @see RFC822 3.4.1 + */ + public static function quotedString($str) + { + if (preg_match('/[ ()<>@,;:"\/\[\]?=]/', $str)) { + //If the string contains any of these chars, it must be double-quoted + //and any double quotes must be escaped with a backslash + return '"' . str_replace('"', '\\"', $str) . '"'; + } + + //Return the string untouched, it doesn't need quoting + return $str; + } + /** * Allows for public read access to 'to' property. * Before the send() call, queued addresses (i.e. with IDN) are not yet included. diff --git a/e107_handlers/vendor/phpmailer/phpmailer/src/POP3.php b/e107_handlers/vendor/phpmailer/phpmailer/src/POP3.php index 50d5f0c2b..7d4c88f6c 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/src/POP3.php +++ b/e107_handlers/vendor/phpmailer/phpmailer/src/POP3.php @@ -45,7 +45,7 @@ class POP3 * * @var string */ - const VERSION = '6.1.4'; + const VERSION = '6.1.6'; /** * Default POP3 port number. @@ -230,6 +230,8 @@ class POP3 } // connect to the POP3 server + $errno = 0; + $errstr = ''; $this->pop_conn = fsockopen( $host, // POP3 Host $port, // Port # diff --git a/e107_handlers/vendor/phpmailer/phpmailer/src/SMTP.php b/e107_handlers/vendor/phpmailer/phpmailer/src/SMTP.php index c693f4d46..aa5555149 100644 --- a/e107_handlers/vendor/phpmailer/phpmailer/src/SMTP.php +++ b/e107_handlers/vendor/phpmailer/phpmailer/src/SMTP.php @@ -34,7 +34,7 @@ class SMTP * * @var string */ - const VERSION = '6.1.4'; + const VERSION = '6.1.6'; /** * SMTP line break constant. @@ -1168,7 +1168,7 @@ class SMTP //Must pass vars in here as params are by reference if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { $this->edebug( - 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', + 'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL ); break; @@ -1187,7 +1187,7 @@ class SMTP $info = stream_get_meta_data($this->smtp_conn); if ($info['timed_out']) { $this->edebug( - 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', + 'SMTP -> get_lines(): stream timed-out (' . $this->Timeout . ' sec)', self::DEBUG_LOWLEVEL ); break; @@ -1344,6 +1344,7 @@ class SMTP } else { $this->last_smtp_transaction_id = false; foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { + $matches = []; if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) { $this->last_smtp_transaction_id = trim($matches[1]); break; diff --git a/e107_tests/tests/unit/e_user_providerTest.php b/e107_tests/tests/unit/e_user_providerTest.php index 658278758..8c54fe4ca 100644 --- a/e107_tests/tests/unit/e_user_providerTest.php +++ b/e107_tests/tests/unit/e_user_providerTest.php @@ -34,7 +34,7 @@ class e_user_providerTest extends \Codeception\Test\Unit $this->assertIsArray($result); $this->assertContains("Facebook", $result); $this->assertContains("Twitter", $result); - $this->assertCount(45, $result, + $this->assertCount(46, $result, "The number of Hybridauth providers has changed! If this is intentional, note the change " . "in Hybridauth providers in the release changelog and update the count in this test." );