From: Francis De Brabandere <francisdb@gmail.com> GetTypeAttr unconditionally inflated cFuncs by the IDispatch vtbl size and GetRefTypeOfImplType(0) returned dispatch_href, even for typeinfos created via ICreateTypeLib2 without AddImplType. In that case dispatch_href is -1, so callers that walked GetRefTypeOfImplType chains followed an invalid href. Only inflate cFuncs when an impl type is registered, and only return dispatch_href when the typelib actually has an IDispatch reference. --- dlls/oleaut32/tests/typelib.c | 2 -- dlls/oleaut32/typelib.c | 10 +++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index f390d2eccee..8e7e20ca4ef 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -8824,7 +8824,6 @@ static void test_dispatch_no_implparent(void) hr = ITypeInfo_GetTypeAttr(ti, &typeattr); ok(hr == S_OK, "got %#lx\n", hr); ok(typeattr->typekind == TKIND_DISPATCH, "typekind %d\n", typeattr->typekind); - todo_wine ok(typeattr->cFuncs == 1, "cFuncs %u\n", typeattr->cFuncs); ok(typeattr->cVars == 1, "cVars %u\n", typeattr->cVars); ok(typeattr->cImplTypes == 0, "cImplTypes %u\n", typeattr->cImplTypes); @@ -8832,7 +8831,6 @@ static void test_dispatch_no_implparent(void) href = 0xdeadbeef; hr = ITypeInfo_GetRefTypeOfImplType(ti, 0, &href); - todo_wine ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %#lx\n", hr); ITypeInfo_Release(ti); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index e9997a86d24..aa997531e7d 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5757,7 +5757,7 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, if (This->tdescAlias) TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias, This->tdescAlias, *ppTypeAttr + 1); - if((*ppTypeAttr)->typekind == TKIND_DISPATCH) { + if((*ppTypeAttr)->typekind == TKIND_DISPATCH && This->typeattr.cImplTypes) { /* This should include all the inherited funcs */ (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / This->pTypeLib->ptr_size; /* This is always the size of IDispatch's vtbl */ @@ -6279,9 +6279,13 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( hr = TYPE_E_ELEMENTNOTFOUND; } } - else if(index == 0 && This->typeattr.typekind == TKIND_DISPATCH) + else if(index == 0 && This->typeattr.typekind == TKIND_DISPATCH + && This->pTypeLib->dispatch_href != -1) { - /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */ + /* TKIND_DISPATCH inherits from IDispatch when the typelib has a + * registered IDispatch reference. Without one (e.g. typelibs built + * via ICreateTypeLib2 with no explicit AddImplType), index 0 is + * out of range. */ *pRefType = This->pTypeLib->dispatch_href; } else -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10855