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) {