diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 1bb93e0e2675..20714c38aada 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2255,7 +2255,9 @@ static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */ } if (intern->initialised && intern->db) { - sqlite3_close(intern->db); + /* Use sqlite3_close_v2() because the object may be destroyed while resources depending on the connection are still alive, + * e.g. a blob stream created by SQLite3::openBlob(). */ + sqlite3_close_v2(intern->db); intern->initialised = 0; } diff --git a/ext/sqlite3/tests/sqlite3_close_blob_stream.phpt b/ext/sqlite3/tests/sqlite3_close_blob_stream.phpt new file mode 100644 index 000000000000..d2426445a7cd --- /dev/null +++ b/ext/sqlite3/tests/sqlite3_close_blob_stream.phpt @@ -0,0 +1,22 @@ +--TEST-- +Destroying the SQLite3 object while a blob stream is still open must not leak the connection +--EXTENSIONS-- +sqlite3 +--FILE-- +exec('CREATE TABLE test (data BLOB)'); +$db->exec("INSERT INTO test (data) VALUES (x'34323432')"); + +$stream = $db->openBlob('test', 'data', 1); +var_dump($db->close()); +unset($db); +var_dump(fread($stream, 4)); +fclose($stream); + +?> +--EXPECTF-- +Warning: SQLite3::close(): Unable to close database: %s in %s on line %d +bool(false) +string(4) "4242"