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