Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ PHP NEWS
. Fixed bug GH-24697 (PHP_HTTP_PARSER_STRICT build option doesn't work).
(ndossche, devnexen)

- COM:
. Fixed bug GH-25008 (com_event_sink() and com_print_typeinfo() crash
resolving an event source with no loaded typelib). (Ilia Alshanetsky)

- Curl:
. Fix use-after-free of CURLOPT_STDERR stream on cloned curl handle.
(lacatoire)
Expand Down
31 changes: 29 additions & 2 deletions ext/com_dotnet/com_typeinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,27 @@ ITypeInfo *php_com_locate_typeinfo(zend_string *type_lib_name, php_com_dotnet_ob
php_error_docref(NULL, E_WARNING, "IProvideClassInfo: this code not yet written!");
IProvideClassInfo_Release(pci);
}
if (gotguid) {
ITypeInfo *srcinfo = obj->typeinfo;
bool release_srcinfo = false;
unsigned int idx;
ITypeLib *container = NULL;

if (!srcinfo) {
ITypeInfo *fetched = NULL;

if (SUCCEEDED(IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &fetched)) && fetched) {
srcinfo = fetched;
release_srcinfo = true;
}
}
if (srcinfo && SUCCEEDED(ITypeInfo_GetContainingTypeLib(srcinfo, &container, &idx))) {
typelib = container;
}
if (release_srcinfo) {
ITypeInfo_Release(srcinfo);
}
}
}
} else if (dispatch_name == NULL) {
if (obj->typeinfo) {
Expand Down Expand Up @@ -408,8 +429,12 @@ ITypeInfo *php_com_locate_typeinfo(zend_string *type_lib_name, php_com_dotnet_ob


efree(olename);
} else if (gotguid) {
ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo);
} else if (gotguid && typelib) {
ITypeInfo *found = NULL;

if (SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &found))) {
typeinfo = found;
}
}

if (typelib) {
Expand Down Expand Up @@ -639,6 +664,8 @@ bool php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, bool p
}
} else {
zend_throw_error(NULL, "Type kind must be dispatchable, %08x given", attr->typekind);
ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
return false;
}

ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
Expand Down
59 changes: 59 additions & 0 deletions ext/com_dotnet/tests/gh25008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
GH-25008 (com_event_sink and com_print_typeinfo crash on a NULL source typelib)
--EXTENSIONS--
com_dotnet
--INI--
com.autoregister_typelib=0
--SKIPIF--
<?php
if (!extension_loaded('com_dotnet')) die('skip com_dotnet not loaded');
try {
new COM('WinHttp.WinHttpRequest.5.1');
new COM('Scripting.Dictionary');
} catch (com_exception $e) {
die('skip WinHttp or Scripting.Dictionary is not available');
}
?>
--FILE--
<?php
$o = new COM('WinHttp.WinHttpRequest.5.1', null, CP_UTF8);

try {
var_dump(com_event_sink($o, new stdClass));
echo "sink: no error\n";
} catch (Error $e) {
echo 'sink: ', $e::class, ': ', $e->getMessage(), "\n";
}

ob_start();
$events = com_print_typeinfo($o, null, true);
$events_dump = ob_get_clean();
echo 'events: ';
var_dump($events);
echo (str_contains($events_dump, 'class IWinHttpRequestEvents')
&& str_contains($events_dump, '{F97F4E15-B787-4212-80D1-D380CBBF982E}')
&& str_contains($events_dump, 'function OnResponseStart'))
? "events interface\n" : "events missing\n";

ob_start();
$request = com_print_typeinfo($o, null, false);
$request_dump = ob_get_clean();
echo 'request: ';
var_dump($request);
echo (str_contains($request_dump, 'class IWinHttpRequest')
&& str_contains($request_dump, '{016FE2EC-B2C8-45F8-B23B-39E53A75396B}'))
? "request interface\n" : "request missing\n";

$d = new COM('Scripting.Dictionary');
echo 'dictionary: ';
var_dump(com_event_sink($d, new stdClass));
?>
--EXPECTF--
sink: Error: Type kind must be dispatchable, 00000003 given
events: bool(true)
events interface
request: bool(true)
request interface
dictionary:
Warning: com_event_sink(): IProvideClassInfo: this code not yet written! in %s on line %d
bool(false)
Loading