Fix MySQL Statement has a empty query result when the response field has changed, also Segmentation fault

Closes GH-11551.
This commit is contained in:
Yurun 2023-06-28 16:29:31 +08:00 committed by Kamil Tekiela
parent dc586b121a
commit ca5d48213a
No known key found for this signature in database
GPG Key ID: 0760BDAB1E89A1E3
4 changed files with 160 additions and 1 deletions

3
NEWS
View File

@ -27,6 +27,9 @@ PHP NEWS
. Fixed bug GH-11438 (mysqlnd fails to authenticate with sha256_password . Fixed bug GH-11438 (mysqlnd fails to authenticate with sha256_password
accounts using passwords longer than 19 characters). accounts using passwords longer than 19 characters).
(nielsdos, Kamil Tekiela) (nielsdos, Kamil Tekiela)
. Fixed bug GH-11550 (MySQL Statement has a empty query result when
the response field has changed, also Segmentation fault).
(Yurunsoft)
- Opcache: - Opcache:
. Fixed bug GH-11715 (opcache.interned_strings_buffer either has no effect or . Fixed bug GH-11715 (opcache.interned_strings_buffer either has no effect or

View File

@ -0,0 +1,70 @@
--TEST--
Bug GH-11550 (MySQL Statement has a empty query result when the response field has changed, also Segmentation fault)
--EXTENSIONS--
mysqli
--SKIPIF--
<?php
require_once 'skipifconnectfailure.inc';
?>
--FILE--
<?php
require_once 'connect.inc';
$link = new \mysqli($host, $user, $passwd, $db, $port, $socket);
$link->query(<<<'SQL'
CREATE TABLE `test_gh11550` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `name`(`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
SQL);
$link->query(<<<'SQL'
INSERT INTO `test_gh11550` (`name`) VALUES ('test1');
SQL);
$stmt = $link->prepare('select * from test_gh11550');
var_dump('mysqli-1:', $stmt->execute(), $stmt->get_result()->fetch_all());
$link->query(<<<'SQL'
ALTER TABLE `test_gh11550`
ADD COLUMN `a` varchar(255) NOT NULL DEFAULT '';
SQL);
var_dump('mysqli-2:', $stmt->execute(), $stmt->get_result()->fetch_all());
echo 'Done';
?>
--CLEAN--
<?php
require_once 'connect.inc';
$link = new \mysqli($host, $user, $passwd, $db, $port, $socket);
$link->query('DROP TABLE IF EXISTS test_gh11550');
?>
--EXPECT--
string(9) "mysqli-1:"
bool(true)
array(1) {
[0]=>
array(2) {
[0]=>
int(1)
[1]=>
string(5) "test1"
}
}
string(9) "mysqli-2:"
bool(true)
array(1) {
[0]=>
array(3) {
[0]=>
int(1)
[1]=>
string(5) "test1"
[2]=>
string(0) ""
}
}
Done

View File

@ -286,8 +286,12 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
COM_STMT_EXECUTE (even if it is not necessary), so either this or COM_STMT_EXECUTE (even if it is not necessary), so either this or
previous branch always works. previous branch always works.
*/ */
if (rset_header.field_count != stmt->result->field_count) {
stmt->result->m.free_result(stmt->result, TRUE);
stmt->result = conn->m->result_init(rset_header.field_count);
}
result = stmt->result;
} }
result = stmt->result;
} }
if (!result) { if (!result) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(conn->error_info);

View File

@ -0,0 +1,82 @@
--TEST--
Bug GH-11550 (MySQL Statement has a empty query result when the response field has changed, also Segmentation fault)
--EXTENSIONS--
pdo
pdo_mysql
--SKIPIF--
<?php
require_once __DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
MySQLPDOTest::skip();
?>
--FILE--
<?php
require_once __DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$pdo = MySQLPDOTest::factory();
$pdo->exec(<<<'SQL'
CREATE TABLE `test_gh11550` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `name`(`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
SQL);
$pdo->exec(<<<'SQL'
INSERT INTO `test_gh11550` (`name`) VALUES ('test1');
SQL);
$stmt = $pdo->prepare('select * from test_gh11550');
var_dump('PDO-1:', $stmt->execute(), $stmt->fetchAll());
$stmt->closeCursor(); // Optional. Segmentation fault (core dumped)
$pdo->exec(<<<'SQL'
ALTER TABLE `test_gh11550`
ADD COLUMN `a` varchar(255) NOT NULL DEFAULT '';
SQL);
var_dump('PDO-2:', $stmt->execute(), $stmt->fetchAll());
echo 'Done';
?>
--CLEAN--
<?php
require_once __DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$pdo = MySQLPDOTest::factory();
$pdo->query('DROP TABLE IF EXISTS test_gh11550');
?>
--EXPECT--
string(6) "PDO-1:"
bool(true)
array(1) {
[0]=>
array(4) {
["id"]=>
int(1)
[0]=>
int(1)
["name"]=>
string(5) "test1"
[1]=>
string(5) "test1"
}
}
string(6) "PDO-2:"
bool(true)
array(1) {
[0]=>
array(6) {
["id"]=>
int(1)
[0]=>
int(1)
["name"]=>
string(5) "test1"
[1]=>
string(5) "test1"
["a"]=>
string(0) ""
[2]=>
string(0) ""
}
}
Done