Bug 1167100 - User originAttribute in ContentPrincipalInfo. r=bholley
authorYoshi Huang <allstars.chh@mozilla.com>
Wed, 23 Sep 2015 18:19:06 +0800
changeset 265546 27576be038eac52e109a8d241e723778e0dd42ee
parent 265545 e843ef367f3535bdb675f6afd501ac8b8d0220d8
child 265547 88ded650bc7cc3a1f1c0390d29bba6ef30e35003
push id15472
push usercbook@mozilla.com
push dateFri, 02 Oct 2015 11:51:34 +0000
treeherderfx-team@2c33ef6b27e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1167100
milestone44.0a1
Bug 1167100 - User originAttribute in ContentPrincipalInfo. r=bholley
caps/BasePrincipal.cpp
caps/BasePrincipal.h
dom/base/StructuredCloneHolder.cpp
dom/cache/CacheStorage.cpp
dom/cache/DBSchema.cpp
dom/workers/ServiceWorkerRegistrar.cpp
dom/workers/test/gtest/TestReadWrite.cpp
ipc/glue/BackgroundUtils.cpp
ipc/glue/PBackgroundSharedTypes.ipdlh
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -374,17 +374,17 @@ BasePrincipal::GetIsInBrowserElement(boo
 NS_IMETHODIMP
 BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
 {
   *aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID;
   return NS_OK;
 }
 
 already_AddRefed<BasePrincipal>
-BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs)
+BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
 {
   // If the URI is supposed to inherit the security context of whoever loads it,
   // we shouldn't make a codebase principal for it.
   bool inheritsPrincipal;
   nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                                     &inheritsPrincipal);
   nsCOMPtr<nsIPrincipal> principal;
   if (NS_FAILED(rv) || inheritsPrincipal) {
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -154,17 +154,18 @@ public:
   NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
   NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
 
   virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
 
   virtual bool IsCodebasePrincipal() const { return false; };
 
   static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
-  static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs);
+  static already_AddRefed<BasePrincipal>
+  CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
   static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
 
   const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
   uint32_t AppId() const { return mOriginAttributes.mAppId; }
   uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
   bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
 
 protected:
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -421,42 +421,37 @@ StructuredCloneHolder::ReadFullySerializ
     }
 
     mozilla::ipc::PrincipalInfo info;
     if (aTag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
       info = mozilla::ipc::SystemPrincipalInfo();
     } else if (aTag == SCTAG_DOM_NULL_PRINCIPAL) {
       info = mozilla::ipc::NullPrincipalInfo();
     } else {
-      uint32_t appId = aIndex;
-
-      uint32_t isInBrowserElement, specLength;
-      if (!JS_ReadUint32Pair(aReader, &isInBrowserElement, &specLength)) {
+      
+      uint32_t suffixLength, specLength;
+      if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
         return nullptr;
       }
 
-      uint32_t signedPkgLength, dummy;
-      if (!JS_ReadUint32Pair(aReader, &signedPkgLength, &dummy)) {
-        return nullptr;
+      nsAutoCString suffix;
+      suffix.SetLength(suffixLength);
+      if (!JS_ReadBytes(aReader, suffix.BeginWriting(), suffixLength)) {
+       return nullptr;
       }
 
       nsAutoCString spec;
       spec.SetLength(specLength);
       if (!JS_ReadBytes(aReader, spec.BeginWriting(), specLength)) {
         return nullptr;
       }
 
-      nsAutoCString signedPkg;
-      signedPkg.SetLength(signedPkgLength);
-      if (!JS_ReadBytes(aReader, signedPkg.BeginWriting(), signedPkgLength)) {
-        return nullptr;
-      }
-
-      info = mozilla::ipc::ContentPrincipalInfo(appId, isInBrowserElement,
-                                                spec, signedPkg);
+      OriginAttributes attrs;
+      attrs.PopulateFromSuffix(suffix);
+      info = mozilla::ipc::ContentPrincipalInfo(attrs, spec);
     }
 
     nsresult rv;
     nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(info, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
       return nullptr;
     }
@@ -573,23 +568,22 @@ StructuredCloneHolder::WriteFullySeriali
         return JS_WriteUint32Pair(aWriter, SCTAG_DOM_NULL_PRINCIPAL, 0);
       }
       if (info.type() == mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
         return JS_WriteUint32Pair(aWriter, SCTAG_DOM_SYSTEM_PRINCIPAL, 0);
       }
 
       MOZ_ASSERT(info.type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
       const mozilla::ipc::ContentPrincipalInfo& cInfo = info;
-      return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL,
-                                cInfo.appId()) &&
-             JS_WriteUint32Pair(aWriter, cInfo.isInBrowserElement(),
-                                cInfo.spec().Length()) &&
-             JS_WriteUint32Pair(aWriter, cInfo.signedPkg().Length(), 0) &&
-             JS_WriteBytes(aWriter, cInfo.spec().get(), cInfo.spec().Length()) &&
-             JS_WriteBytes(aWriter, cInfo.signedPkg().get(), cInfo.signedPkg().Length());
+      nsAutoCString suffix;
+      cInfo.attrs().CreateSuffix(suffix);
+      return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
+             JS_WriteUint32Pair(aWriter, suffix.Length(), cInfo.spec().Length()) &&
+             JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
+             JS_WriteBytes(aWriter, cInfo.spec().get(), cInfo.spec().Length());
     }
   }
 
 #ifdef MOZ_NFC
   {
     MozNDEFRecord* ndefRecord;
     if (NS_SUCCEEDED(UNWRAP_OBJECT(MozNDEFRecord, aObj, ndefRecord))) {
       MOZ_ASSERT(NS_IsMainThread());
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -76,17 +76,17 @@ IsTrusted(const PrincipalInfo& aPrincipa
 
   // Require a ContentPrincipal to avoid null principal, etc.
   //
   // Also, an unknown appId means that this principal was created for the
   // codebase without all the security information from the end document or
   // worker.  We require exact knowledge of this information before allowing
   // the caller to touch the disk using the Cache API.
   if (NS_WARN_IF(aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo ||
-                 aPrincipalInfo.get_ContentPrincipalInfo().appId() ==
+                 aPrincipalInfo.get_ContentPrincipalInfo().attrs().mAppId ==
                  nsIScriptSecurityManager::UNKNOWN_APP_ID)) {
     return false;
   }
 
   // If we're in testing mode, then don't do any more work to determing if
   // the origin is trusted.  We have to run some tests as http.
   if (aTestingPrefEnabled) {
     return true;
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -1735,20 +1735,18 @@ InsertEntry(mozIStorageConnection* aConn
     const mozilla::ipc::PrincipalInfo& principalInfo =
       aResponse.principalInfo().get_PrincipalInfo();
     MOZ_ASSERT(principalInfo.type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
     const mozilla::ipc::ContentPrincipalInfo& cInfo =
       principalInfo.get_ContentPrincipalInfo();
 
     serializedInfo.Append(cInfo.spec());
 
-    MOZ_ASSERT(cInfo.appId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
-    OriginAttributes attrs(cInfo.appId(), cInfo.isInBrowserElement());
     nsAutoCString suffix;
-    attrs.CreateSuffix(suffix);
+    cInfo.attrs().CreateSuffix(suffix);
     serializedInfo.Append(suffix);
   }
 
   rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("response_principal_info"),
                                    serializedInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_redirected"),
@@ -1908,19 +1906,18 @@ ReadResponse(mozIStorageConnection* aCon
   if (!serializedInfo.IsEmpty()) {
     nsAutoCString originNoSuffix;
     OriginAttributes attrs;
     if (!attrs.PopulateFromOrigin(serializedInfo, originNoSuffix)) {
       NS_WARNING("Something went wrong parsing a serialized principal!");
       return NS_ERROR_FAILURE;
     }
 
-    nsCString signedPkg = NS_ConvertUTF16toUTF8(attrs.mSignedPkg);
     aSavedResponseOut->mValue.principalInfo() =
-      mozilla::ipc::ContentPrincipalInfo(attrs.mAppId, attrs.mInBrowser, originNoSuffix, signedPkg);
+      mozilla::ipc::ContentPrincipalInfo(attrs, originNoSuffix);
   }
 
   int32_t redirected;
   rv = state->GetInt32(7, &redirected);
   aSavedResponseOut->mValue.channelInfo().redirected() = !!redirected;
 
   rv = state->GetUTF8String(8, aSavedResponseOut->mValue.channelInfo().redirectedURI());
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -327,19 +327,18 @@ ServiceWorkerRegistrar::ReadData()
     GET_LINE(suffix);
 
     OriginAttributes attrs;
     if (!attrs.PopulateFromSuffix(suffix)) {
       return NS_ERROR_INVALID_ARG;
     }
 
     GET_LINE(line);
-    nsCString signedPkg = NS_ConvertUTF16toUTF8(attrs.mSignedPkg);
     entry->principal() =
-      mozilla::ipc::ContentPrincipalInfo(attrs.mAppId, attrs.mInBrowser, line, signedPkg);
+      mozilla::ipc::ContentPrincipalInfo(attrs, line);
 
     GET_LINE(entry->scope());
     GET_LINE(entry->scriptSpec());
     GET_LINE(entry->currentWorkerURL());
 
     nsAutoCString cacheName;
     GET_LINE(cacheName);
     CopyUTF8toUTF16(cacheName, entry->activeCacheName());
@@ -544,19 +543,18 @@ ServiceWorkerRegistrar::WriteData()
   for (uint32_t i = 0, len = data.Length(); i < len; ++i) {
     const mozilla::ipc::PrincipalInfo& info = data[i].principal();
 
     MOZ_ASSERT(info.type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
 
     const mozilla::ipc::ContentPrincipalInfo& cInfo =
       info.get_ContentPrincipalInfo();
 
-    OriginAttributes attrs(cInfo.appId(), cInfo.isInBrowserElement());
     nsAutoCString suffix;
-    attrs.CreateSuffix(suffix);
+    cInfo.attrs().CreateSuffix(suffix);
 
     buffer.Truncate();
     buffer.Append(suffix.get());
     buffer.Append('\n');
 
     buffer.Append(cInfo.spec());
     buffer.Append('\n');
 
--- a/dom/workers/test/gtest/TestReadWrite.cpp
+++ b/dom/workers/test/gtest/TestReadWrite.cpp
@@ -158,35 +158,33 @@ TEST(ServiceWorkerRegistrar, TestReadDat
 
   const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
   ASSERT_EQ((uint32_t)2, data.Length()) << "4 entries should be found";
 
   const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
   ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
   const mozilla::ipc::ContentPrincipalInfo& cInfo0 = data[0].principal();
 
-  mozilla::OriginAttributes attrs0(cInfo0.appId(), cInfo0.isInBrowserElement());
   nsAutoCString suffix0;
-  attrs0.CreateSuffix(suffix0);
+  cInfo0.attrs().CreateSuffix(suffix0);
 
   ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
   ASSERT_STREQ("spec 0", cInfo0.spec().get());
   ASSERT_STREQ("scope 0", data[0].scope().get());
   ASSERT_STREQ("scriptSpec 0", data[0].scriptSpec().get());
   ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
   ASSERT_STREQ("activeCache 0", NS_ConvertUTF16toUTF8(data[0].activeCacheName()).get());
   ASSERT_STREQ("waitingCache 0", NS_ConvertUTF16toUTF8(data[0].waitingCacheName()).get());
 
   const mozilla::ipc::PrincipalInfo& info1 = data[1].principal();
   ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
   const mozilla::ipc::ContentPrincipalInfo& cInfo1 = data[1].principal();
 
-  mozilla::OriginAttributes attrs1(cInfo1.appId(), cInfo1.isInBrowserElement());
   nsAutoCString suffix1;
-  attrs1.CreateSuffix(suffix1);
+  cInfo1.attrs().CreateSuffix(suffix1);
 
   ASSERT_STREQ("", suffix1.get());
   ASSERT_STREQ("spec 1", cInfo1.spec().get());
   ASSERT_STREQ("scope 1", data[1].scope().get());
   ASSERT_STREQ("scriptSpec 1", data[1].scriptSpec().get());
   ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
   ASSERT_STREQ("activeCache 1", NS_ConvertUTF16toUTF8(data[1].activeCacheName()).get());
   ASSERT_STREQ("waitingCache 1", NS_ConvertUTF16toUTF8(data[1].waitingCacheName()).get());
@@ -216,17 +214,17 @@ TEST(ServiceWorkerRegistrar, TestWriteDa
 
     nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
 
     for (int i = 0; i < 10; ++i) {
       ServiceWorkerRegistrationData* d = data.AppendElement();
 
       nsAutoCString spec;
       spec.AppendPrintf("spec write %d", i);
-      d->principal() = mozilla::ipc::ContentPrincipalInfo(i, i % 2, spec, EmptyCString());
+      d->principal() = mozilla::ipc::ContentPrincipalInfo(mozilla::OriginAttributes(i, i % 2), spec);
       d->scope().AppendPrintf("scope write %d", i);
       d->scriptSpec().AppendPrintf("scriptSpec write %d", i);
       d->currentWorkerURL().AppendPrintf("currentWorkerURL write %d", i);
       d->activeCacheName().AppendPrintf("activeCacheName write %d", i);
       d->waitingCacheName().AppendPrintf("waitingCacheName write %d", i);
     }
 
     nsresult rv = swr->TestWriteData();
@@ -242,18 +240,22 @@ TEST(ServiceWorkerRegistrar, TestWriteDa
   ASSERT_EQ((uint32_t)10, data.Length()) << "10 entries should be found";
 
   for (int i = 0; i < 10; ++i) {
     nsAutoCString test;
 
     ASSERT_EQ(data[i].principal().type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
     const mozilla::ipc::ContentPrincipalInfo& cInfo = data[i].principal();
 
-    ASSERT_EQ((uint32_t)i, cInfo.appId());
-    ASSERT_EQ((uint32_t)(i % 2), (uint32_t)cInfo.isInBrowserElement());
+    mozilla::OriginAttributes attrs(i, i % 2);
+    nsAutoCString suffix, expectSuffix;
+    attrs.CreateSuffix(expectSuffix);
+    cInfo.attrs().CreateSuffix(suffix);
+
+    ASSERT_STREQ(expectSuffix.get(), suffix.get());
 
     test.AppendPrintf("spec write %d", i);
     ASSERT_STREQ(test.get(), cInfo.spec().get());
 
     test.Truncate();
     test.AppendPrintf("scope write %d", i);
     ASSERT_STREQ(test.get(), data[i].scope().get());
 
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -20,17 +20,16 @@
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace net {
 class OptionalLoadInfoArgs;
 }
 
 using mozilla::BasePrincipal;
-using mozilla::OriginAttributes;
 using namespace mozilla::net;
 
 namespace ipc {
 
 already_AddRefed<nsIPrincipal>
 PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo,
                          nsresult* aOptionalResult)
 {
@@ -72,23 +71,20 @@ PrincipalInfoToPrincipal(const Principal
         aPrincipalInfo.get_ContentPrincipalInfo();
 
       nsCOMPtr<nsIURI> uri;
       rv = NS_NewURI(getter_AddRefs(uri), info.spec());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
 
-      if (info.appId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+      if (info.attrs().mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
         rv = secMan->GetSimpleCodebasePrincipal(uri, getter_AddRefs(principal));
       } else {
-        // TODO: Bug 1167100 - User nsIPrincipal.originAttribute in ContentPrincipalInfo
-        OriginAttributes attrs(info.appId(), info.isInBrowserElement());
-        attrs.mSignedPkg = NS_ConvertUTF8toUTF16(info.signedPkg());
-        principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
+        principal = BasePrincipal::CreateCodebasePrincipal(uri, info.attrs());
         rv = principal ? NS_OK : NS_ERROR_FAILURE;
       }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
 
       return principal.forget();
     }
@@ -198,43 +194,18 @@ PrincipalToPrincipalInfo(nsIPrincipal* a
   }
 
   nsCString spec;
   rv = uri->GetSpec(spec);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  const mozilla::OriginAttributes& attr =
-	mozilla::BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
-  nsCString signedPkg = NS_ConvertUTF16toUTF8(attr.mSignedPkg);
-
-  bool isUnknownAppId;
-  rv = aPrincipal->GetUnknownAppId(&isUnknownAppId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  uint32_t appId;
-  if (isUnknownAppId) {
-    appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
-  } else {
-    rv = aPrincipal->GetAppId(&appId);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  bool isInBrowserElement;
-  rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  *aPrincipalInfo = ContentPrincipalInfo(appId, isInBrowserElement, spec, signedPkg);
+  *aPrincipalInfo = ContentPrincipalInfo(BasePrincipal::Cast(aPrincipal)->OriginAttributesRef(),
+                                         spec);
   return NS_OK;
 }
 
 nsresult
 LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
                        OptionalLoadInfoArgs* aOptionalLoadInfoArgs)
 {
   if (!aLoadInfo) {
--- a/ipc/glue/PBackgroundSharedTypes.ipdlh
+++ b/ipc/glue/PBackgroundSharedTypes.ipdlh
@@ -1,23 +1,22 @@
 /* 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/. */
 
+using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 
 namespace mozilla {
 namespace ipc {
 
 struct ContentPrincipalInfo
 {
-  uint32_t appId;
-  bool isInBrowserElement;
+  OriginAttributes attrs;
   nsCString spec;
-  nsCString signedPkg;
 };
 
 struct SystemPrincipalInfo
 { };
 
 struct NullPrincipalInfo
 { };