Bug 1340163 - Introducing originNoSuffix as attribute in ContentPrincipalInfo, r=smaug a=gchang
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 20 Mar 2017 16:03:45 +0100
changeset 376906 1fe52840b0eaa4b2ca02f66446351640a2848704
parent 376905 7b852b9750055433ba5bd46473602ba42422a045
child 376907 d01bf6283507b6820bd0961173426d6c21ebfc50
push id7082
push usercbook@mozilla.com
push dateWed, 22 Mar 2017 10:34:10 +0000
treeherdermozilla-beta@d01bf6283507 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, gchang
bugs1340163
milestone53.0
Bug 1340163 - Introducing originNoSuffix as attribute in ContentPrincipalInfo, r=smaug a=gchang
caps/nsJSPrincipals.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/nsJSPrincipals.cpp
+++ b/caps/nsJSPrincipals.cpp
@@ -130,26 +130,32 @@ ReadSuffixAndSpec(JSStructuredCloneReade
                   nsACString& aSpec)
 {
     uint32_t suffixLength, specLength;
     if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
         return false;
     }
 
     nsAutoCString suffix;
-    suffix.SetLength(suffixLength);
+    if (!suffix.SetLength(suffixLength, fallible)) {
+        return false;
+    }
+
     if (!JS_ReadBytes(aReader, suffix.BeginWriting(), suffixLength)) {
         return false;
     }
 
     if (!aAttrs.PopulateFromSuffix(suffix)) {
         return false;
     }
 
-    aSpec.SetLength(specLength);
+    if (!aSpec.SetLength(specLength, fallible)) {
+        return false;
+    }
+
     if (!JS_ReadBytes(aReader, aSpec.BeginWriting(), specLength)) {
         return false;
     }
 
     return true;
 }
 
 static bool
@@ -190,17 +196,17 @@ ReadPrincipalInfo(JSStructuredCloneReade
         aInfo = expanded;
     } else if (aTag == SCTAG_DOM_CONTENT_PRINCIPAL) {
         OriginAttributes attrs;
         nsAutoCString spec;
         if (!ReadSuffixAndSpec(aReader, attrs, spec)) {
             return false;
         }
 
-        aInfo = ContentPrincipalInfo(attrs, spec);
+        aInfo = ContentPrincipalInfo(attrs, void_t(), spec);
     } else {
         MOZ_CRASH("unexpected principal structured clone tag");
     }
 
     return true;
 }
 
 /* static */ bool
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -1969,25 +1969,25 @@ ReadResponse(mozIStorageConnection* aCon
   }
 
   nsAutoCString serializedInfo;
   rv = state->GetUTF8String(5, serializedInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   aSavedResponseOut->mValue.principalInfo() = void_t();
   if (!serializedInfo.IsEmpty()) {
-    nsAutoCString originNoSuffix;
+    nsAutoCString specNoSuffix;
     OriginAttributes attrs;
-    if (!attrs.PopulateFromOrigin(serializedInfo, originNoSuffix)) {
+    if (!attrs.PopulateFromOrigin(serializedInfo, specNoSuffix)) {
       NS_WARNING("Something went wrong parsing a serialized principal!");
       return NS_ERROR_FAILURE;
     }
 
     aSavedResponseOut->mValue.principalInfo() =
-      mozilla::ipc::ContentPrincipalInfo(attrs, originNoSuffix);
+      mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), specNoSuffix);
   }
 
   rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.channelInfo().securityInfo());
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT "
       "name, "
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -349,17 +349,17 @@ ServiceWorkerRegistrar::ReadData()
       OriginAttributes attrs;
       if (!attrs.PopulateFromSuffix(suffix)) {
         return NS_ERROR_INVALID_ARG;
       }
 
       GET_LINE(entry->scope());
 
       entry->principal() =
