mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
e80ccc6058
The main bug fixed here is that in half of our interfaces, we use "is browser frame/element" to mean "browser or app", and in the other half, we use it to mean "is browser not app". There's a related, functional bug also fixed here, which is that a browser process doesn't inherit its parent's app-id. This causes problems e.g. for IndexedDB: If a browser inside an app uses IndexedDB, the DB should have the app's app-id. I also modified Tab{Parent,Child} and nsFrameLoader to call "app" "ownOrContainingApp", to emphasize that we might have inherited the app from a parent process. I left nsIDocShell::appId alone, because changing that would have necessitated changing nsILoadGroup and therefore a /lot/ of users in Necko; it's also not clear it would have clarified anything in those cases.
293 lines
7.4 KiB
C++
293 lines
7.4 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "mozilla/dom/TabContext.h"
|
|
#include "mozilla/dom/TabParent.h"
|
|
#include "mozilla/dom/TabChild.h"
|
|
#include "nsIAppsService.h"
|
|
|
|
using namespace mozilla::dom::ipc;
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
TabContext::TabContext()
|
|
: mInitialized(false)
|
|
, mOwnAppId(nsIScriptSecurityManager::NO_APP_ID)
|
|
, mContainingAppId(nsIScriptSecurityManager::NO_APP_ID)
|
|
, mIsBrowser(false)
|
|
{
|
|
}
|
|
|
|
TabContext::TabContext(const IPCTabContext& aParams)
|
|
: mInitialized(true)
|
|
{
|
|
switch(aParams.type()) {
|
|
case IPCTabContext::TPopupIPCTabContext: {
|
|
const PopupIPCTabContext &ipcContext = aParams.get_PopupIPCTabContext();
|
|
|
|
TabContext *context;
|
|
if (ipcContext.openerParent()) {
|
|
context = static_cast<TabParent*>(ipcContext.openerParent());
|
|
if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
|
|
// If the TabParent corresponds to a browser element, then it can only
|
|
// open other browser elements, for security reasons. We should have
|
|
// checked this before calling the TabContext constructor, so this is
|
|
// a fatal error.
|
|
MOZ_CRASH();
|
|
}
|
|
}
|
|
else if (ipcContext.openerChild()) {
|
|
context = static_cast<TabChild*>(ipcContext.openerChild());
|
|
}
|
|
else {
|
|
// This should be unreachable because PopupIPCTabContext::opener is not a
|
|
// nullable field.
|
|
MOZ_CRASH();
|
|
}
|
|
|
|
// If ipcContext is a browser element, then the opener's app-id becomes
|
|
// our containing app-id. Otherwise, our own and containing app-ids are
|
|
// directly inherited from our opener.
|
|
if (ipcContext.isBrowserElement()) {
|
|
mIsBrowser = true;
|
|
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
mContainingAppId = context->OwnAppId();
|
|
}
|
|
else {
|
|
mIsBrowser = false;
|
|
mOwnAppId = context->mOwnAppId;
|
|
mContainingAppId = context->mContainingAppId;
|
|
}
|
|
break;
|
|
}
|
|
case IPCTabContext::TAppFrameIPCTabContext: {
|
|
const AppFrameIPCTabContext &ipcContext =
|
|
aParams.get_AppFrameIPCTabContext();
|
|
|
|
mIsBrowser = false;
|
|
mOwnAppId = ipcContext.ownAppId();
|
|
mContainingAppId = ipcContext.appFrameOwnerAppId();
|
|
break;
|
|
}
|
|
case IPCTabContext::TBrowserFrameIPCTabContext: {
|
|
const BrowserFrameIPCTabContext &ipcContext =
|
|
aParams.get_BrowserFrameIPCTabContext();
|
|
|
|
mIsBrowser = true;
|
|
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
mContainingAppId = ipcContext.browserFrameOwnerAppId();
|
|
break;
|
|
}
|
|
case IPCTabContext::TVanillaFrameIPCTabContext: {
|
|
mIsBrowser = false;
|
|
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
mContainingAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
break;
|
|
}
|
|
default: {
|
|
MOZ_CRASH();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
TabContext::IsBrowserElement() const
|
|
{
|
|
return mIsBrowser;
|
|
}
|
|
|
|
bool
|
|
TabContext::IsBrowserOrApp() const
|
|
{
|
|
return HasOwnApp() || IsBrowserElement();
|
|
}
|
|
|
|
uint32_t
|
|
TabContext::OwnAppId() const
|
|
{
|
|
return mOwnAppId;
|
|
}
|
|
|
|
already_AddRefed<mozIApplication>
|
|
TabContext::GetOwnApp() const
|
|
{
|
|
return GetAppForId(OwnAppId());
|
|
}
|
|
|
|
bool
|
|
TabContext::HasOwnApp() const
|
|
{
|
|
return mOwnAppId != nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
uint32_t
|
|
TabContext::BrowserOwnerAppId() const
|
|
{
|
|
if (mIsBrowser) {
|
|
return mContainingAppId;
|
|
}
|
|
return nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
already_AddRefed<mozIApplication>
|
|
TabContext::GetBrowserOwnerApp() const
|
|
{
|
|
return GetAppForId(BrowserOwnerAppId());
|
|
}
|
|
|
|
bool
|
|
TabContext::HasBrowserOwnerApp() const
|
|
{
|
|
return BrowserOwnerAppId() != nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
uint32_t
|
|
TabContext::AppOwnerAppId() const
|
|
{
|
|
if (mOwnAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
|
return mContainingAppId;
|
|
}
|
|
return nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
already_AddRefed<mozIApplication>
|
|
TabContext::GetAppOwnerApp() const
|
|
{
|
|
return GetAppForId(AppOwnerAppId());
|
|
}
|
|
|
|
bool
|
|
TabContext::HasAppOwnerApp() const
|
|
{
|
|
return AppOwnerAppId() != nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
uint32_t
|
|
TabContext::OwnOrContainingAppId() const
|
|
{
|
|
if (mIsBrowser) {
|
|
MOZ_ASSERT(mOwnAppId == nsIScriptSecurityManager::NO_APP_ID);
|
|
return mContainingAppId;
|
|
}
|
|
|
|
if (mOwnAppId) {
|
|
return mOwnAppId;
|
|
}
|
|
|
|
return mContainingAppId;
|
|
}
|
|
|
|
already_AddRefed<mozIApplication>
|
|
TabContext::GetOwnOrContainingApp() const
|
|
{
|
|
return GetAppForId(OwnOrContainingAppId());
|
|
}
|
|
|
|
bool
|
|
TabContext::HasOwnOrContainingApp() const
|
|
{
|
|
return OwnOrContainingAppId() != nsIScriptSecurityManager::NO_APP_ID;
|
|
}
|
|
|
|
bool
|
|
TabContext::SetTabContext(const TabContext& aContext)
|
|
{
|
|
NS_ENSURE_FALSE(mInitialized, false);
|
|
|
|
// Verify that we can actually get apps for the given ids. This step gives us
|
|
// confidence that HasX() returns true iff GetX() returns true.
|
|
if (aContext.mOwnAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
|
nsCOMPtr<mozIApplication> app = GetAppForId(aContext.mOwnAppId);
|
|
NS_ENSURE_TRUE(app, false);
|
|
}
|
|
|
|
if (aContext.mContainingAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
|
nsCOMPtr<mozIApplication> app = GetAppForId(aContext.mContainingAppId);
|
|
NS_ENSURE_TRUE(app, false);
|
|
}
|
|
|
|
mInitialized = true;
|
|
mIsBrowser = aContext.mIsBrowser;
|
|
mOwnAppId = aContext.mOwnAppId;
|
|
mContainingAppId = aContext.mContainingAppId;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TabContext::SetTabContextForAppFrame(mozIApplication* aOwnApp, mozIApplication* aAppFrameOwnerApp)
|
|
{
|
|
NS_ENSURE_FALSE(mInitialized, false);
|
|
|
|
// Get ids for both apps and only write to our member variables after we've
|
|
// verified that this worked.
|
|
uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
if (aOwnApp) {
|
|
nsresult rv = aOwnApp->GetLocalId(&ownAppId);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
}
|
|
|
|
uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
if (aAppFrameOwnerApp) {
|
|
nsresult rv = aOwnApp->GetLocalId(&containingAppId);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
}
|
|
|
|
mInitialized = true;
|
|
mIsBrowser = false;
|
|
mOwnAppId = ownAppId;
|
|
mContainingAppId = containingAppId;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TabContext::SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp)
|
|
{
|
|
NS_ENSURE_FALSE(mInitialized, false);
|
|
|
|
uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
if (aBrowserFrameOwnerApp) {
|
|
nsresult rv = aBrowserFrameOwnerApp->GetLocalId(&containingAppId);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
}
|
|
|
|
mInitialized = true;
|
|
mIsBrowser = true;
|
|
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
mContainingAppId = containingAppId;
|
|
return true;
|
|
}
|
|
|
|
IPCTabContext
|
|
TabContext::AsIPCTabContext() const
|
|
{
|
|
if (mIsBrowser) {
|
|
return BrowserFrameIPCTabContext(mContainingAppId);
|
|
}
|
|
|
|
return AppFrameIPCTabContext(mOwnAppId, mContainingAppId);
|
|
}
|
|
|
|
already_AddRefed<mozIApplication>
|
|
TabContext::GetAppForId(uint32_t aAppId) const
|
|
{
|
|
if (aAppId == nsIScriptSecurityManager::NO_APP_ID) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
|
NS_ENSURE_TRUE(appsService, nullptr);
|
|
|
|
nsCOMPtr<mozIDOMApplication> domApp;
|
|
appsService->GetAppByLocalId(aAppId, getter_AddRefs(domApp));
|
|
|
|
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
|
|
return app.forget();
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|