Commit 79871b427f3 for php.net
commit 79871b427f3e4e009d684ac51cfca3f4b6f33d9d
Author: Gina Peter Banyard <girgias@php.net>
Date: Fri Jun 26 10:35:55 2026 +0100
ext/com: remove ability to clone Variants
As it is seriously broken
diff --git a/UPGRADING b/UPGRADING
index 27a095288d3..1c75894512f 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -19,6 +19,10 @@ PHP 8.6 UPGRADE NOTES
1. Backward Incompatible Changes
========================================
+- COM
+ . It is no longer possible to clone variant objects, this is because
+ the cloning behaviour was ill defined.
+
- DOM:
. Properties previously documented as @readonly (e.g. DOMNode::$nodeType,
DOMDocument::$xmlEncoding, DOMEntity::$actualEncoding, ::$encoding,
diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c
index af0b1a24b06..e4b187b3c98 100644
--- a/ext/com_dotnet/com_handlers.c
+++ b/ext/com_dotnet/com_handlers.c
@@ -509,7 +509,7 @@ zend_object_handlers php_com_object_handlers = {
0,
php_com_object_free_storage,
zend_objects_destroy_object,
- php_com_object_clone,
+ NULL, /* clone */
NULL, /* clone_with */
com_property_read,
com_property_write,
@@ -587,30 +587,6 @@ void php_com_object_free_storage(zend_object *object)
zend_object_std_dtor(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;
-}
-
zend_object* php_com_object_new(zend_class_entry *ce)
{
php_com_dotnet_object *obj;
diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h
index 541074a3a8b..c7e065c2487 100644
--- a/ext/com_dotnet/php_com_dotnet_internal.h
+++ b/ext/com_dotnet/php_com_dotnet_internal.h
@@ -66,7 +66,6 @@ extern zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_e
/* com_handlers.c */
zend_object* php_com_object_new(zend_class_entry *ce);
-zend_object* php_com_object_clone(zend_object *object);
void php_com_object_free_storage(zend_object *object);
extern zend_object_handlers php_com_object_handlers;
void php_com_object_enable_event_sink(php_com_dotnet_object *obj, bool enable);
diff --git a/ext/com_dotnet/tests/variant_no_clone.phpt b/ext/com_dotnet/tests/variant_no_clone.phpt
new file mode 100644
index 00000000000..edb0b3996e7
--- /dev/null
+++ b/ext/com_dotnet/tests/variant_no_clone.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Prevent cloning of Variant types as it's broken
+--EXTENSIONS--
+com_dotnet
+
+--FILE--
+<?php
+
+$v = new variant("123");
+
+try {
+ $v2 = clone $v;
+ var_dump($v2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+Error: Trying to clone an uncloneable object of class variant