Bug 1316683 - Part 5: Avoid going into SpiderMonkey for retrieving origin attributes; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 18 Mar 2017 16:08:12 -0400
changeset 561453 adf1dbdf0042afc959cbe1cd2d817e196a36f36e
parent 561452 448f478547deb1aa7109a7eceb40b231a6514baa
child 561454 f52e34fa7a0b6b8fea22117b6e5dcc78150649ed
push id53730
push userdholbert@mozilla.com
push dateWed, 12 Apr 2017 17:18:19 +0000
reviewersbaku
bugs1316683
milestone55.0a1
Bug 1316683 - Part 5: Avoid going into SpiderMonkey for retrieving origin attributes; r=baku Our caller is C++ code, and the implementations are all also written in C++, so there is no reason to go through SpiderMonkey here. This patch also makes nsILoadContext builtinclass to ensure that the implementation is always native.
caps/nsScriptSecurityManager.cpp
docshell/base/LoadContext.cpp
docshell/base/SerializedLoadContext.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsILoadContext.idl
dom/ipc/TabParent.cpp
dom/offline/nsDOMOfflineResourceList.cpp
uriloader/prefetch/OfflineCacheUpdateParent.cpp
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -1182,18 +1182,17 @@ nsScriptSecurityManager::GetAppCodebaseP
 NS_IMETHODIMP
 nsScriptSecurityManager::
   GetLoadContextCodebasePrincipal(nsIURI* aURI,
                                   nsILoadContext* aLoadContext,
                                   nsIPrincipal** aPrincipal)
 {
   NS_ENSURE_STATE(aLoadContext);
   OriginAttributes docShellAttrs;
-  bool result = aLoadContext->GetOriginAttributes(docShellAttrs);
-  NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
+  aLoadContext->GetOriginAttributes(docShellAttrs);
 
   nsCOMPtr<nsIPrincipal> prin =
     BasePrincipal::CreateCodebasePrincipal(aURI, docShellAttrs);
   prin.forget(aPrincipal);
   return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -7,40 +7,16 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI
 #include "nsContentUtils.h"
 #include "xpcpublic.h"
 
-bool
-nsILoadContext::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
-{
-  mozilla::dom::AutoJSAPI jsapi;
-  bool ok = jsapi.Init(xpc::PrivilegedJunkScope());
-  NS_ENSURE_TRUE(ok, false);
-  JS::Rooted<JS::Value> v(jsapi.cx());
-  nsresult rv = GetOriginAttributes(&v);
-  NS_ENSURE_SUCCESS(rv, false);
-  NS_ENSURE_TRUE(v.isObject(), false);
-  JS::Rooted<JSObject*> obj(jsapi.cx(), &v.toObject());
-
-  // If we're JS-implemented, the object will be left in a different (System-Principaled)
-  // scope, so we may need to enter its compartment.
-  MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj)));
-  JSAutoCompartment ac(jsapi.cx(), obj);
-
-  mozilla::OriginAttributes attrs;
-  ok = attrs.Init(jsapi.cx(), v);
-  NS_ENSURE_TRUE(ok, false);
-  aAttrs = attrs;
-  return true;
-}
-
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor)
 
 LoadContext::LoadContext(nsIPrincipal* aPrincipal,
                          nsILoadContext* aOptionalBase)
   : mTopFrameElement(nullptr)
   , mNestedFrameId(0)
@@ -166,26 +142,32 @@ LoadContext::GetIsInIsolatedMozBrowserEl
 
   NS_ENSURE_ARG_POINTER(aIsInIsolatedMozBrowserElement);
 
   *aIsInIsolatedMozBrowserElement = mOriginAttributes.mInIsolatedMozBrowser;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs)
