Skip to content

Commit dc642e8

Browse files
committed
ext/pgsql: Fix segfaults when attemting to fetch row into a non-instantiable class name
1 parent d36109b commit dc642e8

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

ext/pgsql/pgsql.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,11 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
18761876

18771877
ZVAL_COPY_VALUE(&dataset, return_value);
18781878
object_init_ex(return_value, ce);
1879+
if (UNEXPECTED(EG(exception))) {
1880+
zval_ptr_dtor(&dataset);
1881+
zval_ptr_dtor(return_value);
1882+
RETURN_THROWS();
1883+
}
18791884
if (!ce->default_properties_count && !ce->__set) {
18801885
Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
18811886
} else {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
pg_fetch_object() with abstract class name
3+
--EXTENSIONS--
4+
pgsql
5+
--SKIPIF--
6+
<?php
7+
include("skipif.inc");
8+
?>
9+
--FILE--
10+
<?php
11+
12+
interface I {}
13+
14+
abstract class C {}
15+
16+
enum E {
17+
case A;
18+
}
19+
20+
include "config.inc";
21+
$table_name = "pg_fetch_object_abstract_class";
22+
$db = pg_connect($conn_str);
23+
pg_query($db, "CREATE TABLE {$table_name} (a integer, b text)");
24+
pg_query($db, "INSERT INTO {$table_name} VALUES(0, 'ABC')");
25+
26+
$sql = "SELECT * FROM $table_name WHERE a = 0";
27+
28+
try {
29+
$result = pg_query($db, $sql);
30+
var_dump(pg_fetch_object($result, NULL, 'I'));
31+
} catch(Throwable $e) {
32+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
33+
}
34+
35+
try {
36+
$result = pg_query($db, $sql);
37+
var_dump(pg_fetch_object($result, NULL, 'C'));
38+
} catch(Throwable $e) {
39+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
40+
}
41+
42+
try {
43+
$result = pg_query($db, $sql);
44+
var_dump(pg_fetch_object($result, NULL, 'E'));
45+
} catch(Throwable $e) {
46+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
47+
}
48+
49+
--CLEAN--
50+
<?php
51+
include('config.inc');
52+
$db = pg_connect($conn_str);
53+
pg_query($db, "DROP TABLE IF EXISTS pg_fetch_object_abstract_class cascade");
54+
?>
55+
--EXPECT--
56+
Error: Cannot instantiate interface I
57+
Error: Cannot instantiate abstract class C
58+
Error: Cannot instantiate enum E

0 commit comments

Comments
 (0)