Skip to content

Commit 811ba21

Browse files
committed
Prevent direct instantiation of com_safearray_proxy
The `com_safearray_proxy` class is meant for internal usage, but so far it was possible to instantiate it from userland, although that made no sense. However, a while ago there was a relevant change[1], namely that its `default_object_handlers` are now assigned when the class is registered, while previously they only have been assigned when an instance had been created internally. So now when freeing a manually created object, `free_obj()` is called, although the object never has been properly initialized (causing segfaults). We fix this by introducing a `create_object()` handler which properly initializes the object with dummy values. Since a manually created `com_safearray_proxy` still does not make sense, we disallow its instantiation. [1] <94ee4f9>
1 parent 13b82ee commit 811ba21

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

ext/com_dotnet/com_extension.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ PHP_MINIT_FUNCTION(com_dotnet)
183183

184184
php_com_saproxy_class_entry = register_class_com_safearray_proxy();
185185
/* php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
186+
php_com_saproxy_class_entry->create_object = php_com_saproxy_create_object;
186187
php_com_saproxy_class_entry->default_object_handlers = &php_com_saproxy_handlers;
187188
php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get;
188189

ext/com_dotnet/com_saproxy.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ typedef struct {
5757

5858
#define SA_FETCH(zv) (php_com_saproxy*)Z_OBJ_P(zv)
5959

60+
zend_object *php_com_saproxy_create_object(zend_class_entry *class_type) {
61+
php_com_saproxy *intern = zend_object_alloc(sizeof(php_com_saproxy), class_type);
62+
memset((char*)intern + sizeof(zend_object), 0, sizeof(php_com_saproxy) - sizeof(zend_object));
63+
64+
zend_object_std_init(&intern->std, class_type);
65+
object_properties_init(&intern->std, class_type);
66+
67+
return &intern->std;
68+
}
69+
6070
static inline void clone_indices(php_com_saproxy *dest, php_com_saproxy *src, int ndims)
6171
{
6272
int i;
@@ -317,7 +327,7 @@ static zend_function *saproxy_method_get(zend_object **object, zend_string *name
317327

318328
static zend_function *saproxy_constructor_get(zend_object *object)
319329
{
320-
/* user cannot instantiate */
330+
zend_throw_error(NULL, "Cannot directly construct com_safeproxy_array; it is for internal usage only");
321331
return NULL;
322332
}
323333

@@ -365,7 +375,9 @@ static void saproxy_free_storage(zend_object *object)
365375
//??? }
366376
//??? }
367377

368-
OBJ_RELEASE(&proxy->obj->zo);
378+
if (&proxy->obj->zo != NULL) {
379+
OBJ_RELEASE(&proxy->obj->zo);
380+
}
369381

370382
zend_object_std_dtor(object);
371383

ext/com_dotnet/php_com_dotnet_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ extern zend_object_handlers php_com_object_handlers;
7676
void php_com_object_enable_event_sink(php_com_dotnet_object *obj, bool enable);
7777

7878
/* com_saproxy.c */
79+
zend_object *php_com_saproxy_create_object(zend_class_entry *class_type);
7980
zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object, int by_ref);
8081
void php_com_saproxy_create(zend_object *com_object, zval *proxy_out, zval *index);
8182
extern zend_object_handlers php_com_saproxy_handlers;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Manual instantiation of com_safearray_proxy is not allowed
3+
--EXTENSIONS--
4+
com_dotnet
5+
--FILE--
6+
<?php
7+
try {
8+
new com_safearray_proxy();
9+
} catch (Error $e) {
10+
echo $e->getMessage(), PHP_EOL;
11+
}
12+
?>
13+
--EXPECT--
14+
Cannot directly construct com_safeproxy_array; it is for internal usage only

0 commit comments

Comments
 (0)