summaryrefslogtreecommitdiff
path: root/ext/com_dotnet
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-08-26 14:45:13 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-08-26 14:50:04 +0200
commit5ff15e2651850ba30dde69056436b8774fac9166 (patch)
tree0c89374826fe821be2fd005e9775fd800b50fde1 /ext/com_dotnet
parentd179e34e42e8e9cc5250ba2265fb50a8187bb6b1 (diff)
downloadphp-git-5ff15e2651850ba30dde69056436b8774fac9166.tar.gz
Fix #64130: COM obj parameters passed by reference are not updated
`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`.
Diffstat (limited to 'ext/com_dotnet')
-rw-r--r--ext/com_dotnet/com_com.c4
-rw-r--r--ext/com_dotnet/tests/bug64130.phpt27
2 files changed, 30 insertions, 1 deletions
diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c
index c9962835d1..5c6cc5ab14 100644
--- a/ext/com_dotnet/com_com.c
+++ b/ext/com_dotnet/com_com.c
@@ -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
index 0000000000..0f8e083295
--- /dev/null
+++ b/ext/com_dotnet/tests/bug64130.phpt
@@ -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)