From b5a49d144a0dbd116f651d03fba5e3678f11a6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A6=E7=94=B0=20=E6=86=B2=E5=A4=AA=E9=83=8E?= Date: Sun, 23 Aug 2026 13:22:34 +0000 Subject: [PATCH] Fixed PDO::CURSOR_SCROLL statements closing a cursor that was never declared --- NEWS | 4 +++ ext/pdo_pgsql/pgsql_statement.c | 2 +- .../tests/cursor_scroll_without_declare.phpt | 30 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 ext/pdo_pgsql/tests/cursor_scroll_without_declare.phpt diff --git a/NEWS b/NEWS index 519b0ccaf053..bfdbe1225c87 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,10 @@ PHP NEWS . Fixed a leak when a persistent connection failed a liveness check with no other live PDO handle. (iliaal) +- PDO_PGSQL: + . Fixed PDO::CURSOR_SCROLL statements closing a cursor that was never + declared. (KentarouTakeda) + - Phar: . Fixed bug GH-23418 (Use-after-free when looking up mounted directories). (Weilin Du) diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 8f3dd5237b5a..0894faa401f2 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -114,7 +114,7 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt) } if (S->cursor_name) { - if (server_obj_usable) { + if (S->is_prepared && server_obj_usable) { pdo_pgsql_db_handle *H = S->H; char *q = NULL; PGresult *res; diff --git a/ext/pdo_pgsql/tests/cursor_scroll_without_declare.phpt b/ext/pdo_pgsql/tests/cursor_scroll_without_declare.phpt new file mode 100644 index 000000000000..69a8e8add609 --- /dev/null +++ b/ext/pdo_pgsql/tests/cursor_scroll_without_declare.phpt @@ -0,0 +1,30 @@ +--TEST-- +PDO PgSQL PDO::CURSOR_SCROLL sends no CLOSE for a cursor it never declared +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- +beginTransaction(); + +$stmt = $db->prepare('SELECT 1', [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); +unset($stmt); + +$db->exec('SELECT 2'); + +echo 'Done'; + +?> +--EXPECT-- +Done