]> granicus.if.org Git - php/commitdiff
Fix #64130: COM obj parameters passed by reference are not updated
authorChristoph M. Becker <cmbecker69@gmx.de>
Wed, 26 Aug 2020 12:45:13 +0000 (14:45 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Wed, 26 Aug 2020 12:50:04 +0000 (14:50 +0200)
`ITypeInfo_GetIDsOfNames()` is supposed to fail with `E_NOTIMPL` for
out-of-process servers, thus we should not remove the already available
typeinfo of the object in this case.

We also properly free the `byref_vals`.

NEWS
ext/com_dotnet/com_com.c
ext/com_dotnet/tests/bug64130.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 9666878056632095d609b7c7347685a95d2baa61..722f0a70705769d7ce03291fb4431e3620ef2afe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ PHP                                                                        NEWS
   . Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing).
     (Andy Postnikov)
 
+- COM:
+  . Fixed bug #64130 (COM obj parameters passed by reference are not updated).
+    (cmb)
+
 - OPcache:
   . Fixed bug #80002 (calc free space for new interned string is wrong).
     (t-matsuno)
index c9962835d14c78c46d6d1c88d26b77e050dfddeb..5c6cc5ab14a48d9f9de269a36ce7aec0db11a2b0 100644 (file)
@@ -439,8 +439,9 @@ HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name,
        if (obj->typeinfo) {
                hr = ITypeInfo_GetIDsOfNames(obj->typeinfo, &olename, 1, dispid);
                if (FAILED(hr)) {
+                       HRESULT hr1 = hr;
                        hr = IDispatch_GetIDsOfNames(V_DISPATCH(&obj->v), &IID_NULL, &olename, 1, LOCALE_SYSTEM_DEFAULT, dispid);
-                       if (SUCCEEDED(hr)) {
+                       if (SUCCEEDED(hr) && hr1 != E_NOTIMPL) {
                                /* fall back on IDispatch direct */
                                ITypeInfo_Release(obj->typeinfo);
                                obj->typeinfo = NULL;
@@ -588,6 +589,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
                        }
                }
                efree(vargs);
+               if (byref_vals) efree(byref_vals);
        }
 
        return SUCCEEDED(hr) ? SUCCESS : FAILURE;
diff --git a/ext/com_dotnet/tests/bug64130.phpt b/ext/com_dotnet/tests/bug64130.phpt
new file mode 100644 (file)
index 0000000..0f8e083
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #64130 (COM obj parameters passed by reference are not updated)
+--SKIPIF--
+<?php
+if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
+if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
+try {
+    $ie = new com('InternetExplorer.Application');
+} catch (com_exception $ex) {
+    die("skip {$ex->getMessage()}");
+}
+$ie->quit();
+?>
+--FILE--
+<?php
+$ie = new com('InternetExplorer.Application');
+$x = 0;
+$y = 0;
+try {
+    $ie->clientToWindow($x, $y);
+} catch (com_exception $ex) {}
+var_dump($x > 0, $y > 0);
+$ie->quit();
+?>
+--EXPECT--
+bool(true)
+bool(true)