Commit 94dc6ae8717 for php.net

commit 94dc6ae871763af5b5bd9bbf0aab29beb07ab8ac
Author: Gina Peter Banyard <girgias@php.net>
Date:   Tue Nov 4 00:04:30 2025 +0000

    ext/pgsql: Fix segfaults when attempting to fetch row into a non-instantiable class name (#20180)

    Also fix Windows CI with Postgres and CLEAN sections

    ---------

    Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>

diff --git a/.github/scripts/windows/test_task.bat b/.github/scripts/windows/test_task.bat
index 5762aa32414..8ce65b8bde9 100644
--- a/.github/scripts/windows/test_task.bat
+++ b/.github/scripts/windows/test_task.bat
@@ -38,8 +38,7 @@ if %errorlevel% neq 0 exit /b 3
 rem setup PostgreSQL related exts
 set PGUSER=postgres
 set PGPASSWORD=Password12!
-rem set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!
-echo ^<?php $conn_str = "host=127.0.0.1 dbname=test port=5432 user=%PGUSER% password=%PGPASSWORD%"; ?^> >> "./ext/pgsql/tests/config.inc"
+set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=%PGUSER% password=%PGPASSWORD%
 set PDO_PGSQL_TEST_DSN=pgsql:host=127.0.0.1 port=5432 dbname=test user=%PGUSER% password=%PGPASSWORD%
 set TMP_POSTGRESQL_BIN=%PGBIN%
 "%TMP_POSTGRESQL_BIN%\createdb.exe" test
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index e8fb99c7aca..241dc214d8e 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -1873,7 +1873,10 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
 		zval dataset;

 		ZVAL_COPY_VALUE(&dataset, return_value);
-		object_init_ex(return_value, ce);
+		zend_result obj_initialized = object_init_ex(return_value, ce);
+		if (UNEXPECTED(obj_initialized == FAILURE)) {
+			RETURN_THROWS();
+		}
 		if (!ce->default_properties_count && !ce->__set) {
 			Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
 		} else {
diff --git a/ext/pgsql/tests/config.inc b/ext/pgsql/tests/config.inc
index 66ba4810203..1e48e8d10fa 100644
--- a/ext/pgsql/tests/config.inc
+++ b/ext/pgsql/tests/config.inc
@@ -19,5 +19,3 @@ $view_def    = "CREATE VIEW {$view_name} AS SELECT * FROM {$table_name};";
 $table_def    = "CREATE TABLE {$table_name} (num int, str text, bin bytea);";
 $table_def_92 = "CREATE TABLE {$table_name_92} (textary text[],  jsn json);";
 $field_name = "num";             // For pg_field_num()
-
-?>
diff --git a/ext/pgsql/tests/lcmess.inc b/ext/pgsql/tests/lcmess.inc
index 7c6e0b80ed7..a1bf61e6851 100644
--- a/ext/pgsql/tests/lcmess.inc
+++ b/ext/pgsql/tests/lcmess.inc
@@ -17,5 +17,3 @@ function _set_lc_messages($conn, $lc_messages = 'C')

     return true;
 }
-
-?>
diff --git a/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt
new file mode 100644
index 00000000000..d04e66a043b
--- /dev/null
+++ b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt
@@ -0,0 +1,59 @@
+--TEST--
+pg_fetch_object() with abstract class name
+--EXTENSIONS--
+pgsql
+--SKIPIF--
+<?php
+include("skipif.inc");
+?>
+--FILE--
+<?php
+
+interface I {}
+
+abstract class C {}
+
+enum E {
+	case A;
+}
+
+include "config.inc";
+$table_name = "pg_fetch_object_abstract_class";
+$db = pg_connect($conn_str);
+pg_query($db, "CREATE TABLE {$table_name} (a integer, b text)");
+pg_query($db, "INSERT INTO {$table_name} VALUES(0, 'ABC')");
+
+$sql = "SELECT * FROM $table_name WHERE a = 0";
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'I'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'C'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'E'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--CLEAN--
+<?php
+include('config.inc');
+$db = @pg_connect($conn_str);
+@pg_query($db, "DROP TABLE IF EXISTS pg_fetch_object_abstract_class cascade");
+?>
+--EXPECT--
+Error: Cannot instantiate interface I
+Error: Cannot instantiate abstract class C
+Error: Cannot instantiate enum E
diff --git a/ext/pgsql/tests/skipif.inc b/ext/pgsql/tests/skipif.inc
index 06c3ff65711..2ce5f46e778 100644
--- a/ext/pgsql/tests/skipif.inc
+++ b/ext/pgsql/tests/skipif.inc
@@ -1,4 +1,3 @@
-
 <?php
 // This script prints "skip" unless:
 // * the pgsql extension is built-in or loadable, AND
@@ -47,5 +46,3 @@ function skip_bytea_not_escape()
         die("skip libpq or backend >= 9.0\n");
     }
 }
-
-?>