Skip to content

Commit 8772810

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix GH-12107: When running a stored procedure (that returns a result set) twice, PHP crashes
2 parents 120bd36 + 0d21a8d commit 8772810

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ PHP NEWS
1818
- LibXML:
1919
. Fix crashes with entity references and predefined entities. (nielsdos)
2020

21+
- MySQLnd:
22+
. Fixed bug GH-12107 (When running a stored procedure (that returns a result
23+
set) twice, PHP crashes). (nielsdos)
24+
2125
- Opcache:
2226
. Fixed bug GH-13145 (strtok() is not comptime). (ilutov)
2327
. Fixed type inference of range(). (ilutov)

ext/mysqli/tests/gh12107.phpt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
--TEST--
2+
GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes)
3+
--EXTENSIONS--
4+
mysqli
5+
--SKIPIF--
6+
<?php
7+
require_once 'skipifconnectfailure.inc';
8+
?>
9+
--FILE--
10+
<?php
11+
require_once 'connect.inc';
12+
13+
$mysqli = new mysqli("$host:$port", $user, $passwd, $db);
14+
15+
$sql = <<<SQL
16+
CREATE PROCEDURE `gh12107`()
17+
BEGIN
18+
SELECT "hello world";
19+
END;
20+
SQL;
21+
$mysqli->query($sql);
22+
23+
echo "Start or run 1\n";
24+
$stmt = $mysqli->prepare("call `gh12107`()");
25+
$stmt->execute();
26+
$stmt->bind_result($output);
27+
var_dump($stmt->fetch());
28+
var_dump($output);
29+
unset($output);
30+
echo "End of run 1\n";
31+
32+
echo "Start or run 2\n";
33+
$stmt->execute();
34+
$stmt->bind_result($output);
35+
var_dump($stmt->fetch());
36+
var_dump($output);
37+
echo "End of run 2\n";
38+
39+
?>
40+
--CLEAN--
41+
<?php
42+
require_once 'connect.inc';
43+
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
44+
printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
45+
46+
if (!mysqli_query($link, "DROP PROCEDURE IF EXISTS gh12107"))
47+
printf("[c002] Cannot drop procedure, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
48+
49+
mysqli_close($link);
50+
?>
51+
--EXPECT--
52+
Start or run 1
53+
bool(true)
54+
string(11) "hello world"
55+
End of run 1
56+
Start or run 2
57+
bool(true)
58+
string(11) "hello world"
59+
End of run 2

ext/mysqlnd/mysqlnd_ps.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,11 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, const enum_my
652652
Executed, but the user hasn't started to fetch
653653
This will clean also the metadata, but after the EXECUTE call we will
654654
have it again.
655+
stmt->result may be freed and nullified by free_stmt_result, transitively called from flush.
655656
*/
656-
stmt->result->m.free_result_buffers(stmt->result);
657+
if (stmt->result) {
658+
stmt->result->m.free_result_buffers(stmt->result);
659+
}
657660

658661
stmt->state = MYSQLND_STMT_PREPARED;
659662
} else if (stmt->state < MYSQLND_STMT_PREPARED) {

0 commit comments

Comments
 (0)