Bug 1558369: AccessibleHandler: Don't use HandlerChildEnumerator for iframes. r=yzen

When a client wants to fetch all accessible children, the COM handler uses handlerProvider::get_AllChildren in the content process to optimize cross-process retrieval of all children.
This works fine for iframes rendered in the same content process, just as it does for other accessibles.
However, for out-of-process iframes, HandlerProvider::get_AllChildren will fail.
This is because we only send down an IDispatch COM proxy for the embedded document, but get_AllChildren will try to QueryInterface this to IAccessible2 to reduce QI calls from the parent process.
Because the content process is sandboxed, it can't make the outgoing COM call to QI the proxy from IDispatch to IAccessible2 and so it fails.

Since an iframe only has one child anyway, we don't need the bulk fetch optimization offered by HandlerChildEnumerator or even IEnumVARIANT.
Therefore, we explicitly tell the client this interface is not supported, which will cause the oleacc AccessibleChildren function to fall back to accChild.

Differential Revision: https://phabricator.services.mozilla.com/D34494

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Teh 2019-06-12 15:08:21 +00:00
Родитель 98c9b833d0
Коммит a832fc180d
1 изменённых файлов: 21 добавлений и 0 удалений

Просмотреть файл

@ -26,6 +26,7 @@
#include "AccessibleHypertext.h"
#include "AccessibleHypertext2.h"
#include "AccessibleRole.h"
#include "Accessible2_i.c"
#include "Accessible2_2_i.c"
#include "Accessible2_3_i.c"
@ -402,6 +403,26 @@ AccessibleHandler::QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid,
if (mCachedData.mDynamicData.mChildCount == 0) {
return E_NOINTERFACE;
}
if (mCachedData.mDynamicData.mIA2Role == IA2_ROLE_INTERNAL_FRAME &&
mCachedData.mDynamicData.mChildCount == 1) {
// This is for an iframe. HandlerChildEnumerator works fine for iframes
// rendered in the same content process. However, for out-of-process
// iframes, HandlerProvider::get_AllChildren (called by
// HandlerChildEnumerator) will fail. This is because we only send down
// an IDispatch COM proxy for the embedded document, but get_AllChildren
// will try to QueryInterface this to IAccessible2 to reduce QI calls
// from the parent process. Because the content process is sandboxed,
// it can't make the outgoing COM call to QI the proxy from IDispatch to
// IAccessible2 and so it fails.
// Since an iframe only has one child anyway, we don't need the bulk fetch
// optimization offered by HandlerChildEnumerator or even IEnumVARIANT.
// Therefore, we explicitly tell the client this interface is not
// supported, which will cause the oleacc AccessibleChildren function
// to fall back to accChild.
// If we return E_NOINTERFACE here, mscom::Handler will try the COM
// proxy. S_FALSE signals that the proxy should not be tried.
return S_FALSE;
}
RefPtr<IEnumVARIANT> childEnum(
new HandlerChildEnumerator(this, mCachedData.mGeckoBackChannel));
childEnum.forget(aOutInterface);