Skip to content

Commit c03196a

Browse files
committed
Fix GH-14712: segfault on invalid object.
If the extension does not allow to get a property pointer (like PDORow object), we fallback to the read property cb anyway.
1 parent b08def5 commit c03196a

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ PHP NEWS
1515
- LibXML:
1616
. Fixed bug GH-14563 (Build failure with libxml2 v2.13.0). (nielsdos)
1717

18+
- PDO:
19+
. Fixed bug GH-14712 (Crash with PDORow access to null property).
20+
(David Carlier)
21+
1822
- Phar:
1923
. Fixed bug GH-14603 (null string from zip entry).
2024
(David Carlier)

Zend/zend_execute.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,6 +3127,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
31273127
}
31283128
}
31293129

3130+
/* Pointer on property callback is required */
3131+
ZEND_ASSERT(zobj->handlers->get_property_ptr_ptr != NULL);
3132+
31303133
if (prop_op_type == IS_CONST) {
31313134
name = Z_STR_P(prop_ptr);
31323135
} else {

ext/pdo/pdo_stmt.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2453,6 +2453,16 @@ static zend_function *row_get_ctor(zend_object *object)
24532453
return NULL;
24542454
}
24552455

2456+
static zval *pdo_row_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot)
2457+
{
2458+
ZEND_IGNORE_VALUE(object);
2459+
ZEND_IGNORE_VALUE(name);
2460+
ZEND_IGNORE_VALUE(type);
2461+
ZEND_IGNORE_VALUE(cache_slot);
2462+
2463+
return NULL;
2464+
}
2465+
24562466
void pdo_row_free_storage(zend_object *std)
24572467
{
24582468
pdo_row_t *row = (pdo_row_t *)std;
@@ -2492,7 +2502,7 @@ void pdo_stmt_init(void)
24922502
memcpy(&pdo_row_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
24932503
pdo_row_object_handlers.free_obj = pdo_row_free_storage;
24942504
pdo_row_object_handlers.clone_obj = NULL;
2495-
pdo_row_object_handlers.get_property_ptr_ptr = NULL;
2505+
pdo_row_object_handlers.get_property_ptr_ptr = pdo_row_get_property_ptr_ptr;
24962506
pdo_row_object_handlers.read_property = row_prop_read;
24972507
pdo_row_object_handlers.write_property = row_prop_write;
24982508
pdo_row_object_handlers.has_property = row_prop_exists;

ext/pdo_sqlite/tests/gh14712.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-14712: segfault on PDORow
3+
--EXTENSIONS--
4+
pdo_sqlite
5+
--CREDITS--
6+
YuanchengJiang
7+
--FILE--
8+
<?php
9+
$db = new PDO('sqlite::memory:');
10+
11+
try {
12+
$db->query("select 1 as queryStringxx")->fetch(PDO::FETCH_LAZY)->documentElement->firstChild->nextElementSibling->textContent = "é";
13+
} catch (Error $e) {
14+
echo $e->getMessage();
15+
}
16+
?>
17+
--EXPECT--
18+
Attempt to modify property "firstChild" on null

0 commit comments

Comments
 (0)