Skip to content

Commit 56fb83a

Browse files
Merge pull request #18873 from MauricioFauth/mysqli-exception
Remove trigger_error from Dbal\DbiMysqli::connect()
2 parents f867fce + d974d30 commit 56fb83a

6 files changed

Lines changed: 49 additions & 46 deletions

File tree

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7460,11 +7460,6 @@ parameters:
74607460
count: 1
74617461
path: src/Dbal/DbalInterface.php
74627462

7463-
-
7464-
message: "#^Parameter \\#1 \\$haystack of function stripos expects string, string\\|null given\\.$#"
7465-
count: 1
7466-
path: src/Dbal/DbiMysqli.php
7467-
74687463
-
74697464
message: "#^Method PhpMyAdmin\\\\Dbal\\\\MysqliResult\\:\\:fetchAllAssoc\\(\\) should return array\\<int, array\\<string\\|null\\>\\> but returns array\\.$#"
74707465
count: 1

psalm-baseline.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5273,12 +5273,6 @@
52735273
<DeprecatedMethod>
52745274
<code>Config::getInstance()</code>
52755275
</DeprecatedMethod>
5276-
<PossiblyNullArgument>
5277-
<code>$errorMessage</code>
5278-
</PossiblyNullArgument>
5279-
<PossiblyNullOperand>
5280-
<code>$errorMessage</code>
5281-
</PossiblyNullOperand>
52825276
</file>
52835277
<file src="src/Dbal/MysqliResult.php">
52845278
<InvalidReturnStatement>

src/DatabaseInterface.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpMyAdmin\Config\Settings\Server;
88
use PhpMyAdmin\ConfigStorage\Relation;
99
use PhpMyAdmin\Dbal\Connection;
10+
use PhpMyAdmin\Dbal\ConnectionException;
1011
use PhpMyAdmin\Dbal\DbalInterface;
1112
use PhpMyAdmin\Dbal\DbiExtension;
1213
use PhpMyAdmin\Dbal\DbiMysqli;
@@ -1636,7 +1637,14 @@ public function connect(Server $currentServer, int $connectionType, int|null $ta
16361637
// Do not show location and backtrace for connection errors
16371638
$errorHandler = ErrorHandler::getInstance();
16381639
$errorHandler->setHideLocation(true);
1639-
$result = $this->extension->connect($server);
1640+
try {
1641+
$result = $this->extension->connect($server);
1642+
} catch (ConnectionException $exception) {
1643+
trigger_error($exception->getMessage(), E_USER_WARNING);
1644+
1645+
return null;
1646+
}
1647+
16401648
$errorHandler->setHideLocation(false);
16411649

16421650
if ($result !== null) {

src/Dbal/ConnectionException.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\Dbal;
6+
7+
use Exception;
8+
9+
class ConnectionException extends Exception
10+
{
11+
}

src/Dbal/DbiExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ interface DbiExtension
1717
{
1818
/**
1919
* Connects to the database server.
20+
*
21+
* @throws ConnectionException
2022
*/
2123
public function connect(Server $server): Connection|null;
2224

src/Dbal/DbiMysqli.php

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@
2121
use function mysqli_init;
2222
use function mysqli_report;
2323
use function sprintf;
24-
use function stripos;
25-
use function trigger_error;
24+
use function str_contains;
25+
use function strtolower;
2626

27-
use const E_USER_ERROR;
28-
use const E_USER_WARNING;
2927
use const MYSQLI_CLIENT_COMPRESS;
3028
use const MYSQLI_CLIENT_SSL;
3129
use const MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
@@ -106,35 +104,18 @@ public function connect(Server $server): Connection|null
106104
$server->socket,
107105
$clientFlags,
108106
);
109-
} catch (mysqli_sql_exception) {
110-
/**
111-
* Switch to SSL if server asked us to do so, unfortunately
112-
* there are more ways MySQL server can tell this:
113-
*
114-
* - MySQL 8.0 and newer should return error 3159
115-
* - #2001 - SSL Connection is required. Please specify SSL options and retry.
116-
* - #9002 - SSL connection is required. Please specify SSL options and retry.
117-
*/
118-
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
119-
$errorNumber = $mysqli->connect_errno;
120-
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
121-
$errorMessage = $mysqli->connect_error;
122-
if (
123-
! $server->ssl
124-
&& ($errorNumber == 3159
125-
|| (($errorNumber == 2001 || $errorNumber == 9002)
126-
&& stripos($errorMessage, 'SSL Connection is required') !== false))
127-
) {
128-
trigger_error(
129-
__('SSL connection enforced by server, automatically enabling it.'),
130-
E_USER_WARNING,
131-
);
107+
} catch (mysqli_sql_exception $exception) {
108+
$errorNumber = $exception->getCode();
109+
$errorMessage = $exception->getMessage();
132110

111+
if (! $server->ssl && $this->isSslRequiredByServer($errorNumber, $errorMessage)) {
133112
return self::connect($server->withSSL(true));
134113
}
135114

115+
mysqli_report(MYSQLI_REPORT_OFF);
116+
136117
if ($errorNumber === 1045 && $server->hideConnectionErrors) {
137-
trigger_error(
118+
throw new ConnectionException(
138119
sprintf(
139120
__(
140121
'Error 1045: Access denied for user. Additional error information'
@@ -143,15 +124,12 @@ public function connect(Server $server): Connection|null
143124
'[code][doc@cfg_Servers_hide_connection_errors]'
144125
. '$cfg[\'Servers\'][$i][\'hide_connection_errors\'][/doc][/code]',
145126
),
146-
E_USER_ERROR,
127+
$errorNumber,
128+
$exception,
147129
);
148-
} else {
149-
trigger_error($errorNumber . ': ' . $errorMessage, E_USER_WARNING);
150130
}
151131

152-
mysqli_report(MYSQLI_REPORT_OFF);
153-
154-
return null;
132+
throw new ConnectionException($errorNumber . ': ' . $errorMessage, $errorNumber, $exception);
155133
}
156134

157135
$mysqli->options(MYSQLI_OPT_LOCAL_INFILE, (int) defined('PMA_ENABLE_LDI'));
@@ -356,4 +334,19 @@ public function getWarningCount(Connection $connection): int
356334
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
357335
return $mysqli->warning_count;
358336
}
337+
338+
/**
339+
* Switch to SSL if server asked us to do so, unfortunately
340+
* there are more ways MySQL server can tell this:
341+
*
342+
* - MySQL 8.0 and newer should return error 3159
343+
* - #2001 - SSL Connection is required. Please specify SSL options and retry.
344+
* - #9002 - SSL connection is required. Please specify SSL options and retry.
345+
*/
346+
private function isSslRequiredByServer(int $errorNumber, string $errorMessage): bool
347+
{
348+
return $errorNumber === 3159
349+
|| ($errorNumber === 2001 || $errorNumber === 9002)
350+
&& str_contains(strtolower($errorMessage), 'ssl connection is required');
351+
}
359352
}

0 commit comments

Comments
 (0)