+LoadContext::GetScriptableOriginAttributes(JS::MutableHandleValue aAttrs)
 {
   JSContext* cx = nsContentUtils::GetCurrentJSContext();
   MOZ_ASSERT(cx);
 
   bool ok = ToJSValue(cx, mOriginAttributes, aAttrs);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
+NS_IMETHODIMP_(void)
+LoadContext::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+  aAttrs = mOriginAttributes;
+}
+
 NS_IMETHODIMP
 LoadContext::GetUseTrackingProtection(bool* aUseTrackingProtection)
 {
   MOZ_ASSERT(mIsNotNull);
 
   NS_ENSURE_ARG_POINTER(aUseTrackingProtection);
 
   *aUseTrackingProtection = mUseTrackingProtection;
--- a/docshell/base/SerializedLoadContext.cpp
+++ b/docshell/base/SerializedLoadContext.cpp
@@ -57,19 +57,17 @@ void
 SerializedLoadContext::Init(nsILoadContext* aLoadContext)
 {
   if (aLoadContext) {
     mIsNotNull = true;
     mIsPrivateBitValid = true;
     aLoadContext->GetIsContent(&mIsContent);
     aLoadContext->GetUseRemoteTabs(&mUseRemoteTabs);
     aLoadContext->GetUseTrackingProtection(&mUseTrackingProtection);
-    if (!aLoadContext->GetOriginAttributes(mOriginAttributes)) {
-      NS_WARNING("GetOriginAttributes failed");
-    }
+    aLoadContext->GetOriginAttributes(mOriginAttributes);
   } else {
     mIsNotNull = false;
     mIsPrivateBitValid = false;
     // none of below values really matter when mIsNotNull == false:
     // we won't be GetInterfaced to nsILoadContext
     mIsContent = true;
     mUseRemoteTabs = false;
     mUseTrackingProtection = false;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -14515,17 +14515,17 @@ nsDocShell::GetIsTopLevelContentDocShell
     *aIsTopLevelContentDocShell = root.get() == static_cast<nsIDocShellTreeItem*>(this);
   }
 
   return NS_OK;
 }
 
 // Implements nsILoadContext.originAttributes
 NS_IMETHODIMP
-nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
+nsDocShell::GetScriptableOriginAttributes(JS::MutableHandle<JS::Value> aVal)
 {
   JSContext* cx = nsContentUtils::GetCurrentJSContext();
   MOZ_ASSERT(cx);
 
   return GetOriginAttributes(cx, aVal);
 }
 
 // Implements nsIDocShell.GetOriginAttributes()
@@ -14967,8 +14967,14 @@ nsDocShell::GetAwaitingLargeAlloc(bool* 
   nsCOMPtr<nsITabChild> tabChild = GetTabChild();
   if (!tabChild) {
     *aResult = false;
     return NS_OK;
   }
   *aResult = static_cast<TabChild*>(tabChild.get())->IsAwaitingLargeAlloc();
   return NS_OK;
 }
+
+NS_IMETHODIMP_(void)
+nsDocShell::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+  aAttrs = mOriginAttributes;
+}
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -229,17 +229,17 @@ public:
   NS_IMETHOD GetTopFrameElement(nsIDOMElement**) override;
   NS_IMETHOD GetNestedFrameId(uint64_t*) override;
   NS_IMETHOD GetIsContent(bool*) override;
   NS_IMETHOD GetUsePrivateBrowsing(bool*) override;
   NS_IMETHOD SetUsePrivateBrowsing(bool) override;
   NS_IMETHOD SetPrivateBrowsing(bool) override;
   NS_IMETHOD GetUseRemoteTabs(bool*) override;
   NS_IMETHOD SetRemoteTabs(bool) override;
-  NS_IMETHOD GetOriginAttributes(JS::MutableHandle<JS::Value>) override;
+  NS_IMETHOD GetScriptableOriginAttributes(JS::MutableHandle<JS::Value>) override;
 
   // Restores a cached presentation from history (mLSHE).
   // This method swaps out the content viewer and simulates loads for
   // subframes. It then simulates the completion of the toplevel load.
   nsresult RestoreFromHistory();
 
   // Perform a URI load from a refresh timer. This is just like the
   // ForceRefreshURI method on nsIRefreshURI, but makes sure to take
@@ -801,16 +801,18 @@ protected:
   }
 
   uint32_t GetInheritedFrameType();
 
   bool HasUnloadedParent();
 
   void UpdateGlobalHistoryTitle(nsIURI* aURI);
 
