From d1934cbaa53e6cc2f7fb59aaaa0c154266475544 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 24 Nov 2023 14:47:34 +0100 Subject: [PATCH] Fix GH-12107: When running a stored procedure (that returns a result set) twice, PHP crashes --- ext/mysqli/tests/gh12107.phpt | 59 +++++++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_ps.c | 5 ++- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 ext/mysqli/tests/gh12107.phpt diff --git a/ext/mysqli/tests/gh12107.phpt b/ext/mysqli/tests/gh12107.phpt new file mode 100644 index 0000000000000..ca5dd4ba8f142 --- /dev/null +++ b/ext/mysqli/tests/gh12107.phpt @@ -0,0 +1,59 @@ +--TEST-- +GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +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-- + +--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 diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 15ccec4522beb..10c220bc4b7cb 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -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) {