mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Fix GH-16314 "Pdo\Mysql object is uninitialized" when opening a persistent connection (#16369)
This commit is contained in:
parent
fd1dff988e
commit
a5f137821a
6 changed files with 153 additions and 7 deletions
2
NEWS
2
NEWS
|
@ -47,6 +47,8 @@ PHP NEWS
|
||||||
- PDO:
|
- PDO:
|
||||||
. Fixed bug GH-16167 (Prevent mixing PDO sub-classes with different DSN).
|
. Fixed bug GH-16167 (Prevent mixing PDO sub-classes with different DSN).
|
||||||
(kocsismate)
|
(kocsismate)
|
||||||
|
. Fixed bug GH-16314 ("Pdo\Mysql object is uninitialized" when opening a
|
||||||
|
persistent connection). (kocsismate)
|
||||||
|
|
||||||
- PDO_ODBC:
|
- PDO_ODBC:
|
||||||
. Fixed bug GH-16450 (PDO_ODBC can inject garbage into field values). (cmb)
|
. Fixed bug GH-16450 (PDO_ODBC can inject garbage into field values). (cmb)
|
||||||
|
|
|
@ -436,8 +436,16 @@ PDO_API void php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAMETERS, zen
|
||||||
|
|
||||||
if (pdbh) {
|
if (pdbh) {
|
||||||
efree(dbh);
|
efree(dbh);
|
||||||
|
|
||||||
|
pdo_dbh_object_t *pdo_obj;
|
||||||
|
if (new_zval_object) {
|
||||||
|
pdo_obj = Z_PDO_OBJECT_P(new_zval_object);
|
||||||
|
} else {
|
||||||
|
pdo_obj = php_pdo_dbh_fetch_object(current_object);
|
||||||
|
}
|
||||||
|
|
||||||
/* switch over to the persistent one */
|
/* switch over to the persistent one */
|
||||||
php_pdo_dbh_fetch_object(current_object)->inner = pdbh;
|
pdo_obj->inner = pdbh;
|
||||||
pdbh->refcount++;
|
pdbh->refcount++;
|
||||||
dbh = pdbh;
|
dbh = pdbh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ if (getenv('PDOTEST_DSN') === false) {
|
||||||
class PDOTest {
|
class PDOTest {
|
||||||
// create an instance of the PDO driver, based on
|
// create an instance of the PDO driver, based on
|
||||||
// the current environment
|
// the current environment
|
||||||
static function factory($classname = PDO::class) {
|
static function factory($classname = PDO::class, bool $useConnectMethod = false) {
|
||||||
$dsn = getenv('PDOTEST_DSN');
|
$dsn = getenv('PDOTEST_DSN');
|
||||||
$user = getenv('PDOTEST_USER');
|
$user = getenv('PDOTEST_USER');
|
||||||
$pass = getenv('PDOTEST_PASS');
|
$pass = getenv('PDOTEST_PASS');
|
||||||
|
@ -32,7 +32,11 @@ class PDOTest {
|
||||||
if ($user === false) $user = NULL;
|
if ($user === false) $user = NULL;
|
||||||
if ($pass === false) $pass = NULL;
|
if ($pass === false) $pass = NULL;
|
||||||
|
|
||||||
|
if ($useConnectMethod) {
|
||||||
|
$db = $classname::connect($dsn, $user, $pass, $attr);
|
||||||
|
} else {
|
||||||
$db = new $classname($dsn, $user, $pass, $attr);
|
$db = new $classname($dsn, $user, $pass, $attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$db) {
|
if (!$db) {
|
||||||
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
|
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
|
||||||
|
@ -54,12 +58,12 @@ class PDOTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function test_factory($file, $classname = PDO::class) {
|
static function test_factory($file, $classname = PDO::class, bool $useConnectMethod = false) {
|
||||||
$config = self::get_config($file);
|
$config = self::get_config($file);
|
||||||
foreach ($config['ENV'] as $k => $v) {
|
foreach ($config['ENV'] as $k => $v) {
|
||||||
putenv("$k=$v");
|
putenv("$k=$v");
|
||||||
}
|
}
|
||||||
return self::factory($classname);
|
return self::factory($classname, $useConnectMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function get_config($file) {
|
static function get_config($file) {
|
||||||
|
|
62
ext/pdo_mysql/tests/gh16314.phpt
Normal file
62
ext/pdo_mysql/tests/gh16314.phpt
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16314 "Pdo\Mysql object is uninitialized" when opening a persistent connection
|
||||||
|
--EXTENSIONS--
|
||||||
|
pdo_mysql
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||||
|
MySQLPDOTest::skip();
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||||
|
|
||||||
|
$pdo = MySQLPDOTest::factory(Pdo\Mysql::class, null, [PDO::ATTR_PERSISTENT => true], false);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = MySQLPDOTest::factory(Pdo\Mysql::class, null, [PDO::ATTR_PERSISTENT => true], true);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = MySQLPDOTest::factory(Pdo::class, null, [PDO::ATTR_PERSISTENT => true], false);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = MySQLPDOTest::factory(Pdo::class, null, [PDO::ATTR_PERSISTENT => true], true);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
[1]=>
|
||||||
|
int(1)
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
[1]=>
|
||||||
|
int(1)
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
[1]=>
|
||||||
|
int(1)
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
[1]=>
|
||||||
|
int(1)
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ foreach ($env as $k => $v) {
|
||||||
|
|
||||||
class MySQLPDOTest extends PDOTest {
|
class MySQLPDOTest extends PDOTest {
|
||||||
|
|
||||||
static function factory($classname = PDO::class, $mydsn = null, $myAttr = null) {
|
static function factory($classname = PDO::class, $mydsn = null, $myAttr = null, bool $useConnectMethod = false) {
|
||||||
$dsn = self::getDSN($mydsn);
|
$dsn = self::getDSN($mydsn);
|
||||||
$user = PDO_MYSQL_TEST_USER;
|
$user = PDO_MYSQL_TEST_USER;
|
||||||
$pass = PDO_MYSQL_TEST_PASS;
|
$pass = PDO_MYSQL_TEST_PASS;
|
||||||
|
@ -20,7 +20,12 @@ class MySQLPDOTest extends PDOTest {
|
||||||
$attr = is_string($attr) && strlen($attr) ? unserialize($attr) : null;
|
$attr = is_string($attr) && strlen($attr) ? unserialize($attr) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($useConnectMethod) {
|
||||||
|
$db = $classname::connect($dsn, $user, $pass, $attr);
|
||||||
|
} else {
|
||||||
$db = new $classname($dsn, $user, $pass, $attr);
|
$db = new $classname($dsn, $user, $pass, $attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$db) {
|
if (!$db) {
|
||||||
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
|
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
|
||||||
}
|
}
|
||||||
|
|
65
ext/pdo_pgsql/tests/gh16314.phpt
Normal file
65
ext/pdo_pgsql/tests/gh16314.phpt
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16314 "Pdo\Pgsql object is uninitialized" when opening a persistent connection
|
||||||
|
--EXTENSIONS--
|
||||||
|
pdo_pgsql
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require __DIR__ . '/config.inc';
|
||||||
|
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
PDOTest::skip();
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
putenv('PDOTEST_ATTR='.serialize([PDO::ATTR_PERSISTENT => true]));
|
||||||
|
|
||||||
|
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
|
||||||
|
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt', Pdo\Pgsql::class, false);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt', Pdo\Pgsql::class, true);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt', Pdo::class, false);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
|
||||||
|
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt', Pdo::class, true);
|
||||||
|
var_dump($pdo->query('SELECT 1;')->fetchAll());
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
["?column?"]=>
|
||||||
|
string(1) "1"
|
||||||
|
[0]=>
|
||||||
|
string(1) "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
["?column?"]=>
|
||||||
|
string(1) "1"
|
||||||
|
[0]=>
|
||||||
|
string(1) "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
["?column?"]=>
|
||||||
|
string(1) "1"
|
||||||
|
[0]=>
|
||||||
|
string(1) "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
["?column?"]=>
|
||||||
|
string(1) "1"
|
||||||
|
[0]=>
|
||||||
|
string(1) "1"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue