diff --git a/NEWS b/NEWS index 30a30efef6cee..6df288b18f2c0 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ Intl: Opcache: . Added large shared segments support for FreeBSD. (David Carlier) +PDO_PGSQL: + . Fixed GH-12423, DSN credentials being prioritized over the user/password + PDO constructor arguments. (SakiTakamachi) + PGSQL: . Added the possibility to have no conditions for pg_select. (OmarEmaraDev) diff --git a/UPGRADING b/UPGRADING index 5adf37fea828d..fffe92d8234a6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -26,6 +26,10 @@ PHP 8.4 UPGRADE NOTES Consult sections 2. New Features and 6. New Functions for a list of newly implemented methods and constants. +- PDO_PGSQL: + . The DSN's credentials, when set, are given priority over their PDO + constructor counterparts, being closer to the documentation states. + - SimpleXML: . Get methods called, or casting to a string on a SimpleXMLElement will no longer implicitly reset the iterator data, unless explicitly rewound. diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 46b3f25f4086b..531bf14e4bb29 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1281,8 +1281,8 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ } /* escape username and password, if provided */ - tmp_user = _pdo_pgsql_escape_credentials(dbh->username); - tmp_pass = _pdo_pgsql_escape_credentials(dbh->password); + tmp_user = !strstr((char *) dbh->data_source, "user=") ? _pdo_pgsql_escape_credentials(dbh->username) : NULL; + tmp_pass = !strstr((char *) dbh->data_source, "password=") ? _pdo_pgsql_escape_credentials(dbh->password) : NULL; /* support both full connection string & connection string + login and/or password */ if (tmp_user && tmp_pass) { diff --git a/ext/pdo_pgsql/tests/gh12423.phpt b/ext/pdo_pgsql/tests/gh12423.phpt new file mode 100644 index 0000000000000..2f585cb58b4b6 --- /dev/null +++ b/ext/pdo_pgsql/tests/gh12423.phpt @@ -0,0 +1,78 @@ +--TEST-- +GitHub #12424 (Fix GH-12423: [pdo_pgsql] Changed to prioritize DSN authentication information over arguments.) +--SKIPIF-- + +--FILE-- + [ + 'PDOTEST_DSN' => $dsnWithCredentials, + 'PDOTEST_USER' => $user, + 'PDOTEST_PASS' => $password, + ], +] = __DIR__ . '/common.phpt'; + +$dsn = str_replace(" user={$user} password={$password}", '', $dsnWithCredentials); + +echo "dsn without credentials / correct user / correct password\n"; +try { + $db = new PDO($dsn, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + echo "Connected.\n\n"; +} catch (PDOException $e) { + echo $e->getMessage(); +} + +echo "dsn with credentials / no user / no password\n"; +try { + $db = new PDO("{$dsn} user={$user} password={$password}", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + echo "Connected.\n\n"; +} catch (PDOException $e) { + echo $e->getMessage(); +} + +echo "dsn with correct user / incorrect user / correct password\n"; +try { + $db = new PDO("{$dsn} user={$user}", 'hoge', $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + echo "Connected.\n\n"; +} catch (PDOException $e) { + echo $e->getMessage(); +} + +echo "dsn with correct password / correct user / incorrect password\n"; +try { + $db = new PDO("{$dsn} password={$password}", $user, 'fuga', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + echo "Connected.\n\n"; +} catch (PDOException $e) { + echo $e->getMessage(); +} + +echo "dsn with correct credentials / incorrect user / incorrect password\n"; +try { + $db = new PDO("{$dsn} user={$user} password={$password}", 'hoge', 'fuga', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + echo "Connected.\n"; +} catch (PDOException $e) { + echo $e->getMessage(); +} +?> +--EXPECT-- +dsn without credentials / correct user / correct password +Connected. + +dsn with credentials / no user / no password +Connected. + +dsn with correct user / incorrect user / correct password +Connected. + +dsn with correct password / correct user / incorrect password +Connected. + +dsn with correct credentials / incorrect user / incorrect password +Connected.