Skip to content

Fix GH-12107: When running a stored procedure (that returns a result … #12771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions ext/mysqli/tests/gh12107.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes)
--EXTENSIONS--
mysqli
--SKIPIF--
<?php
require_once 'skipifconnectfailure.inc';
?>
--FILE--
<?php
require_once 'connect.inc';

$mysqli = new mysqli("$host:$port", $user, $passwd, $db);

$sql = <<<SQL
CREATE PROCEDURE `gh12107`()
BEGIN
SELECT "hello world";
END;
SQL;
$mysqli->query($sql);

echo "Start or run 1\n";
$stmt = $mysqli->prepare("call `gh12107`()");
$stmt->execute();
$stmt->bind_result($output);
var_dump($stmt->fetch());
var_dump($output);
unset($output);
echo "End of run 1\n";

echo "Start or run 2\n";
$stmt->execute();
$stmt->bind_result($output);
var_dump($stmt->fetch());
var_dump($output);
echo "End of run 2\n";

?>
--CLEAN--
<?php
require_once 'connect.inc';
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());

if (!mysqli_query($link, "DROP PROCEDURE IF EXISTS gh12107"))
printf("[c002] Cannot drop procedure, [%d] %s\n", mysqli_errno($link), mysqli_error($link));

mysqli_close($link);
?>
--EXPECT--
Start or run 1
bool(true)
string(11) "hello world"
End of run 1
Start or run 2
bool(true)
string(11) "hello world"
End of run 2
5 changes: 4 additions & 1 deletion ext/mysqlnd/mysqlnd_ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,11 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, const enum_my
Executed, but the user hasn't started to fetch
This will clean also the metadata, but after the EXECUTE call we will
have it again.
stmt->result may be freed by free_stmt_result, transitively called from flush.
*/
stmt->result->m.free_result_buffers(stmt->result);
if (stmt->result) {
stmt->result->m.free_result_buffers(stmt->result);
}

stmt->state = MYSQLND_STMT_PREPARED;
} else if (stmt->state < MYSQLND_STMT_PREPARED) {
Expand Down