-        mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
+        mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), entry->scope());
 
       GET_LINE(entry->currentWorkerURL());
 
       nsAutoCString fetchFlag;
       GET_LINE(fetchFlag);
       if (!fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_TRUE) &&
           !fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_FALSE)) {
         return NS_ERROR_INVALID_ARG;
@@ -390,17 +390,17 @@ ServiceWorkerRegistrar::ReadData()
       OriginAttributes attrs;
       if (!attrs.PopulateFromSuffix(suffix)) {
         return NS_ERROR_INVALID_ARG;
       }
 
       GET_LINE(entry->scope());
 
       entry->principal() =
-        mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
+        mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), entry->scope());
 
       GET_LINE(entry->currentWorkerURL());
 
       nsAutoCString fetchFlag;
       GET_LINE(fetchFlag);
       if (!fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_TRUE) &&
           !fetchFlag.EqualsLiteral(SERVICEWORKERREGISTRAR_FALSE)) {
         return NS_ERROR_INVALID_ARG;
@@ -423,17 +423,17 @@ ServiceWorkerRegistrar::ReadData()
       OriginAttributes attrs;
       if (!attrs.PopulateFromSuffix(suffix)) {
         return NS_ERROR_INVALID_ARG;
       }
 
       GET_LINE(entry->scope());
 
       entry->principal() =
-        mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
+        mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), entry->scope());
 
       GET_LINE(entry->currentWorkerURL());
 
       // default handlesFetch flag to Enabled
       entry->currentWorkerHandlesFetch() = true;
 
       nsAutoCString cacheName;
       GET_LINE(cacheName);
@@ -453,17 +453,17 @@ ServiceWorkerRegistrar::ReadData()
       }
 
       // principal spec is no longer used; we use scope directly instead
       GET_LINE(unused);
 
       GET_LINE(entry->scope());
 
       entry->principal() =
-        mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
+        mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), entry->scope());
 
       GET_LINE(entry->currentWorkerURL());
 
       // default handlesFetch flag to Enabled
       entry->currentWorkerHandlesFetch() = true;
 
       nsAutoCString cacheName;
       GET_LINE(cacheName);
@@ -483,17 +483,17 @@ ServiceWorkerRegistrar::ReadData()
       }
 
       // principal spec is no longer used; we use scope directly instead
       GET_LINE(unused);
 
       GET_LINE(entry->scope());
 
       entry->principal() =
-        mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
+        mozilla::ipc::ContentPrincipalInfo(attrs, void_t(), entry->scope());
 
       // scriptSpec is no more used in latest version.
       GET_LINE(unused);
 
       GET_LINE(entry->currentWorkerURL());
 
       // default handlesFetch flag to Enabled
       entry->currentWorkerHandlesFetch() = true;
--- a/dom/workers/test/gtest/TestReadWrite.cpp
+++ b/dom/workers/test/gtest/TestReadWrite.cpp
@@ -238,17 +238,18 @@ TEST(ServiceWorkerRegistrar, TestWriteDa
       reg.currentWorkerHandlesFetch() = true;
       reg.cacheName() =
         NS_ConvertUTF8toUTF16(nsPrintfCString("cacheName write %d", i));
       reg.loadFlags() = nsIRequest::VALIDATE_ALWAYS;
 
       nsAutoCString spec;
       spec.AppendPrintf("spec write %d", i);
       reg.principal() =
-        mozilla::ipc::ContentPrincipalInfo(mozilla::OriginAttributes(i, i % 2), spec);
+        mozilla::ipc::ContentPrincipalInfo(mozilla::OriginAttributes(i, i % 2),
+                                           mozilla::void_t(), spec);
 
       swr->TestRegisterServiceWorker(reg);
     }
 
     nsresult rv = swr->TestWriteData();
     ASSERT_EQ(NS_OK, rv) << "WriteData() should not fail";
   }
 
