Skip to content

Cloning of com objects is seriously broken #17602

Open
@cmb69

Description

@cmb69

Description

The following code:

<?php
$v = new variant("123");
$v2 = clone $v;

Resulted in this output:

Assertion failed: (!(((uintptr_t)((executor_globals.objects_store).object_buckets[handle])) & (1<<0))), file Zend\zend_objects_API.c, line 189

But I expected no output instead.


typedef struct _php_com_dotnet_object {
zend_object zo;
VARIANT v;
bool modified;
int code_page;
ITypeInfo *typeinfo;
zend_class_entry *ce;
/* associated event sink */
IDispatch *sink_dispatch;
GUID sink_id;
DWORD sink_cookie;
/* cache for method signatures */
HashTable *method_cache;
/* cache for name -> DISPID */
HashTable *id_of_name_cache;
} php_com_dotnet_object;

zend_object* php_com_object_clone(zend_object *object)
{
php_com_dotnet_object *cloneobj, *origobject;
origobject = (php_com_dotnet_object*) object;
cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object));
memcpy(cloneobj, origobject, sizeof(*cloneobj));
/* VariantCopy will perform VariantClear; we don't want to clobber
* the IDispatch that we memcpy'd, so we init a new variant in the
* clone structure */
VariantInit(&cloneobj->v);
/* We use the Indirection-following version of the API since we
* want to clone as much as possible */
VariantCopyInd(&cloneobj->v, &origobject->v);
if (cloneobj->typeinfo) {
ITypeInfo_AddRef(cloneobj->typeinfo);
}
return (zend_object*)cloneobj;
}

That memcpy() is a "bit" crude, and while we cater to v and typeinfo, we apparently missed sink_dispatch and possibly the elements of method_cache. modified seems to need an reset (not sure, though).

(I also wonder why we store the ce.)

Anyhow, I wonder if that's worth fixing, or whether we should just forbid cloning in the first place; we can still implement proper cloning if requested.

PHP Version

master (but likely since PHP 7, or even before)

Operating System

Windows

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions