From 8be31eddc18daf6835e2ea694e580b9a938a65c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 29 Dec 2023 13:47:31 -0300 Subject: [PATCH 1/2] Extract method from Dbal\DbiMysqli::connect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracts the isSslRequiredByServer() private method from PhpMyAdmin\Dbal\DbiMysqli::connect(). Uses the error message and code from the exception instead of mysqli object. Signed-off-by: MaurĂ­cio Meneghini Fauth --- phpstan-baseline.neon | 5 ----- psalm-baseline.xml | 6 ------ src/Dbal/DbiMysqli.php | 45 ++++++++++++++++++++---------------------- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index af6952c611..56fa0ce1b5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7460,11 +7460,6 @@ parameters: count: 1 path: src/Dbal/DbalInterface.php - - - message: "#^Parameter \\#1 \\$haystack of function stripos expects string, string\\|null given\\.$#" - count: 1 - path: src/Dbal/DbiMysqli.php - - message: "#^Method PhpMyAdmin\\\\Dbal\\\\MysqliResult\\:\\:fetchAllAssoc\\(\\) should return array\\\\> but returns array\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index cbad0b6158..1cfbe60709 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5273,12 +5273,6 @@ Config::getInstance() - - $errorMessage - - - $errorMessage - diff --git a/src/Dbal/DbiMysqli.php b/src/Dbal/DbiMysqli.php index fa637615ba..c4bfae4b50 100644 --- a/src/Dbal/DbiMysqli.php +++ b/src/Dbal/DbiMysqli.php @@ -21,7 +21,8 @@ use function mysqli_get_client_info; use function mysqli_init; use function mysqli_report; use function sprintf; -use function stripos; +use function str_contains; +use function strtolower; use function trigger_error; use const E_USER_ERROR; @@ -106,30 +107,11 @@ class DbiMysqli implements DbiExtension $server->socket, $clientFlags, ); - } catch (mysqli_sql_exception) { - /** - * Switch to SSL if server asked us to do so, unfortunately - * there are more ways MySQL server can tell this: - * - * - MySQL 8.0 and newer should return error 3159 - * - #2001 - SSL Connection is required. Please specify SSL options and retry. - * - #9002 - SSL connection is required. Please specify SSL options and retry. - */ - // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps - $errorNumber = $mysqli->connect_errno; - // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps - $errorMessage = $mysqli->connect_error; - if ( - ! $server->ssl - && ($errorNumber == 3159 - || (($errorNumber == 2001 || $errorNumber == 9002) - && stripos($errorMessage, 'SSL Connection is required') !== false)) - ) { - trigger_error( - __('SSL connection enforced by server, automatically enabling it.'), - E_USER_WARNING, - ); + } catch (mysqli_sql_exception $exception) { + $errorNumber = $exception->getCode(); + $errorMessage = $exception->getMessage(); + if (! $server->ssl && $this->isSslRequiredByServer($errorNumber, $errorMessage)) { return self::connect($server->withSSL(true)); } @@ -356,4 +338,19 @@ class DbiMysqli implements DbiExtension // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps return $mysqli->warning_count; } + + /** + * Switch to SSL if server asked us to do so, unfortunately + * there are more ways MySQL server can tell this: + * + * - MySQL 8.0 and newer should return error 3159 + * - #2001 - SSL Connection is required. Please specify SSL options and retry. + * - #9002 - SSL connection is required. Please specify SSL options and retry. + */ + private function isSslRequiredByServer(int $errorNumber, string $errorMessage): bool + { + return $errorNumber === 3159 + || ($errorNumber === 2001 || $errorNumber === 9002) + && str_contains(strtolower($errorMessage), 'ssl connection is required'); + } } From d974d30fbbf8fddc7a65e7c11afbc6b4ec42aa83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 29 Dec 2023 14:36:15 -0300 Subject: [PATCH 2/2] Remove trigger_error from Dbal\DbiMysqli::connect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces them with Dbal\ConnectionException. Signed-off-by: MaurĂ­cio Meneghini Fauth --- src/DatabaseInterface.php | 10 +++++++++- src/Dbal/ConnectionException.php | 11 +++++++++++ src/Dbal/DbiExtension.php | 2 ++ src/Dbal/DbiMysqli.php | 16 ++++++---------- 4 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/Dbal/ConnectionException.php diff --git a/src/DatabaseInterface.php b/src/DatabaseInterface.php index 080962264b..9aa7379218 100644 --- a/src/DatabaseInterface.php +++ b/src/DatabaseInterface.php @@ -7,6 +7,7 @@ namespace PhpMyAdmin; use PhpMyAdmin\Config\Settings\Server; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Dbal\Connection; +use PhpMyAdmin\Dbal\ConnectionException; use PhpMyAdmin\Dbal\DbalInterface; use PhpMyAdmin\Dbal\DbiExtension; use PhpMyAdmin\Dbal\DbiMysqli; @@ -1636,7 +1637,14 @@ class DatabaseInterface implements DbalInterface // Do not show location and backtrace for connection errors $errorHandler = ErrorHandler::getInstance(); $errorHandler->setHideLocation(true); - $result = $this->extension->connect($server); + try { + $result = $this->extension->connect($server); + } catch (ConnectionException $exception) { + trigger_error($exception->getMessage(), E_USER_WARNING); + + return null; + } + $errorHandler->setHideLocation(false); if ($result !== null) { diff --git a/src/Dbal/ConnectionException.php b/src/Dbal/ConnectionException.php new file mode 100644 index 0000000000..66f65e819f --- /dev/null +++ b/src/Dbal/ConnectionException.php @@ -0,0 +1,11 @@ +withSSL(true)); } + mysqli_report(MYSQLI_REPORT_OFF); + if ($errorNumber === 1045 && $server->hideConnectionErrors) { - trigger_error( + throw new ConnectionException( sprintf( __( 'Error 1045: Access denied for user. Additional error information' @@ -125,15 +124,12 @@ class DbiMysqli implements DbiExtension '[code][doc@cfg_Servers_hide_connection_errors]' . '$cfg[\'Servers\'][$i][\'hide_connection_errors\'][/doc][/code]', ), - E_USER_ERROR, + $errorNumber, + $exception, ); - } else { - trigger_error($errorNumber . ': ' . $errorMessage, E_USER_WARNING); } - mysqli_report(MYSQLI_REPORT_OFF); - - return null; + throw new ConnectionException($errorNumber . ': ' . $errorMessage, $errorNumber, $exception); } $mysqli->options(MYSQLI_OPT_LOCAL_INFILE, (int) defined('PMA_ENABLE_LDI'));