@@ -592,17 +593,18 @@ TEST(ServiceWorkerRegistrar, TestDedupeW
       reg.currentWorkerHandlesFetch() = true;
       reg.cacheName() =
         NS_ConvertUTF8toUTF16(nsPrintfCString("cacheName write %d", i));
       reg.loadFlags() = nsIRequest::VALIDATE_ALWAYS;
 
       nsAutoCString spec;
       spec.AppendPrintf("spec write dedupe/%d", i);
       reg.principal() =
-        mozilla::ipc::ContentPrincipalInfo(mozilla::OriginAttributes(0, false), spec);
+        mozilla::ipc::ContentPrincipalInfo(mozilla::OriginAttributes(0, false),
+                                           mozilla::void_t(), spec);
 
       swr->TestRegisterServiceWorker(reg);
     }
 
     nsresult rv = swr->TestWriteData();
     ASSERT_EQ(NS_OK, rv) << "WriteData() should not fail";
   }
 
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -88,16 +88,28 @@ PrincipalInfoToPrincipal(const Principal
         attrs = info.attrs();
       }
       principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
       rv = principal ? NS_OK : NS_ERROR_FAILURE;
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
 
+      // When the principal is serialized, the origin is extract from it. This
+      // can fail, and in case, here we will havea Tvoid_t. If we have a string,
+      // it must match with what the_new_principal.getOrigin returns.
+      if (info.originNoSuffix().type() == ContentPrincipalInfoOriginNoSuffix::TnsCString) {
+        nsAutoCString originNoSuffix;
+        rv = principal->GetOriginNoSuffix(originNoSuffix);
+        if (NS_WARN_IF(NS_FAILED(rv)) ||
+            !info.originNoSuffix().get_nsCString().Equals(originNoSuffix)) {
+          MOZ_CRASH("If the origin was in the contentPrincipalInfo, it must be available when deserialized");
+        }
+      }
+
       return principal.forget();
     }
 
     case PrincipalInfo::TExpandedPrincipalInfo: {
       const ExpandedPrincipalInfo& info = aPrincipalInfo.get_ExpandedPrincipalInfo();
 
       nsTArray<nsCOMPtr<nsIPrincipal>> whitelist;
       nsCOMPtr<nsIPrincipal> wlPrincipal;
@@ -215,18 +227,28 @@ PrincipalToPrincipalInfo(nsIPrincipal* a
   }
 
   nsAutoCString spec;
   rv = uri->GetSpec(spec);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  ContentPrincipalInfoOriginNoSuffix infoOriginNoSuffix;
+
+  nsCString originNoSuffix;
+  rv = aPrincipal->GetOriginNoSuffix(originNoSuffix);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    infoOriginNoSuffix = void_t();
+  } else {
+    infoOriginNoSuffix = originNoSuffix;
+  }
+
   *aPrincipalInfo = ContentPrincipalInfo(aPrincipal->OriginAttributesRef(),
-                                         spec);
+                                         infoOriginNoSuffix, spec);
   return NS_OK;
 }
 
 bool
 IsPincipalInfoPrivate(const PrincipalInfo& aPrincipalInfo)
 {
   if (aPrincipalInfo.type() != ipc::PrincipalInfo::TContentPrincipalInfo) {
     return false;
--- a/ipc/glue/PBackgroundSharedTypes.ipdlh
+++ b/ipc/glue/PBackgroundSharedTypes.ipdlh
@@ -3,19 +3,31 @@
  * 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 {
 
+union ContentPrincipalInfoOriginNoSuffix
+{
+  nsCString;
+  void_t;
+};
+
 struct ContentPrincipalInfo
 {
   OriginAttributes attrs;
+
+  // nsIPrincipal.originNoSuffix can fail. In case this happens, this value
+  // will be set to void_t. So far, this is used only for dom/media.
+  // It will be removed in bug 1347817.
+  ContentPrincipalInfoOriginNoSuffix originNoSuffix;
+
   nsCString spec;
 };
 
 struct SystemPrincipalInfo
 { };
 
 struct NullPrincipalInfo
 {