Bug 1390652: Part 1 - Send parent COM proxies to content as IDispatch instead of IAccessible to match the outparam type of IAccessible::get_accParent; r=yzen

MozReview-Commit-ID: 1CplfZrIt6l
This commit is contained in:
Aaron Klotz 2017-08-16 10:56:00 -06:00
parent 841456a51c
commit 7319740647
7 changed files with 30 additions and 19 deletions

View File

@ -624,7 +624,7 @@ DocAccessibleParent::MaybeInitWindowEmulation()
}
nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
IAccessibleHolder hWndAccHolder;
IDispatchHolder hWndAccHolder;
::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast<HANDLE>(this));
@ -634,7 +634,7 @@ DocAccessibleParent::MaybeInitWindowEmulation()
if (SUCCEEDED(::AccessibleObjectFromWindow(aHwnd, OBJID_WINDOW,
IID_IAccessible,
(void**)&rawHWNDAcc))) {
hWndAccHolder.Set(IAccessibleHolder::COMPtrType(rawHWNDAcc));
hWndAccHolder.Set(IDispatchHolder::COMPtrType(rawHWNDAcc));
}
Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
@ -672,8 +672,8 @@ DocAccessibleParent::SendParentCOMProxy()
outerDoc->GetNativeInterface((void**) &rawNative);
MOZ_ASSERT(rawNative);
IAccessibleHolder::COMPtrType ptr(rawNative);
IAccessibleHolder holder(Move(ptr));
IDispatchHolder::COMPtrType ptr(rawNative);
IDispatchHolder holder(Move(ptr));
if (!PDocAccessibleParent::SendParentCOMProxy(holder)) {
return;
}

View File

@ -41,6 +41,7 @@ namespace mozilla {
namespace a11y {
typedef uint32_t IAccessibleHolder;
typedef uint32_t IDispatchHolder;
typedef uint32_t IHandlerControlHolder;
} // namespace a11y

View File

@ -16,6 +16,7 @@ namespace mozilla {
namespace a11y {
typedef mozilla::mscom::COMPtrHolder<IAccessible, IID_IAccessible> IAccessibleHolder;
typedef mozilla::mscom::COMPtrHolder<IDispatch, IID_IDispatch> IDispatchHolder;
class Accessible;

View File

@ -49,10 +49,10 @@ DocAccessibleChild::Shutdown()
}
ipc::IPCResult
DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
DocAccessibleChild::RecvParentCOMProxy(const IDispatchHolder& aParentCOMProxy)
{
MOZ_ASSERT(!mParentProxy && !aParentCOMProxy.IsNull());
mParentProxy.reset(const_cast<IAccessibleHolder&>(aParentCOMProxy).Release());
mParentProxy.reset(const_cast<IDispatchHolder&>(aParentCOMProxy).Release());
SetConstructedInParentProcess();
for (uint32_t i = 0, l = mDeferredEvents.Length(); i < l; ++i) {
@ -66,13 +66,13 @@ DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
ipc::IPCResult
DocAccessibleChild::RecvEmulatedWindow(const WindowsHandle& aEmulatedWindowHandle,
const IAccessibleHolder& aEmulatedWindowCOMProxy)
const IDispatchHolder& aEmulatedWindowCOMProxy)
{
mEmulatedWindowHandle = reinterpret_cast<HWND>(aEmulatedWindowHandle);
if (!aEmulatedWindowCOMProxy.IsNull()) {
MOZ_ASSERT(!mEmulatedWindowProxy);
mEmulatedWindowProxy.reset(
const_cast<IAccessibleHolder&>(aEmulatedWindowCOMProxy).Release());
const_cast<IDispatchHolder&>(aEmulatedWindowCOMProxy).Release());
}
return IPC_OK();

View File

@ -28,17 +28,17 @@ public:
virtual void Shutdown() override;
virtual ipc::IPCResult
RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) override;
RecvParentCOMProxy(const IDispatchHolder& aParentCOMProxy) override;
virtual ipc::IPCResult
RecvEmulatedWindow(const WindowsHandle& aEmulatedWindowHandle,
const IAccessibleHolder& aEmulatedWindowCOMProxy) override;
const IDispatchHolder& aEmulatedWindowCOMProxy) override;
virtual ipc::IPCResult
RecvRestoreFocus() override;
HWND GetNativeWindowHandle() const;
IAccessible* GetEmulatedWindowIAccessible() const { return mEmulatedWindowProxy.get(); }
IDispatch* GetEmulatedWindowIAccessible() const { return mEmulatedWindowProxy.get(); }
IAccessible* GetParentIAccessible() const { return mParentProxy.get(); }
IDispatch* GetParentIAccessible() const { return mParentProxy.get(); }
bool SendEvent(const uint64_t& aID, const uint32_t& type);
bool SendHideEvent(const uint64_t& aRootID, const bool& aFromUser);
@ -344,8 +344,8 @@ private:
};
bool mIsRemoteConstructed;
mscom::ProxyUniquePtr<IAccessible> mParentProxy;
mscom::ProxyUniquePtr<IAccessible> mEmulatedWindowProxy;
mscom::ProxyUniquePtr<IDispatch> mParentProxy;
mscom::ProxyUniquePtr<IDispatch> mEmulatedWindowProxy;
nsTArray<UniquePtr<DeferredEvent>> mDeferredEvents;
HWND mEmulatedWindowHandle;
};

View File

@ -8,6 +8,7 @@ include protocol PFileDescriptorSet;
include protocol PBrowser;
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::a11y::IDispatchHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
using mozilla::LayoutDeviceIntRect from "Units.h";
@ -71,9 +72,18 @@ parent:
returns (IAccessibleHolder aPluginCOMProxy);
child:
async ParentCOMProxy(IAccessibleHolder aParentCOMProxy);
/**
* We use IDispatchHolder instead of IAccessibleHolder for the following two
* methods because of sandboxing. IAccessible::get_accParent returns the parent
* as an IDispatch. COM is not smart enough to understand that IAccessible is
* derived from IDispatch, so during marshaling it attempts to QueryInterface
* on the parent's proxy for IDispatch. This will fail with E_ACCESSDENIED
* thanks to the sandbox. We can avoid this entirely by just giving content
* the correct interface to begin with: IDispatch.
*/
async ParentCOMProxy(IDispatchHolder aParentCOMProxy);
async EmulatedWindow(WindowsHandle aEmulatedWindowHandle,
IAccessibleHolder aEmulatedWindowCOMProxy);
IDispatchHolder aEmulatedWindowCOMProxy);
/*
* Called as a result of focus shifting from chrome to content
* elements through keyboard navigation.

View File

@ -56,7 +56,7 @@ DocAccessibleWrap::get_accParent(
// Emulated window proxy is only set for the top level content document when
// emulation is enabled.
IAccessible* dispParent = ipcDoc->GetEmulatedWindowIAccessible();
RefPtr<IDispatch> dispParent = ipcDoc->GetEmulatedWindowIAccessible();
if (!dispParent) {
dispParent = ipcDoc->GetParentIAccessible();
}
@ -65,8 +65,7 @@ DocAccessibleWrap::get_accParent(
return S_FALSE;
}
dispParent->AddRef();
*ppdispParent = static_cast<IDispatch*>(dispParent);
dispParent.forget(ppdispParent);
return S_OK;
}