Bug 1161507 - BroadcastChannel should use origin+appId+IsInBrowserElement as key in b2g, r=sicking
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 06 May 2015 11:07:06 +0100
changeset 273965 e7f7dc49cf08a6e833ab0a03aa7889ae14fcf00a
parent 273964 9641952c788f9a6ba52f7d773b2887d6d0493641
child 273966 845b8366a7e4f65613c0a7620e337fd89da8de45
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1161507
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161507 - BroadcastChannel should use origin+appId+IsInBrowserElement as key in b2g, r=sicking
dom/broadcastchannel/BroadcastChannel.cpp
dom/broadcastchannel/BroadcastChannelParent.cpp
dom/broadcastchannel/BroadcastChannelParent.h
dom/broadcastchannel/BroadcastChannelService.cpp
dom/broadcastchannel/BroadcastChannelService.h
ipc/glue/BackgroundParentImpl.cpp
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -11,20 +11,17 @@
 #include "mozilla/dom/StructuredCloneUtils.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/Preferences.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 
-#include "nsIAppsService.h"
 #include "nsIDocument.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsServiceManagerUtils.h"
 #include "nsISupportsPrimitives.h"
 
 #ifdef XP_WIN
 #undef PostMessage
 #endif
 
 namespace mozilla {
 
@@ -52,46 +49,16 @@ private:
 
 namespace {
 
 void
 GetOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin, ErrorResult& aRv)
 {
   MOZ_ASSERT(aPrincipal);
 
-  bool unknownAppId;
-  aRv = aPrincipal->GetUnknownAppId(&unknownAppId);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (!unknownAppId) {
-    uint32_t appId;
-    aRv = aPrincipal->GetAppId(&appId);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
-
-    if (appId != nsIScriptSecurityManager::NO_APP_ID) {
-      // If we are in "app code", use manifest URL as unique origin since
-      // multiple apps can share the same origin but not same broadcast
-      // messages.
-      nsresult rv;
-      nsCOMPtr<nsIAppsService> appsService =
-        do_GetService("@mozilla.org/AppsService;1", &rv);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        aRv.Throw(rv);
-        return;
-      }
-
-      appsService->GetManifestURLByLocalId(appId, aOrigin);
-      return;
-    }
-  }
-
   nsAutoString tmp;
   aRv = nsContentUtils::GetUTFOrigin(aPrincipal, tmp);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   // 'null' means an unknown origin (it can be chrome code or it can be some
   // about: page).
--- a/dom/broadcastchannel/BroadcastChannelParent.cpp
+++ b/dom/broadcastchannel/BroadcastChannelParent.cpp
@@ -5,51 +5,63 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BroadcastChannelParent.h"
 #include "BroadcastChannelService.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/unused.h"
+#include "nsIScriptSecurityManager.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
 BroadcastChannelParent::BroadcastChannelParent(
+                                            const PrincipalInfo& aPrincipalInfo,
                                             const nsAString& aOrigin,
                                             const nsAString& aChannel,
                                             bool aPrivateBrowsing)
   : mService(BroadcastChannelService::GetOrCreate())
   , mOrigin(aOrigin)
   , mChannel(aChannel)
+  , mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
+  , mIsInBrowserElement(false)
   , mPrivateBrowsing(aPrivateBrowsing)
 {
   AssertIsOnBackgroundThread();
   mService->RegisterActor(this);
+
+  if (aPrincipalInfo.type() ==PrincipalInfo::TContentPrincipalInfo) {
+    const ContentPrincipalInfo& info =
+      aPrincipalInfo.get_ContentPrincipalInfo();
+    mAppId = info.appId();
+    mIsInBrowserElement = info.isInBrowserElement();
+  }
 }
 
 BroadcastChannelParent::~BroadcastChannelParent()
 {
   AssertIsOnBackgroundThread();
 }
 
 bool
 BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
 {
   AssertIsOnBackgroundThread();
 
   if (NS_WARN_IF(!mService)) {
     return false;
   }
 
-  mService->PostMessage(this, aData, mOrigin, mChannel, mPrivateBrowsing);
+  mService->PostMessage(this, aData, mOrigin, mAppId, mIsInBrowserElement,
+                        mChannel, mPrivateBrowsing);
   return true;
 }
 
 bool
 BroadcastChannelParent::RecvClose()
 {
   AssertIsOnBackgroundThread();
 
@@ -75,22 +87,26 @@ BroadcastChannelParent::ActorDestroy(Act
     // released too.
     mService->UnregisterActor(this);
   }
 }
 
 void
 BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
                                         const nsString& aOrigin,
+                                        uint64_t aAppId,
+                                        bool aInBrowserElement,
                                         const nsString& aChannel,
                                         bool aPrivateBrowsing)
 {
   AssertIsOnBackgroundThread();
 
   if (aOrigin == mOrigin &&
+      aAppId == mAppId &&
+      aInBrowserElement == mIsInBrowserElement &&
       aChannel == mChannel &&
       aPrivateBrowsing == mPrivateBrowsing) {
     // We need to duplicate data only if we have blobs or if the manager of
     // them is different than the manager of this parent actor.
     if (aData.blobsParent().IsEmpty() ||
         static_cast<BlobParent*>(aData.blobsParent()[0])->GetBackgroundManager() == Manager()) {
       unused << SendNotify(aData);
       return;
--- a/dom/broadcastchannel/BroadcastChannelParent.h
+++ b/dom/broadcastchannel/BroadcastChannelParent.h
@@ -8,47 +8,55 @@
 #define mozilla_dom_BroadcastChannelParent_h
 
 #include "mozilla/dom/PBroadcastChannelParent.h"
 
 namespace mozilla {
 
 namespace ipc {
 class BackgroundParentImpl;
+class PrincipalInfo;
 }
 
 namespace dom {
 
 class BroadcastChannelService;
 
 class BroadcastChannelParent final : public PBroadcastChannelParent
 {
   friend class mozilla::ipc::BackgroundParentImpl;
 
+  typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
+
 public:
   void CheckAndDeliver(const ClonedMessageData& aData,
                        const nsString& aOrigin,
+                       const uint64_t aAppId,
+                       const bool aIsInBrowserElement,
                        const nsString& aChannel,
                        bool aPrivateBrowsing);
 
 private:
-  BroadcastChannelParent(const nsAString& aOrigin,
+  BroadcastChannelParent(const PrincipalInfo& aPrincipalInfo,
+                         const nsAString& aOrigin,
                          const nsAString& aChannel,
                          bool aPrivateBrowsing);
   ~BroadcastChannelParent();
 
   virtual bool
   RecvPostMessage(const ClonedMessageData& aData) override;
 
   virtual bool RecvClose() override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   nsRefPtr<BroadcastChannelService> mService;
   nsString mOrigin;
   nsString mChannel;
+  uint64_t mAppId;
+  bool mIsInBrowserElement;
   bool mPrivateBrowsing;
 };
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_BroadcastChannelParent_h
--- a/dom/broadcastchannel/BroadcastChannelService.cpp
+++ b/dom/broadcastchannel/BroadcastChannelService.cpp
@@ -79,22 +79,26 @@ BroadcastChannelService::UnregisterActor
 
 namespace {
 
 struct MOZ_STACK_CLASS PostMessageData final
 {
   PostMessageData(BroadcastChannelParent* aParent,
                   const ClonedMessageData& aData,
                   const nsAString& aOrigin,
+                  uint64_t aAppId,
+                  bool aIsInBrowserElement,
                   const nsAString& aChannel,
                   bool aPrivateBrowsing)
     : mParent(aParent)
     , mData(aData)
     , mOrigin(aOrigin)
     , mChannel(aChannel)
+    , mAppId(aAppId)
+    , mIsInBrowserElement(aIsInBrowserElement)
     , mPrivateBrowsing(aPrivateBrowsing)
   {
     MOZ_ASSERT(aParent);
     MOZ_COUNT_CTOR(PostMessageData);
 
     // We need to keep the array alive for the life-time of this
     // PostMessageData.
     if (!aData.blobsParent().IsEmpty()) {
@@ -114,47 +118,53 @@ struct MOZ_STACK_CLASS PostMessageData f
     MOZ_COUNT_DTOR(PostMessageData);
   }
 
   BroadcastChannelParent* mParent;
   const ClonedMessageData& mData;
   nsTArray<nsRefPtr<FileImpl>> mFiles;
   const nsString mOrigin;
   const nsString mChannel;
+  uint64_t mAppId;
+  bool mIsInBrowserElement;
   bool mPrivateBrowsing;
 };
 
 PLDHashOperator
 PostMessageEnumerator(nsPtrHashKey<BroadcastChannelParent>* aKey, void* aPtr)
 {
   AssertIsOnBackgroundThread();
 
   auto* data = static_cast<PostMessageData*>(aPtr);
   BroadcastChannelParent* parent = aKey->GetKey();
   MOZ_ASSERT(parent);
 
   if (parent != data->mParent) {
-    parent->CheckAndDeliver(data->mData, data->mOrigin, data->mChannel,
+    parent->CheckAndDeliver(data->mData, data->mOrigin, data->mAppId,
+                            data->mIsInBrowserElement, data->mChannel,
                             data->mPrivateBrowsing);
   }
 
   return PL_DHASH_NEXT;
 }
 
 } // anonymous namespace
 
 void
 BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
                                      const ClonedMessageData& aData,
                                      const nsAString& aOrigin,
+                                     uint64_t aAppId,
+                                     bool aIsInBrowserElement,
                                      const nsAString& aChannel,
                                      bool aPrivateBrowsing)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aParent);
   MOZ_ASSERT(mAgents.Contains(aParent));
 
-  PostMessageData data(aParent, aData, aOrigin, aChannel, aPrivateBrowsing);
+  PostMessageData data(aParent, aData, aOrigin, aAppId, aIsInBrowserElement,
+                       aChannel, aPrivateBrowsing);
   mAgents.EnumerateEntries(PostMessageEnumerator, &data);
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/broadcastchannel/BroadcastChannelService.h
+++ b/dom/broadcastchannel/BroadcastChannelService.h
@@ -29,16 +29,18 @@ public:
   static already_AddRefed<BroadcastChannelService> GetOrCreate();
 
   void RegisterActor(BroadcastChannelParent* aParent);
   void UnregisterActor(BroadcastChannelParent* aParent);
 
   void PostMessage(BroadcastChannelParent* aParent,
                    const ClonedMessageData& aData,
                    const nsAString& aOrigin,
+                   uint64_t aAppId,
+                   bool aIsInBrowserElement,
                    const nsAString& aChannel,
                    bool aPrivateBrowsing);
 
 private:
   BroadcastChannelService();
   ~BroadcastChannelService();
 
   nsTHashtable<nsPtrHashKey<BroadcastChannelParent>> mAgents;
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -257,17 +257,18 @@ BackgroundParentImpl::AllocPBroadcastCha
                                             const PrincipalInfo& aPrincipalInfo,
                                             const nsString& aOrigin,
                                             const nsString& aChannel,
                                             const bool& aPrivateBrowsing)
 {
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 
-  return new BroadcastChannelParent(aOrigin, aChannel, aPrivateBrowsing);
+  return new BroadcastChannelParent(aPrincipalInfo, aOrigin, aChannel,
+                                    aPrivateBrowsing);
 }
 
 namespace {
 
 class CheckPrincipalRunnable final : public nsRunnable
 {
 public:
   CheckPrincipalRunnable(already_AddRefed<ContentParent> aParent,
@@ -310,57 +311,16 @@ public:
 
     bool isNullPrincipal;
     nsresult rv = principal->GetIsNullPrincipal(&isNullPrincipal);
     if (NS_WARN_IF(NS_FAILED(rv)) || isNullPrincipal) {
       mContentParent->KillHard("BroadcastChannel killed: no null principal.");
       return NS_OK;
     }
 
-    bool unknownAppId;
-    rv = principal->GetUnknownAppId(&unknownAppId);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      mContentParent->KillHard("BroadcastChannel killed: failed to get the app status.");
-      return NS_OK;
-    }
-
-    if (!unknownAppId) {
-      uint32_t appId;
-      rv = principal->GetAppId(&appId);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        mContentParent->KillHard("BroadcastChannel killed: failed to get the app id.");
-        return NS_OK;
-      }
-
-      // If the broadcastChannel is used by an app, the origin is the manifest URL.
-      if (appId != nsIScriptSecurityManager::NO_APP_ID) {
-        nsresult rv;
-        nsCOMPtr<nsIAppsService> appsService =
-          do_GetService("@mozilla.org/AppsService;1", &rv);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          mContentParent->KillHard("BroadcastChannel killed: appService getter failed.");
-          return NS_OK;
-        }
-
-        nsAutoString origin;
-        rv = appsService->GetManifestURLByLocalId(appId, origin);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          mContentParent->KillHard("BroadcastChannel killed: failed to retrieve the manifestURL.");
-          return NS_OK;
-        }
-
-        if (!origin.Equals(mOrigin)) {
-          mContentParent->KillHard("BroadcastChannel killed: origins do not match.");
-          return NS_OK;
-        }
-
-        return NS_OK;
-      }
-    }
-
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), mOrigin);
     if (NS_FAILED(rv) || !uri) {
       mContentParent->KillHard("BroadcastChannel killed: invalid origin URI.");
       return NS_OK;
     }
 
     rv = principal->CheckMayLoad(uri, false, false);