diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 2bc33e4ad673..1325736ccf42 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -532,6 +532,10 @@ PHP_FUNCTION(mysqli_execute_query) MYSQLND_PARAM_BIND *params; if (!zend_array_is_list(input_params)) { + if (stmt->query) { + efree(stmt->query); + stmt->query = NULL; + } mysqli_stmt_close(stmt->stmt, false); stmt->stmt = NULL; efree(stmt); @@ -542,6 +546,10 @@ PHP_FUNCTION(mysqli_execute_query) hash_num_elements = zend_hash_num_elements(input_params); param_count = mysql_stmt_param_count(stmt->stmt); if (hash_num_elements != param_count) { + if (stmt->query) { + efree(stmt->query); + stmt->query = NULL; + } mysqli_stmt_close(stmt->stmt, false); stmt->stmt = NULL; efree(stmt); diff --git a/ext/mysqli/tests/mysqli_execute_query_leak.phpt b/ext/mysqli/tests/mysqli_execute_query_leak.phpt new file mode 100644 index 000000000000..11f56877aece --- /dev/null +++ b/ext/mysqli/tests/mysqli_execute_query_leak.phpt @@ -0,0 +1,37 @@ +--TEST-- +mysqli_execute_query() does not leak stmt->query on input_params validation errors with MYSQLI_REPORT_INDEX +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +execute_query('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?', ['foo', 42]); +} catch (ValueError $e) { + echo '[001] '.$e->getMessage()."\n"; +} + +try { + $link->execute_query('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?', ['foo' => 42]); +} catch (ValueError $e) { + echo '[002] '.$e->getMessage()."\n"; +} + +print "done!"; +?> +--CLEAN-- + +--EXPECT-- +[001] mysqli::execute_query(): Argument #2 ($params) must consist of exactly 3 elements, 2 present +[002] mysqli::execute_query(): Argument #2 ($params) must be a list array +done!