+  NS_IMETHOD_(void) GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override;
+
   // Dimensions of the docshell
   nsIntRect mBounds;
   nsString mName;
   nsString mTitle;
   nsString mCustomUserAgent;
 
   /**
    * Content-Type Hint of the most-recently initiated load. Used for
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -4,28 +4,30 @@
  * 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 "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
 interface nsIDOMElement;
 
+[ref] native OriginAttributes(mozilla::OriginAttributes);
+
 %{C++
 #ifdef MOZILLA_INTERNAL_API
 #include "mozilla/BasePrincipal.h" // for OriginAttributes
 #endif
 %}
 
 /**
  * An nsILoadContext represents the context of a load.  This interface
  * can be queried for various information about where the load is
  * happening.
  */
-[scriptable, uuid(2813a7a3-d084-4d00-acd0-f76620315c02)]
+[builtinclass, scriptable, uuid(2813a7a3-d084-4d00-acd0-f76620315c02)]
 interface nsILoadContext : nsISupports
 {
   /**
    * associatedWindow is the window with which the load is associated, if any.
    * Note that the load may be triggered by a document which is different from
    * the document in associatedWindow, and in fact the source of the load need
    * not be same-origin with the document in associatedWindow.  This attribute
    * may be null if there is no associated window.
@@ -128,21 +130,16 @@ interface nsILoadContext : nsISupports
    * containing document is chrome.
    */
   readonly attribute boolean isInIsolatedMozBrowserElement;
 
   /**
    * A dictionary of the non-default origin attributes associated with this
    * nsILoadContext.
    */
+  [binaryname(ScriptableOriginAttributes)]
   readonly attribute jsval originAttributes;
 
-%{C++
-#ifdef MOZILLA_INTERNAL_API
   /**
    * The C++ getter for origin attributes.
-   *
-   * Defined in LoadContext.cpp
    */
-  bool GetOriginAttributes(mozilla::OriginAttributes& aAttrs);
-#endif
-%}
+  [noscript, notxpcom] void GetOriginAttributes(out OriginAttributes aAttrs);
 };
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3014,17 +3014,18 @@ public:
     return NS_OK;
   }
   NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
   NS_IMETHOD GetIsContent(bool*) NO_IMPL
   NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
   NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL
-  NS_IMETHOD GetOriginAttributes(JS::MutableHandleValue) NO_IMPL
+  NS_IMETHOD GetScriptableOriginAttributes(JS::MutableHandleValue) NO_IMPL
+  NS_IMETHOD_(void) GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override {}
   NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL
   NS_IMETHOD SetRemoteTabs(bool) NO_IMPL
   NS_IMETHOD GetUseTrackingProtection(bool*) NO_IMPL
   NS_IMETHOD SetUseTrackingProtection(bool) NO_IMPL
 #undef NO_IMPL
 
 protected:
   ~FakeChannel() {}
--- a/dom/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/offline/nsDOMOfflineResourceList.cpp
@@ -811,18 +811,17 @@ nsDOMOfflineResourceList::CacheKeys()
 
   nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetOwner());
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
 
   nsAutoCString originSuffix;
   if (loadContext) {
     mozilla::OriginAttributes oa;
-    bool ok = loadContext->GetOriginAttributes(oa);
-    NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
+    loadContext->GetOriginAttributes(oa);
 
     oa.CreateSuffix(originSuffix);
   }
 
   nsAutoCString groupID;
   mApplicationCacheService->BuildGroupIDForSuffix(
       mManifestURI, originSuffix, groupID);
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -258,29 +258,37 @@ OfflineCacheUpdateParent::SetRemoteTabs(
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
 {
     NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
     return mLoadingPrincipal->GetIsInIsolatedMozBrowserElement(aIsInIsolatedMozBrowserElement);
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetOriginAttributes(JS::MutableHandleValue aAttrs)
+OfflineCacheUpdateParent::GetScriptableOriginAttributes(JS::MutableHandleValue aAttrs)
 {
     NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
 
     JSContext* cx = nsContentUtils::GetCurrentJSContext();
     MOZ_ASSERT(cx);
 
     nsresult rv = mLoadingPrincipal->GetOriginAttributes(cx, aAttrs);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
+NS_IMETHODIMP_(void)
+OfflineCacheUpdateParent::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+    if (mLoadingPrincipal) {
+        aAttrs = mLoadingPrincipal->OriginAttributesRef();
+    }
+}
+
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetUseTrackingProtection(bool* aUseTrackingProtection)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetUseTrackingProtection(bool aUseTrackingProtection)