Skip to content

Commit 5ff15e2

Browse files
committed
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`.
1 parent d179e34 commit 5ff15e2

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ PHP NEWS
66
. Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing).
77
(Andy Postnikov)
88

9+
- COM:
10+
. Fixed bug #64130 (COM obj parameters passed by reference are not updated).
11+
(cmb)
12+
913
- OPcache:
1014
. Fixed bug #80002 (calc free space for new interned string is wrong).
1115
(t-matsuno)

ext/com_dotnet/com_com.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,9 @@ HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name,
439439
if (obj->typeinfo) {
440440
hr = ITypeInfo_GetIDsOfNames(obj->typeinfo, &olename, 1, dispid);
441441
if (FAILED(hr)) {
442+
HRESULT hr1 = hr;
442443
hr = IDispatch_GetIDsOfNames(V_DISPATCH(&obj->v), &IID_NULL, &olename, 1, LOCALE_SYSTEM_DEFAULT, dispid);
443-
if (SUCCEEDED(hr)) {
444+
if (SUCCEEDED(hr) && hr1 != E_NOTIMPL) {
444445
/* fall back on IDispatch direct */
445446
ITypeInfo_Release(obj->typeinfo);
446447
obj->typeinfo = NULL;
@@ -588,6 +589,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
588589
}
589590
}
590591
efree(vargs);
592+
if (byref_vals) efree(byref_vals);
591593
}
592594

593595
return SUCCEEDED(hr) ? SUCCESS : FAILURE;

ext/com_dotnet/tests/bug64130.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Bug #64130 (COM obj parameters passed by reference are not updated)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
6+
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
7+
try {
8+
$ie = new com('InternetExplorer.Application');
9+
} catch (com_exception $ex) {
10+
die("skip {$ex->getMessage()}");
11+
}
12+
$ie->quit();
13+
?>
14+
--FILE--
15+
<?php
16+
$ie = new com('InternetExplorer.Application');
17+
$x = 0;
18+
$y = 0;
19+
try {
20+
$ie->clientToWindow($x, $y);
21+
} catch (com_exception $ex) {}
22+
var_dump($x > 0, $y > 0);
23+
$ie->quit();
24+
?>
25+
--EXPECT--
26+
bool(true)
27+
bool(true)

0 commit comments

Comments
 (0)